/*******************************************************************************
* 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 java.util.Collection;
import java.util.Set;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import cuchaz.enigma.mapping.ClassEntry;
import cuchaz.enigma.mapping.Entry;
public class MemberMatches<T extends Entry>
{
private BiMap<T, T> m_matches;
private Multimap<ClassEntry, T> m_matchedSourceEntries;
private Multimap<ClassEntry, T> m_unmatchedSourceEntries;
private Multimap<ClassEntry, T> m_unmatchedDestEntries;
private Multimap<ClassEntry, T> 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<T> 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<T> destEntriesntries)
{
for(T entry : destEntriesntries)
addUnmatchedDestEntry(entry);
}
public void addUnmatchableSourceEntry(T sourceEntry)
{
boolean wasAdded =
m_unmatchableSourceEntries.put(sourceEntry.getClassEntry(),
sourceEntry);
assert wasAdded;
}
public Set<ClassEntry> getSourceClassesWithUnmatchedEntries()
{
return m_unmatchedSourceEntries.keySet();
}
public Collection<ClassEntry> getSourceClassesWithoutUnmatchedEntries()
{
Set<ClassEntry> out = Sets.newHashSet();
out.addAll(m_matchedSourceEntries.keySet());
out.removeAll(m_unmatchedSourceEntries.keySet());
return out;
}
public Collection<T> getUnmatchedSourceEntries()
{
return m_unmatchedSourceEntries.values();
}
public Collection<T> getUnmatchedSourceEntries(ClassEntry sourceClass)
{
return m_unmatchedSourceEntries.get(sourceClass);
}
public Collection<T> getUnmatchedDestEntries()
{
return m_unmatchedDestEntries.values();
}
public Collection<T> getUnmatchedDestEntries(ClassEntry destClass)
{
return m_unmatchedDestEntries.get(destClass);
}
public Collection<T> 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<T, T> 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)
{
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)
{
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)
{
assert !isMatchedSourceEntry(sourceEntry);
boolean wasRemoved =
m_unmatchedSourceEntries.remove(sourceEntry.getClassEntry(),
sourceEntry);
assert wasRemoved;
addUnmatchableSourceEntry(sourceEntry);
}
}