1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package de.mindcrimeilab.xsanalyzer;
19
20 import java.security.NoSuchAlgorithmException;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.Set;
26
27 import org.apache.xerces.impl.xs.util.XSObjectListImpl;
28 import org.apache.xerces.xs.XSConstants;
29 import org.apache.xerces.xs.XSObject;
30 import org.apache.xerces.xs.XSObjectList;
31 import org.apache.xerces.xs.XSTypeDefinition;
32
33 import de.mindcrimeilab.xsanalyzer.util.XSModelHelper;
34 import de.mindcrimeilab.xsanalyzer.xsext.TypeDescriptionFactory;
35
36
37
38
39
40
41
42 public class SimilarTypeFinderWorker extends NamespaceFilteredWorker implements XsComponentWorker {
43
44 private final Map<String, XSObjectListImpl> similarTypes;
45
46 private final TypeDescriptionFactory factory;
47
48 public SimilarTypeFinderWorker() {
49 super();
50 similarTypes = new HashMap<String, XSObjectListImpl>();
51 try {
52
53 factory = new TypeDescriptionFactory();
54 }
55 catch (NoSuchAlgorithmException e) {
56 SimilarTypeFinderWorker.logger.error("SimilarTypeFinder()", e);
57 throw new RuntimeException("Cannot create " + TypeDescriptionFactory.class.getName());
58 }
59 }
60
61 public synchronized Map<String, ? extends XSObjectList> getSimilarTypes() {
62 removeSingularTypes();
63 return Collections.unmodifiableMap(similarTypes);
64 }
65
66
67
68
69
70
71
72 @Override
73 public void execute(XSObject object, XSObject parent) {
74 final XSTypeDefinition stype = (XSTypeDefinition) object;
75 String signature = generateTypeSignature(stype);
76 addSimilarType(signature, stype);
77 }
78
79
80
81
82
83
84 @Override
85 public boolean isSupported(XSObject object) {
86 final boolean result;
87 if (object.getType() == XSConstants.TYPE_DEFINITION) {
88 if (((XSTypeDefinition) object).getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
89 result = super.isSupported(object);
90 }
91 else if (((XSTypeDefinition) object).getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
92 result = super.isSupported(object);
93 }
94 else {
95 result = false;
96 }
97 }
98 else {
99 result = false;
100 }
101 return result;
102 }
103
104
105
106
107
108
109 private String generateTypeSignature(XSTypeDefinition type) {
110 return factory.generateTypeDescriptionSignature(type);
111 }
112
113 private void addSimilarType(String signatureDigest, XSTypeDefinition type) {
114
115 final XSObjectListImpl xsoList;
116 if (similarTypes.containsKey(signatureDigest)) {
117 xsoList = similarTypes.get(signatureDigest);
118 for (int i = 0; i < xsoList.getLength(); ++i) {
119 XSObject object = xsoList.item(i);
120
121 if (XSModelHelper.isSameTypeDefinition(object, type)) { return; }
122 }
123 xsoList.add(type);
124 }
125 else {
126 xsoList = new XSObjectListImpl();
127 xsoList.add(type);
128 similarTypes.put(signatureDigest, xsoList);
129 }
130 }
131
132 private void removeSingularTypes() {
133 Set<String> keys = similarTypes.keySet();
134 for (Iterator<String> it = keys.iterator(); it.hasNext();) {
135 String key = it.next();
136 if (similarTypes.get(key).getLength() < 2) {
137 SimilarTypeFinderWorker.logger.debug("Removing key [" + key + "] having count < 2");
138 it.remove();
139 }
140 }
141 }
142
143 }