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 }