    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    }