summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/convert/ClassMatching.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/convert/ClassMatching.java')
-rw-r--r--src/cuchaz/enigma/convert/ClassMatching.java184
1 files changed, 184 insertions, 0 deletions
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 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.convert;
12
13import java.util.ArrayList;
14import java.util.Collection;
15import java.util.List;
16import java.util.Map;
17
18import com.beust.jcommander.internal.Lists;
19import com.google.common.collect.ArrayListMultimap;
20import com.google.common.collect.BiMap;
21import com.google.common.collect.HashBiMap;
22import com.google.common.collect.Multimap;
23
24public class ClassMatching
25{
26 private Multimap<ClassIdentity,ClassIdentity> m_sourceClasses;
27 private Multimap<ClassIdentity,ClassIdentity> m_matchedDestClasses;
28 private List<ClassIdentity> m_unmatchedDestClasses;
29
30 public ClassMatching( )
31 {
32 m_sourceClasses = ArrayListMultimap.create();
33 m_matchedDestClasses = ArrayListMultimap.create();
34 m_unmatchedDestClasses = Lists.newArrayList();
35 }
36
37 public void addSource( ClassIdentity c )
38 {
39 m_sourceClasses.put( c, c );
40 }
41
42 public void matchDestClass( ClassIdentity destClass )
43 {
44 Collection<ClassIdentity> matchedSourceClasses = m_sourceClasses.get( destClass );
45 if( matchedSourceClasses.isEmpty() )
46 {
47 // no match
48 m_unmatchedDestClasses.add( destClass );
49 }
50 else
51 {
52 // found a match
53 m_matchedDestClasses.put( destClass, destClass );
54
55 // DEBUG
56 ClassIdentity sourceClass = matchedSourceClasses.iterator().next();
57 assert( sourceClass.hashCode() == destClass.hashCode() );
58 assert( sourceClass.equals( destClass ) );
59 }
60 }
61
62 public void removeSource( ClassIdentity sourceClass )
63 {
64 m_sourceClasses.remove( sourceClass, sourceClass );
65 }
66
67 public void removeDest( ClassIdentity destClass )
68 {
69 m_matchedDestClasses.remove( destClass, destClass );
70 m_unmatchedDestClasses.remove( destClass );
71 }
72
73 public List<ClassIdentity> getSourceClasses( )
74 {
75 return new ArrayList<ClassIdentity>( m_sourceClasses.values() );
76 }
77
78 public List<ClassIdentity> getDestClasses( )
79 {
80 List<ClassIdentity> classes = Lists.newArrayList();
81 classes.addAll( m_matchedDestClasses.values() );
82 classes.addAll( m_unmatchedDestClasses );
83 return classes;
84 }
85
86 public BiMap<ClassIdentity,ClassIdentity> getUniqueMatches( )
87 {
88 BiMap<ClassIdentity,ClassIdentity> uniqueMatches = HashBiMap.create();
89 for( ClassIdentity sourceClass : m_sourceClasses.keySet() )
90 {
91 Collection<ClassIdentity> matchedSourceClasses = m_sourceClasses.get( sourceClass );
92 Collection<ClassIdentity> matchedDestClasses = m_matchedDestClasses.get( sourceClass );
93 if( matchedSourceClasses.size() == 1 && matchedDestClasses.size() == 1 )
94 {
95 ClassIdentity matchedSourceClass = matchedSourceClasses.iterator().next();
96 ClassIdentity matchedDestClass = matchedSourceClasses.iterator().next();
97 uniqueMatches.put( matchedSourceClass, matchedDestClass );
98 }
99 }
100 return uniqueMatches;
101 }
102
103 public BiMap<List<ClassIdentity>,List<ClassIdentity>> getAmbiguousMatches( )
104 {
105 BiMap<List<ClassIdentity>,List<ClassIdentity>> ambiguousMatches = HashBiMap.create();
106 for( ClassIdentity sourceClass : m_sourceClasses.keySet() )
107 {
108 Collection<ClassIdentity> matchedSourceClasses = m_sourceClasses.get( sourceClass );
109 Collection<ClassIdentity> matchedDestClasses = m_matchedDestClasses.get( sourceClass );
110 if( matchedSourceClasses.size() > 1 && matchedDestClasses.size() > 1 )
111 {
112 ambiguousMatches.put(
113 new ArrayList<ClassIdentity>( matchedSourceClasses ),
114 new ArrayList<ClassIdentity>( matchedDestClasses )
115 );
116 }
117 }
118 return ambiguousMatches;
119 }
120
121 public int getNumAmbiguousSourceMatches( )
122 {
123 int num = 0;
124 for( Map.Entry<List<ClassIdentity>,List<ClassIdentity>> entry : getAmbiguousMatches().entrySet() )
125 {
126 num += entry.getKey().size();
127 }
128 return num;
129 }
130
131 public int getNumAmbiguousDestMatches( )
132 {
133 int num = 0;
134 for( Map.Entry<List<ClassIdentity>,List<ClassIdentity>> entry : getAmbiguousMatches().entrySet() )
135 {
136 num += entry.getValue().size();
137 }
138 return num;
139 }
140
141 public List<ClassIdentity> getUnmatchedSourceClasses( )
142 {
143 List<ClassIdentity> classes = Lists.newArrayList();
144 for( ClassIdentity sourceClass : getSourceClasses() )
145 {
146 if( m_matchedDestClasses.get( sourceClass ).isEmpty() )
147 {
148 classes.add( sourceClass );
149 }
150 }
151 return classes;
152 }
153
154 public List<ClassIdentity> getUnmatchedDestClasses( )
155 {
156 return new ArrayList<ClassIdentity>( m_unmatchedDestClasses );
157 }
158
159 @Override
160 public String toString( )
161 {
162 StringBuilder buf = new StringBuilder();
163
164 buf.append( "Source classes: " );
165 buf.append( getSourceClasses().size() );
166 buf.append( "\n\tUnique: " );
167 buf.append( getUniqueMatches().size() );
168 buf.append( "\n\tAmbiguous: " );
169 buf.append( getNumAmbiguousSourceMatches() );
170 buf.append( "\n\tUnmatched: " );
171 buf.append( getUnmatchedSourceClasses().size() );
172
173 buf.append( "\nDest classes: " );
174 buf.append( getDestClasses().size() );
175 buf.append( "\n\tUnique: " );
176 buf.append( getUniqueMatches().size() );
177 buf.append( "\n\tAmbiguous: " );
178 buf.append( getNumAmbiguousDestMatches() );
179 buf.append( "\n\tUnmatched: " );
180 buf.append( getUnmatchedDestClasses().size() );
181
182 return buf.toString();
183 }
184}