001/*
002 * The FML Forge Mod Loader suite. Copyright (C) 2012 cpw
003 *
004 * 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
005 * Software Foundation; either version 2.1 of the License, or any later version.
006 *
007 * 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
008 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
009 *
010 * 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
011 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
012 */
013package cpw.mods.fml.common;
014
015import java.util.Arrays;
016import java.util.logging.Level;
017
018import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
019import cpw.mods.fml.relauncher.ReflectionHelper;
020import cpw.mods.fml.relauncher.ReflectionHelper.UnableToAccessFieldException;
021import cpw.mods.fml.relauncher.ReflectionHelper.UnableToFindFieldException;
022
023/**
024 * Some reflection helper code.
025 *
026 * @author cpw
027 *
028 */
029public class ObfuscationReflectionHelper
030{
031    @SuppressWarnings("unchecked")
032    public static <T, E> T getPrivateValue(Class<? super E> classToAccess, E instance, int fieldIndex)
033    {
034        try
035        {
036            return ReflectionHelper.getPrivateValue(classToAccess, instance, fieldIndex);
037        }
038        catch (UnableToAccessFieldException e)
039        {
040            FMLLog.log(Level.SEVERE, e, "There was a problem getting field index %d from %s", fieldIndex, classToAccess.getName());
041            throw e;
042        }
043    }
044
045    public static String[] remapFieldNames(String className, String... fieldNames)
046    {
047        String internalClassName = FMLDeobfuscatingRemapper.INSTANCE.unmap(className.replace('.', '/'));
048        String[] mappedNames = new String[fieldNames.length];
049        int i = 0;
050        for (String fName : fieldNames)
051        {
052            mappedNames[i++] = FMLDeobfuscatingRemapper.INSTANCE.mapFieldName(internalClassName, fName, null);
053        }
054        return mappedNames;
055    }
056    @SuppressWarnings("unchecked")
057    public static <T, E> T getPrivateValue(Class<? super E> classToAccess, E instance, String... fieldNames)
058    {
059        try
060        {
061            return ReflectionHelper.getPrivateValue(classToAccess, instance, remapFieldNames(classToAccess.getName(),fieldNames));
062        }
063        catch (UnableToFindFieldException e)
064        {
065            FMLLog.log(Level.SEVERE,e,"Unable to locate any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
066            throw e;
067        }
068        catch (UnableToAccessFieldException e)
069        {
070            FMLLog.log(Level.SEVERE, e, "Unable to access any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
071            throw e;
072        }
073    }
074
075    @Deprecated
076    public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, int fieldIndex, E value)
077    {
078        setPrivateValue(classToAccess, instance, value, fieldIndex);
079    }
080
081    public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, E value, int fieldIndex)
082    {
083        try
084        {
085            ReflectionHelper.setPrivateValue(classToAccess, instance, value, fieldIndex);
086        }
087        catch (UnableToAccessFieldException e)
088        {
089            FMLLog.log(Level.SEVERE, e, "There was a problem setting field index %d on type %s", fieldIndex, classToAccess.getName());
090            throw e;
091        }
092    }
093
094    @Deprecated
095    public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, String fieldName, E value)
096    {
097        setPrivateValue(classToAccess, instance, value, fieldName);
098    }
099
100    public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, E value, String... fieldNames)
101    {
102        try
103        {
104            ReflectionHelper.setPrivateValue(classToAccess, instance, value, remapFieldNames(classToAccess.getName(), fieldNames));
105        }
106        catch (UnableToFindFieldException e)
107        {
108            FMLLog.log(Level.SEVERE, e, "Unable to locate any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
109            throw e;
110        }
111        catch (UnableToAccessFieldException e)
112        {
113            FMLLog.log(Level.SEVERE, e, "Unable to set any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
114            throw e;
115        }
116    }
117}