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}