    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
    015package cpw.mods.fml.common;
    016
    017import java.lang.reflect.Field;
    018import java.lang.reflect.Modifier;
    019import java.util.Set;
    020import java.util.logging.Level;
    021
    022import cpw.mods.fml.common.discovery.ASMDataTable;
    023import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
    024import cpw.mods.fml.relauncher.Side;
    025
    026/**
    027 * @author cpw
    028 *
    029 */
    030public 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}