/******************************************************************************* * Copyright (c) 2014 Jeff Martin. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * Jeff Martin - initial API and implementation ******************************************************************************/ package cuchaz.enigma.analysis; import java.util.AbstractMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import com.beust.jcommander.internal.Lists; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import cuchaz.enigma.mapping.ArgumentEntry; import cuchaz.enigma.mapping.ClassEntry; import cuchaz.enigma.mapping.ConstructorEntry; import cuchaz.enigma.mapping.Entry; import cuchaz.enigma.mapping.FieldEntry; import cuchaz.enigma.mapping.MethodEntry; public class EntryRenamer { public static void renameClassesInSet( Map renames, Set set ) { List entries = Lists.newArrayList(); for( T val : set ) { entries.add( renameClassesInThing( renames, val ) ); } set.clear(); set.addAll( entries ); } public static void renameClassesInMap( Map renames, Map map ) { // for each key/value pair... Set> entriesToAdd = Sets.newHashSet(); for( Map.Entry entry : map.entrySet() ) { entriesToAdd.add( new AbstractMap.SimpleEntry( renameClassesInThing( renames, entry.getKey() ), renameClassesInThing( renames, entry.getValue() ) ) ); } map.clear(); for( Map.Entry entry : entriesToAdd ) { map.put( entry.getKey(), entry.getValue() ); } } public static void renameClassesInMultimap( Map renames, Multimap map ) { // for each key/value pair... Set> entriesToAdd = Sets.newHashSet(); for( Map.Entry entry : map.entries() ) { entriesToAdd.add( new AbstractMap.SimpleEntry( renameClassesInThing( renames, entry.getKey() ), renameClassesInThing( renames, entry.getValue() ) ) ); } map.clear(); for( Map.Entry entry : entriesToAdd ) { map.put( entry.getKey(), entry.getValue() ); } } public static void renameMethodsInMultimap( Map renames, Multimap map ) { // for each key/value pair... Set> entriesToAdd = Sets.newHashSet(); Iterator> iter = map.entries().iterator(); while( iter.hasNext() ) { Map.Entry entry = iter.next(); iter.remove(); entriesToAdd.add( new AbstractMap.SimpleEntry( renameMethodsInThing( renames, entry.getKey() ), renameMethodsInThing( renames, entry.getValue() ) ) ); } for( Map.Entry entry : entriesToAdd ) { map.put( entry.getKey(), entry.getValue() ); } } @SuppressWarnings( "unchecked" ) public static T renameMethodsInThing( Map renames, T thing ) { if( thing instanceof MethodEntry ) { MethodEntry methodEntry = (MethodEntry)thing; MethodEntry newMethodEntry = renames.get( methodEntry ); if( newMethodEntry != null ) { return (T)new MethodEntry( methodEntry.getClassEntry(), newMethodEntry.getName(), methodEntry.getSignature() ); } return thing; } else if( thing instanceof ArgumentEntry ) { ArgumentEntry argumentEntry = (ArgumentEntry)thing; return (T)new ArgumentEntry( renameMethodsInThing( renames, argumentEntry.getMethodEntry() ), argumentEntry.getIndex(), argumentEntry.getName() ); } else if( thing instanceof EntryReference ) { EntryReference reference = (EntryReference)thing; reference.entry = renameMethodsInThing( renames, reference.entry ); reference.context = renameMethodsInThing( renames, reference.context ); return thing; } return thing; } @SuppressWarnings( "unchecked" ) public static T renameClassesInThing( Map renames, T thing ) { if( thing instanceof String ) { String stringEntry = (String)thing; if( renames.containsKey( stringEntry ) ) { return (T)renames.get( stringEntry ); } } else if( thing instanceof ClassEntry ) { ClassEntry classEntry = (ClassEntry)thing; return (T)new ClassEntry( renameClassesInThing( renames, classEntry.getClassName() ) ); } else if( thing instanceof FieldEntry ) { FieldEntry fieldEntry = (FieldEntry)thing; return (T)new FieldEntry( renameClassesInThing( renames, fieldEntry.getClassEntry() ), fieldEntry.getName() ); } else if( thing instanceof ConstructorEntry ) { ConstructorEntry constructorEntry = (ConstructorEntry)thing; return (T)new ConstructorEntry( renameClassesInThing( renames, constructorEntry.getClassEntry() ), constructorEntry.getSignature() ); } else if( thing instanceof MethodEntry ) { MethodEntry methodEntry = (MethodEntry)thing; return (T)new MethodEntry( renameClassesInThing( renames, methodEntry.getClassEntry() ), methodEntry.getName(), methodEntry.getSignature() ); } else if( thing instanceof ArgumentEntry ) { ArgumentEntry argumentEntry = (ArgumentEntry)thing; return (T)new ArgumentEntry( renameClassesInThing( renames, argumentEntry.getMethodEntry() ), argumentEntry.getIndex(), argumentEntry.getName() ); } else if( thing instanceof EntryReference ) { EntryReference reference = (EntryReference)thing; reference.entry = renameClassesInThing( renames, reference.entry ); reference.context = renameClassesInThing( renames, reference.context ); return thing; } else { throw new Error( "Not an entry: " + thing ); } return thing; } }