From e43fac9f55cfeebacd869352bfb090b7d8d063c1 Mon Sep 17 00:00:00 2001 From: jeff Date: Sat, 30 Aug 2014 11:41:17 -0400 Subject: got a decent class matcher working --- src/cuchaz/enigma/convert/ClassMatching.java | 184 +++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 src/cuchaz/enigma/convert/ClassMatching.java (limited to 'src/cuchaz/enigma/convert/ClassMatching.java') diff --git a/src/cuchaz/enigma/convert/ClassMatching.java b/src/cuchaz/enigma/convert/ClassMatching.java new file mode 100644 index 0000000..fea8438 --- /dev/null +++ b/src/cuchaz/enigma/convert/ClassMatching.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * 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.convert; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import com.beust.jcommander.internal.Lists; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.Multimap; + +public class ClassMatching +{ + private Multimap m_sourceClasses; + private Multimap m_matchedDestClasses; + private List m_unmatchedDestClasses; + + public ClassMatching( ) + { + m_sourceClasses = ArrayListMultimap.create(); + m_matchedDestClasses = ArrayListMultimap.create(); + m_unmatchedDestClasses = Lists.newArrayList(); + } + + public void addSource( ClassIdentity c ) + { + m_sourceClasses.put( c, c ); + } + + public void matchDestClass( ClassIdentity destClass ) + { + Collection matchedSourceClasses = m_sourceClasses.get( destClass ); + if( matchedSourceClasses.isEmpty() ) + { + // no match + m_unmatchedDestClasses.add( destClass ); + } + else + { + // found a match + m_matchedDestClasses.put( destClass, destClass ); + + // DEBUG + ClassIdentity sourceClass = matchedSourceClasses.iterator().next(); + assert( sourceClass.hashCode() == destClass.hashCode() ); + assert( sourceClass.equals( destClass ) ); + } + } + + public void removeSource( ClassIdentity sourceClass ) + { + m_sourceClasses.remove( sourceClass, sourceClass ); + } + + public void removeDest( ClassIdentity destClass ) + { + m_matchedDestClasses.remove( destClass, destClass ); + m_unmatchedDestClasses.remove( destClass ); + } + + public List getSourceClasses( ) + { + return new ArrayList( m_sourceClasses.values() ); + } + + public List getDestClasses( ) + { + List classes = Lists.newArrayList(); + classes.addAll( m_matchedDestClasses.values() ); + classes.addAll( m_unmatchedDestClasses ); + return classes; + } + + public BiMap getUniqueMatches( ) + { + BiMap uniqueMatches = HashBiMap.create(); + for( ClassIdentity sourceClass : m_sourceClasses.keySet() ) + { + Collection matchedSourceClasses = m_sourceClasses.get( sourceClass ); + Collection matchedDestClasses = m_matchedDestClasses.get( sourceClass ); + if( matchedSourceClasses.size() == 1 && matchedDestClasses.size() == 1 ) + { + ClassIdentity matchedSourceClass = matchedSourceClasses.iterator().next(); + ClassIdentity matchedDestClass = matchedSourceClasses.iterator().next(); + uniqueMatches.put( matchedSourceClass, matchedDestClass ); + } + } + return uniqueMatches; + } + + public BiMap,List> getAmbiguousMatches( ) + { + BiMap,List> ambiguousMatches = HashBiMap.create(); + for( ClassIdentity sourceClass : m_sourceClasses.keySet() ) + { + Collection matchedSourceClasses = m_sourceClasses.get( sourceClass ); + Collection matchedDestClasses = m_matchedDestClasses.get( sourceClass ); + if( matchedSourceClasses.size() > 1 && matchedDestClasses.size() > 1 ) + { + ambiguousMatches.put( + new ArrayList( matchedSourceClasses ), + new ArrayList( matchedDestClasses ) + ); + } + } + return ambiguousMatches; + } + + public int getNumAmbiguousSourceMatches( ) + { + int num = 0; + for( Map.Entry,List> entry : getAmbiguousMatches().entrySet() ) + { + num += entry.getKey().size(); + } + return num; + } + + public int getNumAmbiguousDestMatches( ) + { + int num = 0; + for( Map.Entry,List> entry : getAmbiguousMatches().entrySet() ) + { + num += entry.getValue().size(); + } + return num; + } + + public List getUnmatchedSourceClasses( ) + { + List classes = Lists.newArrayList(); + for( ClassIdentity sourceClass : getSourceClasses() ) + { + if( m_matchedDestClasses.get( sourceClass ).isEmpty() ) + { + classes.add( sourceClass ); + } + } + return classes; + } + + public List getUnmatchedDestClasses( ) + { + return new ArrayList( m_unmatchedDestClasses ); + } + + @Override + public String toString( ) + { + StringBuilder buf = new StringBuilder(); + + buf.append( "Source classes: " ); + buf.append( getSourceClasses().size() ); + buf.append( "\n\tUnique: " ); + buf.append( getUniqueMatches().size() ); + buf.append( "\n\tAmbiguous: " ); + buf.append( getNumAmbiguousSourceMatches() ); + buf.append( "\n\tUnmatched: " ); + buf.append( getUnmatchedSourceClasses().size() ); + + buf.append( "\nDest classes: " ); + buf.append( getDestClasses().size() ); + buf.append( "\n\tUnique: " ); + buf.append( getUniqueMatches().size() ); + buf.append( "\n\tAmbiguous: " ); + buf.append( getNumAmbiguousDestMatches() ); + buf.append( "\n\tUnmatched: " ); + buf.append( getUnmatchedDestClasses().size() ); + + return buf.toString(); + } +} -- cgit v1.2.3