/*******************************************************************************
* 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 m_matches;
private Multimap m_matchedSourceEntries;
private Multimap m_unmatchedSourceEntries;
private Multimap m_unmatchedDestEntries;
private Multimap m_unmatchableSourceEntries;
public MemberMatches() {
m_matches = HashBiMap.create();
m_matchedSourceEntries = HashMultimap.create();
m_unmatchedSourceEntries = HashMultimap.create();
m_unmatchedDestEntries = HashMultimap.create();
m_unmatchableSourceEntries = HashMultimap.create();
}
public void addMatch(T srcEntry, T destEntry) {
boolean wasAdded = m_matches.put(srcEntry, destEntry) == null;
assert (wasAdded);
wasAdded = m_matchedSourceEntries.put(srcEntry.getClassEntry(), srcEntry);
assert (wasAdded);
}
public void addUnmatchedSourceEntry(T sourceEntry) {
boolean wasAdded = m_unmatchedSourceEntries.put(sourceEntry.getClassEntry(), sourceEntry);
assert (wasAdded);
}
public void addUnmatchedSourceEntries(Iterable sourceEntries) {
for (T sourceEntry : sourceEntries) {
addUnmatchedSourceEntry(sourceEntry);
}
}
public void addUnmatchedDestEntry(T destEntry) {
boolean wasAdded = m_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 = m_unmatchableSourceEntries.put(sourceEntry.getClassEntry(), sourceEntry);
assert (wasAdded);
}
public Set getSourceClassesWithUnmatchedEntries() {
return m_unmatchedSourceEntries.keySet();
}
public Collection getSourceClassesWithoutUnmatchedEntries() {
Set out = Sets.newHashSet();
out.addAll(m_matchedSourceEntries.keySet());
out.removeAll(m_unmatchedSourceEntries.keySet());
return out;
}
public Collection getUnmatchedSourceEntries() {
return m_unmatchedSourceEntries.values();
}
public Collection getUnmatchedSourceEntries(ClassEntry sourceClass) {
return m_unmatchedSourceEntries.get(sourceClass);
}
public Collection getUnmatchedDestEntries() {
return m_unmatchedDestEntries.values();
}
public Collection getUnmatchedDestEntries(ClassEntry destClass) {
return m_unmatchedDestEntries.get(destClass);
}
public Collection getUnmatchableSourceEntries() {
return m_unmatchableSourceEntries.values();
}
public boolean hasSource(T sourceEntry) {
return m_matches.containsKey(sourceEntry) || m_unmatchedSourceEntries.containsValue(sourceEntry);
}
public boolean hasDest(T destEntry) {
return m_matches.containsValue(destEntry) || m_unmatchedDestEntries.containsValue(destEntry);
}
public BiMap matches() {
return m_matches;
}
public boolean isMatchedSourceEntry(T sourceEntry) {
return m_matches.containsKey(sourceEntry);
}
public boolean isMatchedDestEntry(T destEntry) {
return m_matches.containsValue(destEntry);
}
public boolean isUnmatchableSourceEntry(T sourceEntry) {
return m_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 = m_unmatchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry);
assert (wasRemoved);
wasRemoved = m_unmatchedDestEntries.remove(destEntry.getClassEntry(), destEntry);
assert (wasRemoved);
addMatch(sourceEntry, destEntry);
}
public boolean isMatched(T sourceEntry, T destEntry) {
T match = m_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 = m_matches.remove(sourceEntry) != null;
assert (wasRemoved);
wasRemoved = m_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 = m_unmatchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry);
assert (wasRemoved);
addUnmatchableSourceEntry(sourceEntry);
}
}