001    /*
002     * The FML Forge Mod Loader suite.
003     * Copyright (C) 2012 cpw
004     *
005     * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or any later version.
007     *
008     * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
009     * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
010     *
011     * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
012     * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
013     */
014    
015    package cpw.mods.fml.common;
016    
017    import java.lang.reflect.Field;
018    import java.lang.reflect.Modifier;
019    import java.util.Set;
020    import java.util.logging.Level;
021    
022    import cpw.mods.fml.common.discovery.ASMDataTable;
023    import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
024    
025    /**
026     * @author cpw
027     *
028     */
029    public class ProxyInjector
030    {
031        public static void inject(ModContainer mod, ASMDataTable data, Side side)
032        {
033            FMLLog.fine("Attempting to inject @SidedProxy classes into %s", mod.getModId());
034            Set<ASMData> targets = data.getAnnotationsFor(mod).get(SidedProxy.class.getName());
035            ClassLoader mcl = Loader.instance().getModClassLoader();
036    
037            for (ASMData targ : targets)
038            {
039                try
040                {
041                    Class<?> proxyTarget = Class.forName(targ.getClassName(), true, mcl);
042                    Field target = proxyTarget.getDeclaredField(targ.getObjectName());
043                    if (target == null)
044                    {
045                        // Impossible?
046                        FMLLog.severe("Attempted to load a proxy type into %s.%s but the field was not found", targ.getClassName(), targ.getObjectName());
047                        throw new LoaderException();
048                    }
049    
050                    String targetType = side.isClient() ? target.getAnnotation(SidedProxy.class).clientSide() : target.getAnnotation(SidedProxy.class).serverSide();
051                    Object proxy=Class.forName(targetType, true, mcl).newInstance();
052    
053                    if ((target.getModifiers() & Modifier.STATIC) == 0 )
054                    {
055                        FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the field is not static", targetType, targ.getClassName(), targ.getObjectName());
056                        throw new LoaderException();
057                    }
058                    if (!target.getType().isAssignableFrom(proxy.getClass()))
059                    {
060                        FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the types don't match", targetType, targ.getClassName(), targ.getObjectName());
061                        throw new LoaderException();
062                    }
063                    target.set(null, proxy);
064                }
065                catch (Exception e)
066                {
067                    FMLLog.log(Level.SEVERE, e, "An error occured trying to load a proxy into %s.%s", targ.getAnnotationInfo(), targ.getClassName(), targ.getObjectName());
068                    throw new LoaderException(e);
069                }
070            }
071        }
072    }