1
2
3
4
5 package de.mindcrimeilab.xsanalyzer.xsext;
6
7 import java.security.MessageDigest;
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.Collections;
11 import java.util.List;
12
13 import org.apache.xerces.xs.XSAttributeDeclaration;
14 import org.apache.xerces.xs.XSAttributeUse;
15 import org.apache.xerces.xs.XSComplexTypeDefinition;
16 import org.apache.xerces.xs.XSConstants;
17 import org.apache.xerces.xs.XSElementDeclaration;
18 import org.apache.xerces.xs.XSModelGroup;
19 import org.apache.xerces.xs.XSObjectList;
20 import org.apache.xerces.xs.XSParticle;
21 import org.apache.xerces.xs.XSSimpleTypeDefinition;
22 import org.apache.xerces.xs.XSTerm;
23 import org.apache.xerces.xs.XSTypeDefinition;
24
25 import de.mindcrimeilab.util.CollectionsHelper;
26 import de.mindcrimeilab.xsanalyzer.util.NameComparator;
27 import de.mindcrimeilab.xsanalyzer.util.XSListHelper;
28 import de.mindcrimeilab.xsanalyzer.util.XSModelHelper;
29 import de.mindcrimeilab.xsanalyzer.util.XsAttributeExtractor;
30
31
32
33
34
35
36
37 public class ComplexTypeDescription extends AbstractTypeDescription {
38
39 public static String getSignatureDigest(XSComplexTypeDefinition ctypedef, MessageDigest md) {
40 String signature = ComplexTypeDescription.getSignature(ctypedef);
41 String digest = AbstractTypeDescription.getSignatureDigest(signature, md);
42 AbstractTypeDescription.logger.debug("Signature of type [{" + ctypedef.getNamespace() + "}:" + ctypedef.getName() + "|" + signature.toString() + "] is [" + digest + "]");
43 return digest;
44 }
45
46 public static String getSignature(XSComplexTypeDefinition ctypedef) {
47
48 StringBuilder signature = new StringBuilder();
49 XSTypeDefinition baseType = AbstractTypeDescription.getBaseTypeRecursive(ctypedef);
50
51 switch (ctypedef.getContentType()) {
52 case XSComplexTypeDefinition.CONTENTTYPE_SIMPLE:
53 if (null == ctypedef.getParticle()) {
54 signature.append(SimpleTypeDescription.getSignature(ctypedef.getSimpleType()));
55 }
56 else {
57 AbstractTypeDescription.appendBaseType(signature, baseType);
58 signature.append(ComplexTypeDescription.inspectComplexType(ctypedef));
59 }
60 break;
61 case XSComplexTypeDefinition.CONTENTTYPE_EMPTY:
62 AbstractTypeDescription.appendBaseType(signature, baseType);
63 AbstractTypeDescription.logger.debug("{" + ctypedef.getNamespace() + "}" + ctypedef.getName() + " empty content!");
64 break;
65 case XSComplexTypeDefinition.CONTENTTYPE_ELEMENT:
66 AbstractTypeDescription.appendBaseType(signature, baseType);
67 signature.append(ComplexTypeDescription.inspectComplexType(ctypedef));
68 break;
69 default:
70 AbstractTypeDescription.appendBaseType(signature, baseType);
71 signature.append(ctypedef.getName()).append(ctypedef.getNamespace());
72 AbstractTypeDescription.logger.warn("{" + ctypedef.getNamespace() + "}" + ctypedef.getName() + " undefined content type.");
73 break;
74
75 }
76
77 List<XSAttributeDeclaration> attributes = ComplexTypeDescription.getAttributes(ctypedef);
78 if (null != attributes) {
79 for (XSAttributeDeclaration attributeDeclaration : attributes) {
80 signature.append(SimpleTypeDescription.getSignature(attributeDeclaration.getTypeDefinition()));
81 }
82 }
83
84 return signature.toString();
85 }
86
87 private static String inspectComplexType(XSComplexTypeDefinition ctypedef) {
88 StringBuilder sig = new StringBuilder();
89 XSParticle particle = ctypedef.getParticle();
90 if (null != particle) {
91 XSTerm term = particle.getTerm();
92 sig.append(ComplexTypeDescription.inspectTerm(term));
93 }
94 return sig.toString();
95 }
96
97
98
99
100
101
102 private static String inspectTerm(XSTerm term) {
103 StringBuilder sig = new StringBuilder();
104 switch (term.getType()) {
105 case XSConstants.MODEL_GROUP:
106 AbstractTypeDescription.logger.debug("==> found model group");
107 XSModelGroup group = (XSModelGroup) term;
108 sig.append(":").append(XSModelHelper.compositorToString(group.getCompositor()));
109 sig.append("[");
110 XSObjectList list = group.getParticles();
111 List<String> subSignatures = new ArrayList<String>();
112 for (int i = 0; i < list.getLength(); ++i) {
113 XSParticle part = (XSParticle) list.item(i);
114 XSTerm item = part.getTerm();
115 AbstractTypeDescription.logger.debug("==--> embedded [{" + item.getNamespace() + "}:" + item.getName() + "]");
116 subSignatures.add(ComplexTypeDescription.inspectTerm(item));
117 }
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 if (group.getCompositor() == XSModelGroup.COMPOSITOR_CHOICE) {
146 Collections.sort(subSignatures);
147 }
148 for (String subSig : subSignatures) {
149 sig.append(subSig).append("|");
150 }
151 sig.append("]");
152 break;
153 case XSConstants.ELEMENT_DECLARATION:
154 XSElementDeclaration elementDeclaration = (XSElementDeclaration) term;
155 final String tempSig;
156 if (XSTypeDefinition.COMPLEX_TYPE == elementDeclaration.getTypeDefinition().getTypeCategory()) {
157 tempSig = ComplexTypeDescription.getSignature((XSComplexTypeDefinition) elementDeclaration.getTypeDefinition());
158 }
159 else {
160 tempSig = SimpleTypeDescription.getSignature((XSSimpleTypeDefinition) elementDeclaration.getTypeDefinition());
161 }
162 sig.append(tempSig);
163 break;
164 case XSConstants.WILDCARD:
165 AbstractTypeDescription.logger.warn("==> found wildcard");
166 break;
167 default:
168 AbstractTypeDescription.logger.warn("-------------- UNKNOWN PARTICLE TYPE OF TYPE [" + term.getType() + "]");
169 throw new RuntimeException("Unexpected branch selection - Not implemented");
170 }
171 return sig.toString();
172 }
173
174
175
176
177
178 private static List<XSAttributeDeclaration> getAttributes(XSComplexTypeDefinition ctypedef) {
179 List<XSAttributeDeclaration> attributes = null;
180 XSObjectList attributesObjectList = ctypedef.getAttributeUses();
181 if (0 < attributesObjectList.getLength()) {
182 List temp = XSListHelper.asList(attributesObjectList);
183 attributes = new ArrayList<XSAttributeDeclaration>();
184 CollectionsHelper.copyCollection((Collection<XSAttributeUse>) temp, attributes, new XsAttributeExtractor());
185 Collections.sort(attributes, new NameComparator());
186 }
187 return attributes;
188 }
189
190 }