    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    import cpw.mods.fml.relauncher.Side;
    025
    026    /**
    027     * @author cpw
    028     *
    029     */
    030    public class ProxyInjector
    031    {
    032        public static void inject(ModContainer mod, ASMDataTable data, Side side)
    033        {
    034            FMLLog.fine("Attempting to inject @SidedProxy classes into %s", mod.getModId());
    035            Set<ASMData> targets = data.getAnnotationsFor(mod).get(SidedProxy.class.getName());
    036            ClassLoader mcl = Loader.instance().getModClassLoader();
    037
    038            for (ASMData targ : targets)
    039            {
    040                try
    041                {
    042                    Class<?> proxyTarget = Class.forName(targ.getClassName(), true, mcl);
    043                    Field target = proxyTarget.getDeclaredField(targ.getObjectName());
    044                    if (target == null)
    045                    {
    046                        // Impossible?
    047                        FMLLog.severe("Attempted to load a proxy type into %s.%s but the field was not found", targ.getClassName(), targ.getObjectName());
    048                        throw new LoaderException();
    049                    }
    050
    051                    String targetType = side.isClient() ? target.getAnnotation(SidedProxy.class).clientSide() : target.getAnnotation(SidedProxy.class).serverSide();
    052                    Object proxy=Class.forName(targetType, true, mcl).newInstance();
    053
    054                    if ((target.getModifiers() & Modifier.STATIC) == 0 )
    055                    {
    056                        FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the field is not static", targetType, targ.getClassName(), targ.getObjectName());
    057                        throw new LoaderException();
    058                    }
    059                    if (!target.getType().isAssignableFrom(proxy.getClass()))
    060                    {
    061                        FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the types don't match", targetType, targ.getClassName(), targ.getObjectName());
    062                        throw new LoaderException();
    063                    }
    064                    target.set(null, proxy);
    065                }
    066                catch (Exception e)
    067                {
    068                    FMLLog.log(Level.SEVERE, e, "An error occured trying to load a proxy into %s.%s", targ.getAnnotationInfo(), targ.getClassName(), targ.getObjectName());
    069                    throw new LoaderException(e);
    070                }
    071            }
    072        }
    073    }