/*******************************************************************************
* Copyright (c) 2015 Jeff Martin.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public
* License v3.0 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
* Contributors:
* Jeff Martin - initial API and implementation
******************************************************************************/
package cuchaz.enigma.convert;
import com.google.common.collect.*;
import cuchaz.enigma.Deobfuscator;
import cuchaz.enigma.mapping.ClassEntry;
import cuchaz.enigma.mapping.Entry;
import java.util.Collection;
import java.util.Set;
public class MemberMatches {
private BiMap matches;
private Multimap matchedSourceEntries;
private Multimap unmatchedSourceEntries;
private Multimap unmatchedDestEntries;
private Multimap unmatchableSourceEntries;
public MemberMatches() {
matches = HashBiMap.create();
matchedSourceEntries = HashMultimap.create();
unmatchedSourceEntries = HashMultimap.create();
unmatchedDestEntries = HashMultimap.create();
unmatchableSourceEntries = HashMultimap.create();
}
public void addMatch(T srcEntry, T destEntry) {
boolean wasAdded = matches.put(srcEntry, destEntry) == null;
assert (wasAdded);
wasAdded = matchedSourceEntries.put(srcEntry.getClassEntry(), srcEntry);
assert (wasAdded);
}
public void addUnmatchedSourceEntry(T sourceEntry) {
boolean wasAdded = unmatchedSourceEntries.put(sourceEntry.getClassEntry(), sourceEntry);
assert (wasAdded);
}
public void addUnmatchedSourceEntries(Iterable sourceEntries) {
for (T sourceEntry : sourceEntries) {
addUnmatchedSourceEntry(sourceEntry);
}
}
public void addUnmatchedDestEntry(T destEntry) {
if (destEntry.getName().equals("") || destEntry.getName().equals(""))
return;
boolean wasAdded = unmatchedDestEntries.put(destEntry.getClassEntry(), destEntry);
assert (wasAdded);
}
public void addUnmatchedDestEntries(Iterable destEntriesntries) {
for (T entry : destEntriesntries) {
addUnmatchedDestEntry(entry);
}
}
public void addUnmatchableSourceEntry(T sourceEntry) {
boolean wasAdded = unmatchableSourceEntries.put(sourceEntry.getClassEntry(), sourceEntry);
assert (wasAdded);
}
public Set getSourceClassesWithUnmatchedEntries() {
return unmatchedSourceEntries.keySet();
}
public Collection getSourceClassesWithoutUnmatchedEntries() {
Set out = Sets.newHashSet();
out.addAll(matchedSourceEntries.keySet());
out.removeAll(unmatchedSourceEntries.keySet());
return out;
}
public Collection getUnmatchedSourceEntries() {
return unmatchedSourceEntries.values();
}
public Collection getUnmatchedSourceEntries(ClassEntry sourceClass) {
return unmatchedSourceEntries.get(sourceClass);
}
public Collection getUnmatchedDestEntries() {
return unmatchedDestEntries.values();
}
public Collection getUnmatchedDestEntries(ClassEntry destClass) {
return unmatchedDestEntries.get(destClass);
}
public Collection getUnmatchableSourceEntries() {
return unmatchableSourceEntries.values();
}
public boolean hasSource(T sourceEntry) {
return matches.containsKey(sourceEntry) || unmatchedSourceEntries.containsValue(sourceEntry);
}
public boolean hasDest(T destEntry) {
return matches.containsValue(destEntry) || unmatchedDestEntries.containsValue(destEntry);
}
public BiMap matches() {
return matches;
}
public boolean isMatchedSourceEntry(T sourceEntry) {
return matches.containsKey(sourceEntry);
}
public boolean isMatchedDestEntry(T destEntry) {
return matches.containsValue(destEntry);
}
public boolean isUnmatchableSourceEntry(T sourceEntry) {
return unmatchableSourceEntries.containsEntry(sourceEntry.getClassEntry(), sourceEntry);
}
public void makeMatch(T sourceEntry, T destEntry) {
makeMatch(sourceEntry, destEntry, null, null);
}
public void makeMatch(T sourceEntry, T destEntry, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) {
if (sourceDeobfuscator != null && destDeobfuscator != null)
{
makeMatch(sourceEntry, destEntry);
sourceEntry = (T) sourceEntry.cloneToNewClass(sourceDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(sourceEntry, true));
destEntry = (T) destEntry.cloneToNewClass(destDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(destEntry, true));
}
boolean wasRemoved = unmatchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry);
assert (wasRemoved);
wasRemoved = unmatchedDestEntries.remove(destEntry.getClassEntry(), destEntry);
assert (wasRemoved);
addMatch(sourceEntry, destEntry);
}
public boolean isMatched(T sourceEntry, T destEntry) {
T match = matches.get(sourceEntry);
return match != null && match.equals(destEntry);
}
public void unmakeMatch(T sourceEntry, T destEntry, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator)
{
if (sourceDeobfuscator != null && destDeobfuscator != null)
{
unmakeMatch(sourceEntry, destEntry, null, null);
sourceEntry = (T) sourceEntry.cloneToNewClass(
sourceDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(sourceEntry, true));
destEntry = (T) destEntry.cloneToNewClass(
destDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(destEntry, true));
}
boolean wasRemoved = matches.remove(sourceEntry) != null;
assert (wasRemoved);
wasRemoved = matchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry);
assert (wasRemoved);
addUnmatchedSourceEntry(sourceEntry);
addUnmatchedDestEntry(destEntry);
}
public void makeSourceUnmatchable(T sourceEntry, Deobfuscator sourceDeobfuscator) {
if (sourceDeobfuscator != null)
{
makeSourceUnmatchable(sourceEntry, null);
sourceEntry = (T) sourceEntry.cloneToNewClass(
sourceDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(sourceEntry, true));
}
assert (!isMatchedSourceEntry(sourceEntry));
boolean wasRemoved = unmatchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry);
assert (wasRemoved);
addUnmatchableSourceEntry(sourceEntry);
}
}