    001/*
    002 * Forge Mod Loader
    003 * Copyright (c) 2012-2013 cpw.
    004 * All rights reserved. This program and the accompanying materials
    005 * are made available under the terms of the GNU Lesser Public License v2.1
    006 * which accompanies this distribution, and is available at
    007 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
    008 *
    009 * Contributors:
    010 *     cpw - implementation
    011 */
    012
    013package cpw.mods.fml.common;
    014
    015import java.lang.reflect.Field;
    016import java.lang.reflect.Modifier;
    017import java.util.Set;
    018import java.util.logging.Level;
    019
    020import cpw.mods.fml.common.discovery.ASMDataTable;
    021import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
    022import cpw.mods.fml.relauncher.Side;
    023
    024/**
    025 * @author cpw
    026 *
    027 */
    028public class ProxyInjector
    029{
    030    public static void inject(ModContainer mod, ASMDataTable data, Side side)
    031    {
    032        FMLLog.fine("Attempting to inject @SidedProxy classes into %s", mod.getModId());
    033        Set<ASMData> targets = data.getAnnotationsFor(mod).get(SidedProxy.class.getName());
    034        ClassLoader mcl = Loader.instance().getModClassLoader();
    035
    036        for (ASMData targ : targets)
    037        {
    038            try
    039            {
    040                Class<?> proxyTarget = Class.forName(targ.getClassName(), true, mcl);
    041                Field target = proxyTarget.getDeclaredField(targ.getObjectName());
    042                if (target == null)
    043                {
    044                    // Impossible?
    045                    FMLLog.severe("Attempted to load a proxy type into %s.%s but the field was not found", targ.getClassName(), targ.getObjectName());
    046                    throw new LoaderException();
    047                }
    048
    049                String targetType = side.isClient() ? target.getAnnotation(SidedProxy.class).clientSide() : target.getAnnotation(SidedProxy.class).serverSide();
    050                Object proxy=Class.forName(targetType, true, mcl).newInstance();
    051
    052                if ((target.getModifiers() & Modifier.STATIC) == 0 )
    053                {
    054                    FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the field is not static", targetType, targ.getClassName(), targ.getObjectName());
    055                    throw new LoaderException();
    056                }
    057                if (!target.getType().isAssignableFrom(proxy.getClass()))
    058                {
    059                    FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the types don't match", targetType, targ.getClassName(), targ.getObjectName());
    060                    throw new LoaderException();
    061                }
    062                target.set(null, proxy);
    063            }
    064            catch (Exception e)
    065            {
    066                FMLLog.log(Level.SEVERE, e, "An error occured trying to load a proxy into %s.%s", targ.getAnnotationInfo(), targ.getClassName(), targ.getObjectName());
    067                throw new LoaderException(e);
    068            }
    069        }
    070    }
    071}