1
|
|
/*
|
2
|
|
* JBind
|
3
|
|
*
|
4
|
|
* Copyright (c) by Stefan Wachter. All rights reserved.
|
5
|
|
*
|
6
|
|
* Usage, modification, and redistribution is subject to license terms that are
|
7
|
|
* available at 'http://www.jbind.org'. The JBind license is like the
|
8
|
|
* 'Apache Software License V 1.1'.
|
9
|
|
*/
|
10
|
|
package org.jbind.xml.schema.compiler;
|
11
|
|
|
12
|
|
import java.text.BreakIterator;
|
13
|
|
import java.util.ArrayList;
|
14
|
|
import java.util.Collections;
|
15
|
|
import java.util.Comparator;
|
16
|
|
import java.util.Enumeration;
|
17
|
|
import java.util.Iterator;
|
18
|
|
import java.util.Locale;
|
19
|
|
import java.util.Map;
|
20
|
|
import java.util.StringTokenizer;
|
21
|
|
|
22
|
|
import org.jbind.xml.base.IBindingAttributes;
|
23
|
|
import org.jbind.xml.base.IHasBindingAttributes;
|
24
|
|
import org.jbind.xml.base.ILanguage;
|
25
|
|
import org.jbind.xml.base.IRange;
|
26
|
|
import org.jbind.xml.base.StringUtil;
|
27
|
|
import org.jbind.xml.core.bridge.IXPathMethod;
|
28
|
|
import org.jbind.xml.core.cmp.IAnnotation;
|
29
|
|
import org.jbind.xml.core.cmp.IBinding;
|
30
|
|
import org.jbind.xml.core.cmp.IComponent;
|
31
|
|
import org.jbind.xml.core.cmp.IDocumentation;
|
32
|
|
import org.jbind.xml.core.constraint.ConstraintType;
|
33
|
|
import org.jbind.xml.core.constraint.IEnumerationConstraint;
|
34
|
|
import org.jbind.xml.core.content.IAttrRefOrDecl;
|
35
|
|
import org.jbind.xml.core.content.IDataRefOrDecl;
|
36
|
|
import org.jbind.xml.core.content.IElemRefOrDecl;
|
37
|
|
import org.jbind.xml.core.data.IAnyTypeData;
|
38
|
|
import org.jbind.xml.core.data.IComplexCCData;
|
39
|
|
import org.jbind.xml.core.data.IComplexSCData;
|
40
|
|
import org.jbind.xml.core.data.IIDREFSData;
|
41
|
|
import org.jbind.xml.core.type.IAnyType;
|
42
|
|
import org.jbind.xml.core.type.IListType;
|
43
|
|
import org.jbind.xml.core.type.ISimpleType;
|
44
|
|
import org.jbind.xml.instance.data.Language;
|
45
|
|
import org.jbind.xml.msg.XmlException;
|
46
|
|
import org.jbind.xml.schema.cmp.Schemas;
|
47
|
|
import org.jbind.xml.schema.cmp.W3CTypes;
|
48
|
|
|
49
|
|
public class DataInterfaceCartridge extends DataCartridge {
|
50
|
|
|
51
|
3
|
public DataInterfaceCartridge() {
|
52
|
3
|
super("dataInterface", "I", "Data");
|
53
|
|
}
|
54
|
|
|
55
|
466
|
public IBinding createGlobalAnyTypeBinding(IComponent aComponent, String aRootPackage, boolean aUseBuiltInClassesOnly) {
|
56
|
466
|
return new GlobalBinding(aRootPackage, this, aComponent);
|
57
|
|
}
|
58
|
235
|
public IBinding createInnerAnyTypeBinding(IComponent aComponent, IBinding aParentBinding, boolean aUseBuiltInClassesOnly) {
|
59
|
235
|
String typeName = aComponent.getLocalStringBindingAttribute(IBindingAttributes.NAME);
|
60
|
235
|
if (null == typeName) {
|
61
|
233
|
typeName = ((IAnyType)aComponent).getRoleName();
|
62
|
|
}
|
63
|
235
|
return new InnerBinding(aParentBinding, this, aComponent, typeName);
|
64
|
|
}
|
65
|
|
|
66
|
|
private static String ourBuiltInPackage = null;
|
67
|
|
static {
|
68
|
3
|
String s = IAnyTypeData.class.getName();
|
69
|
3
|
ourBuiltInPackage = s.substring(0, s.lastIndexOf('.'));
|
70
|
|
}
|
71
|
|
|
72
|
282
|
protected String doGetBuiltInPackage() {
|
73
|
282
|
return ourBuiltInPackage;
|
74
|
|
}
|
75
|
|
|
76
|
51
|
protected String interfaceOrClass() {
|
77
|
51
|
return "interface";
|
78
|
|
}
|
79
|
437
|
protected boolean treatMethods(IAnyType aType) {
|
80
|
437
|
return true;
|
81
|
|
}
|
82
|
897
|
protected boolean treatInherited() {
|
83
|
897
|
return false;
|
84
|
|
}
|
85
|
|
|
86
|
437
|
protected String declaration(IAnyType aType) {
|
87
|
437
|
String dataInterfaceExtension = "";
|
88
|
437
|
if (aType.isComplex() && !aType.getBaseType().isComplex()) {
|
89
|
198
|
dataInterfaceExtension += ", " + (aType.isSimple() ? IComplexSCData.class.getName() : IComplexCCData.class.getName());
|
90
|
|
}
|
91
|
437
|
if ((aType.getBaseType() == W3CTypes.anyListType) && ((IListType)aType.getSimpleContentType()).getItemType().isInstanceType(W3CTypes.idRef)) {
|
92
|
2
|
dataInterfaceExtension += ", " + IIDREFSData.class.getName();
|
93
|
|
}
|
94
|
437
|
String baseInterface = getBehaviourInterfaceCartridge().getUsableFqName(aType.getBaseType());
|
95
|
437
|
return new StringBuffer().append(staticOrPublic()).append(" interface ").append(getInnerName(aType)).append(" ").append("extends ").append(baseInterface).append(dataInterfaceExtension).toString();
|
96
|
|
}
|
97
|
|
|
98
|
437
|
protected String begin(IAnyType aType) {
|
99
|
437
|
IEnumerationConstraint ec = (IEnumerationConstraint)aType.getConstraints().getConstraint(ConstraintType.ENUMERATION);
|
100
|
437
|
if ((null != ec) && (null == aType.getBaseType().getConstraints().getConstraint(ConstraintType.ENUMERATION))) {
|
101
|
29
|
String typeString = getUsableFqName(aType);
|
102
|
29
|
ArrayList options = new ArrayList();
|
103
|
29
|
for (Iterator i = ec.iterOptions(); i.hasNext(); ) {
|
104
|
73
|
options.add(i.next());
|
105
|
|
}
|
106
|
29
|
Collections.sort(options, new Comparator() {
|
107
|
65
|
public int compare(Object anObject1, Object anObject2) {
|
108
|
65
|
return ((Map.Entry)anObject1).getKey().toString().compareTo(((Map.Entry)anObject2).getKey().toString());
|
109
|
|
}
|
110
|
|
});
|
111
|
29
|
for (Iterator i = options.iterator(); i.hasNext(); ) {
|
112
|
73
|
Map.Entry me = (Map.Entry)i.next();
|
113
|
73
|
String option = me.getKey().toString();
|
114
|
73
|
IHasBindingAttributes hba = (IHasBindingAttributes)me.getValue();
|
115
|
73
|
String optionConstant = hba.getLocalStringBindingAttribute("name");
|
116
|
73
|
if (null == optionConstant) {
|
117
|
69
|
optionConstant = constant(option);
|
118
|
|
}
|
119
|
73
|
writeLn(new StringBuffer("static final ").append(typeString).append(" ").append(optionConstant).append(" = (").append(typeString).append(")").append(Schemas.class.getName()).append(".getInstance().getEnumerationOption(\"").append(typeString).append("\", \"").append(option).append("\");").toString());
|
120
|
|
}
|
121
|
|
}
|
122
|
437
|
return null;
|
123
|
|
}
|
124
|
|
|
125
|
823
|
private String href(String anAttrOrElem, String aName) {
|
126
|
823
|
return "<a href=\"#" + anAttrOrElem + "_" + aName + "\">" + aName + "</a>";
|
127
|
|
}
|
128
|
|
|
129
|
340
|
private String getter(String anAttOrElm, IAnyType aType, IDataRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass) {
|
130
|
340
|
String propertyTypeName = simpleTypeName(aRefOrDecl.getType(), aUseDataClass);
|
131
|
340
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Gets the " + href(anAttOrElm, aRefOrDecl.getName()) + " " + anAttOrElm + ".\n");
|
132
|
340
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
133
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * <code>protected ").append(propertyTypeName).append(" doGet").append(propertyName(aRefOrDecl)).append("();</code>\n");
|
134
|
|
}
|
135
|
340
|
sb.append(" * @return ");
|
136
|
340
|
if (aUseDataClass || (null == aRefOrDecl.getType().getSimpleStorageType()) || !aRefOrDecl.getType().getSimpleStorageType().isPrimitive()) {
|
137
|
302
|
sb.append("<i>(optional)</i> ");
|
138
|
|
}
|
139
|
340
|
sb.append("The value.\n");
|
140
|
340
|
sb.append(" */\n");
|
141
|
340
|
sb.append(propertyTypeName).append(" get").append(propertyName(aRefOrDecl)).append("();\n");
|
142
|
340
|
return sb.toString();
|
143
|
|
}
|
144
|
|
|
145
|
120
|
protected String elementGetter(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass) {
|
146
|
120
|
return getter("element", aType, aRefOrDecl, aPropertyVariant, aUseDataClass);
|
147
|
|
}
|
148
|
220
|
protected String attributeGetter(IAnyType aType, IAttrRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass) {
|
149
|
220
|
return getter("attribute", aType, aRefOrDecl, aPropertyVariant, aUseDataClass);
|
150
|
|
}
|
151
|
|
|
152
|
122
|
private String checker(String anAttOrElm, IAnyType aType, IDataRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant) {
|
153
|
122
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Checks if the " + href(anAttOrElm, aRefOrDecl.getName()) + " " + anAttOrElm + " is present.\n");
|
154
|
122
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
155
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * <code>protected boolean doHas").append(propertyName(aRefOrDecl)).append("();</code>\n");
|
156
|
|
}
|
157
|
122
|
sb.append(" * @return Returns <code>true</code> iff the ").append(anAttOrElm).append(" is present.\n").append(" */\n").append("boolean has").append(propertyName(aRefOrDecl)).append("();\n");
|
158
|
122
|
return sb.toString();
|
159
|
|
}
|
160
|
|
|
161
|
22
|
protected String elementChecker(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant) {
|
162
|
22
|
return checker("element", aType, aRefOrDecl, aPropertyVariant);
|
163
|
|
}
|
164
|
100
|
protected String attributeChecker(IAnyType aType, IAttrRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant) {
|
165
|
100
|
return checker("attribute", aType, aRefOrDecl, aPropertyVariant);
|
166
|
|
}
|
167
|
|
|
168
|
12
|
protected String elementRemover(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant) {
|
169
|
12
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Removes the " + href("element", aRefOrDecl.getName()) + " element.\n").append(" * If there is no corresponding element then this method does nothing.\n");
|
170
|
12
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
171
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * <code>protected void doRemove").append(propertyName(aRefOrDecl)).append("();</code>\n");
|
172
|
|
}
|
173
|
12
|
sb.append(" */\n").append("void remove").append(propertyName(aRefOrDecl)).append("();\n");
|
174
|
12
|
return sb.toString();
|
175
|
|
}
|
176
|
|
|
177
|
57
|
protected String attributeRemover(IAnyType aType, IAttrRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant) {
|
178
|
57
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Removes the " + href("attribute", aRefOrDecl.getName()) + " attribute.\n").append(" * If the attribute has a default (or fixed) value than a new attribute is created (on demand).\n");
|
179
|
57
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
180
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * <code>protected void doRemove").append(propertyName(aRefOrDecl)).append("() throws ").append(XmlException.class.getName()).append(";</code>\n");
|
181
|
|
}
|
182
|
57
|
sb.append(" * @throws ").append(XmlException.class.getName()).append(" Raised if it is tried to remove a required attribute.\n").append(" */\n").append("void remove").append(propertyName(aRefOrDecl)).append("() throws ").append(XmlException.class.getName()).append(";\n");
|
183
|
57
|
return sb.toString();
|
184
|
|
}
|
185
|
|
|
186
|
5
|
protected String elementCreator(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant) {
|
187
|
5
|
String dataTypeName = interfaceName(aRefOrDecl.getType());
|
188
|
5
|
String ssoTypeName = null;
|
189
|
5
|
if (null != aRefOrDecl.getType().getSimpleContentType()) {
|
190
|
4
|
ssoTypeName = aRefOrDecl.getType().getSimpleContentType().getSimpleStorageType().getName();
|
191
|
|
}
|
192
|
5
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Creates a " + href("element", aRefOrDecl.getName()) + " element.\n");
|
193
|
5
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
194
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * <code>protected ").append(dataTypeName).append(" doCreate").append(propertyName(aRefOrDecl)).append("(").append((null != ssoTypeName) ? ssoTypeName + " aValue, " : "").append(IAnyType.class.getName()).append(" anOverloadingType) throws XmlException;</code>\n");
|
195
|
|
}
|
196
|
5
|
if (null != ssoTypeName) {
|
197
|
4
|
sb.append(" * @param aValue ").append(aRefOrDecl.getType().getSimpleContentType().getSimpleStorageType().isPrimitive() ? "" : "<i>(required)</i>. ").append("The simple content of the element\n");
|
198
|
|
}
|
199
|
5
|
sb.append(" * return <i>(required)</i>.\n").append(" * @throws ").append(XmlException.class.getName()).append(" Raised if the element could not be created.\n").append(" */\n").append(dataTypeName).append(" create").append(propertyName(aRefOrDecl)).append("(").append((null != ssoTypeName) ? ssoTypeName + " aValue" : "").append(") throws ").append(XmlException.class.getName()).append(";\n");
|
200
|
5
|
return sb.toString();
|
201
|
|
}
|
202
|
|
|
203
|
15
|
protected String elementCreatorWithType(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant) {
|
204
|
15
|
String dataTypeName = interfaceName(aRefOrDecl.getType());
|
205
|
15
|
String ssoTypeName = null;
|
206
|
15
|
if (null != aRefOrDecl.getType().getSimpleContentType()) {
|
207
|
8
|
ssoTypeName = aRefOrDecl.getType().getSimpleContentType().getSimpleStorageType().getName();
|
208
|
|
}
|
209
|
15
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Creates a " + href("element", aRefOrDecl.getName()) + " element.\n");
|
210
|
15
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
211
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * <code>protected ").append(dataTypeName).append(" doCreate").append(propertyName(aRefOrDecl)).append("(").append((null != ssoTypeName) ? ssoTypeName + " aValue, " : "").append(IAnyType.class.getName()).append(" anOverloadingType) throws XmlException;</code>\n");
|
212
|
|
}
|
213
|
15
|
if (null != ssoTypeName) {
|
214
|
8
|
sb.append(" * @param aValue ").append(aRefOrDecl.getType().getSimpleContentType().getSimpleStorageType().isPrimitive() ? "" : "<i>(required)</i>. ").append("The simple content of the element\n");
|
215
|
|
}
|
216
|
15
|
sb.append(" * @param anOverloadingType <i>(optional)</i> The type of the element to be created. Must be a subtype of the declared element type.\n");
|
217
|
15
|
sb.append(" * return <i>(required)</i>.\n").append(" * @throws ").append(XmlException.class.getName()).append(" Raised if the element could not be created.\n").append(" */\n").append(dataTypeName).append(" create").append(propertyName(aRefOrDecl)).append("(").append((null != ssoTypeName) ? ssoTypeName + " aValue, " : "").append(IAnyType.class.getName()).append(" anOverloadingType) throws ").append(XmlException.class.getName()).append(";\n");
|
218
|
15
|
return sb.toString();
|
219
|
|
}
|
220
|
|
|
221
|
210
|
protected String elementIterator(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass) {
|
222
|
210
|
String iteratedType = null;
|
223
|
210
|
if (aUseDataClass || (null == aRefOrDecl.getType().getSimpleStorageType())) {
|
224
|
191
|
iteratedType = interfaceName(aRefOrDecl.getType());
|
225
|
|
} else {
|
226
|
19
|
iteratedType = simpleStorageObjectTypeName(aRefOrDecl.getType());
|
227
|
|
}
|
228
|
210
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Iterates the " + href("element", aRefOrDecl.getName()) + " elements.\n");
|
229
|
210
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
230
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * <code>ListIterator doIter").append(pluralForm(propertyName(aRefOrDecl))).append("();</code>\n");
|
231
|
|
}
|
232
|
210
|
sb.append(" * @return Returns a list iterator of {@link ").append(iteratedType).append("}.\n").append(" */\n").append("java.util.ListIterator iter").append(pluralForm(propertyName(aRefOrDecl))).append("();\n");
|
233
|
210
|
return sb.toString();
|
234
|
|
}
|
235
|
|
|
236
|
220
|
protected String attributeIterator(IAnyType aType, IAttrRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass) {
|
237
|
220
|
String res = null;
|
238
|
220
|
if (aRefOrDecl.getType() instanceof IListType) {
|
239
|
5
|
String iteratedType = null;
|
240
|
5
|
ISimpleType itemType = ((IListType)aRefOrDecl.getType()).getItemType();
|
241
|
5
|
if (aUseDataClass) {
|
242
|
0
|
iteratedType = interfaceName(itemType);
|
243
|
|
} else {
|
244
|
5
|
iteratedType = simpleStorageObjectTypeName(itemType);
|
245
|
|
}
|
246
|
5
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Iterates the items of the list valued " + href("attribute", aRefOrDecl.getName()) + " attribute.\n");
|
247
|
5
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
248
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * <code>java.util.ListIterator doIter").append(propertyName(aRefOrDecl)).append("();</code>\n");
|
249
|
|
}
|
250
|
5
|
sb.append(" * @return <i>(required)</i>. Returns a list iterator of {@link ").append(iteratedType).append("}.\n").append(" */\n").append("java.util.ListIterator iter").append(propertyName(aRefOrDecl)).append("();\n");
|
251
|
5
|
res = sb.toString();
|
252
|
|
}
|
253
|
220
|
return res;
|
254
|
|
}
|
255
|
|
|
256
|
57
|
protected String attributeSetter(IAnyType aType, IAttrRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass) {
|
257
|
57
|
aUseDataClass = false;
|
258
|
57
|
String propertyTypeName = simpleTypeName(aRefOrDecl.getType(), aUseDataClass);
|
259
|
57
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Sets the " + href("attribute", aRefOrDecl.getName()) + " attribute.\n");
|
260
|
57
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
261
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * <code>protected void doSet").append(propertyName(aRefOrDecl)).append("(").append(propertyTypeName).append(" aValue) throws XmlException;</code>\n");
|
262
|
|
}
|
263
|
57
|
sb.append(" * @param aValue").append((aUseDataClass || !aRefOrDecl.getType().getSimpleStorageType().isPrimitive()) ? " <i>(optional)</i>.\n" : " The new value.\n").append(" * @throws org.jbind.xml.msg.XmlException Raised if the value could not be set.\n").append(" */\n").append("void set").append(propertyName(aRefOrDecl)).append("(").append(propertyTypeName).append(" aValue) throws ").append(XmlException.class.getName()).append(";\n");
|
264
|
57
|
return sb.toString();
|
265
|
|
}
|
266
|
|
|
267
|
5
|
protected String referenceGetter(IAnyType aType, RefConstraintInfo aConstraintInfo, MethodVariant aPropertyVariant) {
|
268
|
5
|
StringBuffer sb = new StringBuffer();
|
269
|
5
|
sb.append("\n").append("/**\n").append(" * Gets the data object referenced by the "").append(aConstraintInfo.comment).append("" reference constraint.\n");
|
270
|
5
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
271
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * ").append(interfaceName(aConstraintInfo.dataType)).append(" doRef").append(aConstraintInfo.propertyName).append("();\n");
|
272
|
|
}
|
273
|
5
|
sb.append(" * @return The referenced data object.\n").append(" */\n").append(interfaceName(aConstraintInfo.dataType)).append(" ref").append(aConstraintInfo.propertyName).append("();\n");
|
274
|
5
|
return sb.toString();
|
275
|
|
}
|
276
|
|
|
277
|
3
|
protected String referenceIterator(IAnyType aType, RefConstraintInfo aConstraintInfo, MethodVariant aPropertyVariant) {
|
278
|
3
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Iterates the data objects referenced by the "").append(aConstraintInfo.comment).append("" reference constraint.\n");
|
279
|
3
|
if (MethodVariant.HOOK == aPropertyVariant) {
|
280
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * java.util.Iterator doRefs").append(aConstraintInfo.propertyName).append("();\n");
|
281
|
|
}
|
282
|
3
|
sb.append(" * @return <i>required</i>. Returns an iterator of {@link ").append(interfaceName(aConstraintInfo.dataType)).append("}.\n").append(" */\n").append("java.util.Iterator refs").append(aConstraintInfo.propertyName).append("();\n");
|
283
|
3
|
return sb.toString();
|
284
|
|
}
|
285
|
|
|
286
|
6
|
protected String xPathMethod(IAnyType aType, IXPathMethod aMethod, MethodVariant aVariant) {
|
287
|
6
|
String returnType = null;
|
288
|
6
|
if (null != aMethod.getReferencedType()) {
|
289
|
0
|
returnType = interfaceName(aMethod.getReferencedType());
|
290
|
|
} else {
|
291
|
6
|
returnType = aMethod.getReturnType();
|
292
|
|
}
|
293
|
6
|
StringBuffer sb = new StringBuffer().append("/**\n").append(" * Evaluates the XPath "").append(StringUtil.toXml(aMethod.getXPath().asString())).append("".\n");
|
294
|
6
|
if (MethodVariant.HOOK == aVariant) {
|
295
|
0
|
sb.append(" * The underlying data class implements the hook method:<br>\n").append(" * " + returnType + " do" + StringUtil.firstUpper(aMethod.getPrefix())).append(StringUtil.firstUpper(aMethod.getName())).append("() throws ").append(XmlException.class.getName()).append(";\n");
|
296
|
|
}
|
297
|
6
|
sb.append(" * @return The evaluation result.\n").append(" */\n").append(returnType + " " + aMethod.getPrefix()).append(StringUtil.firstUpper(aMethod.getName())).append("() throws ").append(XmlException.class.getName()).append(";\n");
|
298
|
6
|
return sb.toString();
|
299
|
|
}
|
300
|
|
|
301
|
|
//
|
302
|
|
// type comment
|
303
|
|
//
|
304
|
|
|
305
|
437
|
protected String typeComment(IAnyType aType) {
|
306
|
437
|
JavaDoc doc = new JavaDoc();
|
307
|
437
|
interfaceComment(doc, aType);
|
308
|
437
|
if (aType.getAttributesModel().iterAttributes().hasNext()) {
|
309
|
129
|
new AttrDocumenter(doc, aType).document();
|
310
|
|
}
|
311
|
437
|
if (aType.getContentModel().iterElements().hasNext()) {
|
312
|
204
|
new ElemDocumenter(doc, aType).document();
|
313
|
|
}
|
314
|
437
|
return doc.endJavaDoc();
|
315
|
|
}
|
316
|
|
|
317
|
|
private static final ILanguage JAVA_DOC_LANGUAGE = Language.createLanguage("x-javaDoc");
|
318
|
|
|
319
|
437
|
private void interfaceComment(JavaDoc aDoc, IAnyType aType) {
|
320
|
437
|
String comment = getComment(aType);
|
321
|
437
|
aDoc.addLines(comment);
|
322
|
437
|
if (null != comment) {
|
323
|
1
|
aDoc.addLine("<P>");
|
324
|
|
}
|
325
|
|
|
326
|
|
//
|
327
|
|
// type kind
|
328
|
|
//
|
329
|
|
|
330
|
437
|
String typeKind = null;
|
331
|
437
|
if (aType.isComplex() && !aType.isSimple()) {
|
332
|
285
|
String mixed = aType.getContentModel().isMixed() ? "mixed " : "";
|
333
|
285
|
if (aType.getContentModel().isEmpty()) {
|
334
|
67
|
typeKind = "complex type with empty " + mixed + "content model.";
|
335
|
|
} else {
|
336
|
218
|
typeKind = "complex type with complex " + mixed + "content model.";
|
337
|
|
}
|
338
|
152
|
} else if (aType.isComplex() && aType.isSimple()) {
|
339
|
18
|
typeKind = "complex type with simple content model.";
|
340
|
|
} else {
|
341
|
134
|
typeKind = "simple type";
|
342
|
|
}
|
343
|
437
|
aDoc.addLine(aType.isAnonymous() ? "Anonymous " + typeKind : StringUtil.firstUpper(typeKind)).addLine("<P>");
|
344
|
|
|
345
|
|
//
|
346
|
|
// TODO document constraints
|
347
|
|
//
|
348
|
|
|
349
|
|
}
|
350
|
|
|
351
|
2257
|
private String getComment(IComponent aComponent) {
|
352
|
2257
|
String res = null;
|
353
|
2257
|
IAnnotation ann = aComponent.getAnnotation();
|
354
|
2257
|
if (ann != null) {
|
355
|
98
|
IDocumentation doc = ann.getDocumentation(JAVA_DOC_LANGUAGE);
|
356
|
98
|
if (doc != null) {
|
357
|
3
|
res = doc.getText();
|
358
|
|
}
|
359
|
|
}
|
360
|
2257
|
return res;
|
361
|
|
}
|
362
|
|
|
363
|
|
//
|
364
|
|
// attribute documenter
|
365
|
|
//
|
366
|
|
|
367
|
|
private class AttrDocumenter extends AttrOrElemDocumenter {
|
368
|
|
|
369
|
129
|
public AttrDocumenter(JavaDoc aJavaDoc, IAnyType aType) {
|
370
|
129
|
super(aJavaDoc, aType);
|
371
|
|
}
|
372
|
129
|
protected void doItemSummaries() {
|
373
|
129
|
for (Iterator i = myType.getAttributesModel().iterAttributes();
|
374
|
520
|
i.hasNext(); ) {
|
375
|
391
|
IAttrRefOrDecl attr = (IAttrRefOrDecl)i.next();
|
376
|
391
|
summarizeItem(attr);
|
377
|
|
}
|
378
|
|
}
|
379
|
129
|
protected void doItemDetails() {
|
380
|
129
|
for (Iterator i = myType.getAttributesModel().iterAttributes();
|
381
|
520
|
i.hasNext(); ) {
|
382
|
391
|
IAttrRefOrDecl attr = (IAttrRefOrDecl)i.next();
|
383
|
391
|
detailItem(attr);
|
384
|
391
|
if (i.hasNext()) {
|
385
|
262
|
myDoc.addLine("<HR>");
|
386
|
|
}
|
387
|
|
}
|
388
|
|
}
|
389
|
782
|
protected String itemSummaryInfo(IDataRefOrDecl anAttrOrElem) {
|
390
|
782
|
IAttrRefOrDecl attr = (IAttrRefOrDecl)anAttrOrElem;
|
391
|
782
|
StringBuffer sb = new StringBuffer();
|
392
|
782
|
sb.append("use: ").append(attr.getOccurence()).append(";");
|
393
|
782
|
if (null != attr.getFixed()) {
|
394
|
48
|
sb.append(" fixed: ").append(attr.getFixed()).append(";");
|
395
|
|
}
|
396
|
782
|
if (null != attr.getDefault()) {
|
397
|
154
|
sb.append(" default: ").append(attr.getDefault()).append(";");
|
398
|
|
}
|
399
|
782
|
sb.append(" propertyName: ").append(DataInterfaceCartridge.this.propertyName(attr));
|
400
|
782
|
return sb.toString();
|
401
|
|
}
|
402
|
1298
|
protected String attrOrElem() {
|
403
|
1298
|
return "attribute";
|
404
|
|
}
|
405
|
|
}
|
406
|
|
|
407
|
|
//
|
408
|
|
// element documenter
|
409
|
|
//
|
410
|
|
|
411
|
|
private class ElemDocumenter extends AttrOrElemDocumenter {
|
412
|
|
|
413
|
204
|
public ElemDocumenter(JavaDoc aJavaDoc, IAnyType aType) {
|
414
|
204
|
super(aJavaDoc, aType);
|
415
|
|
}
|
416
|
204
|
protected void doItemSummaries() {
|
417
|
204
|
for (Iterator i = myType.getContentModel().iterElements(); i.hasNext(); ) {
|
418
|
519
|
IElemRefOrDecl elem = (IElemRefOrDecl)i.next();
|
419
|
519
|
summarizeItem(elem);
|
420
|
|
}
|
421
|
|
}
|
422
|
204
|
protected void doItemDetails() {
|
423
|
204
|
for (Iterator i = myType.getContentModel().iterElements(); i.hasNext(); ) {
|
424
|
519
|
IElemRefOrDecl elem = (IElemRefOrDecl)i.next();
|
425
|
519
|
detailItem(elem);
|
426
|
519
|
if (i.hasNext()) {
|
427
|
315
|
myDoc.addLine("<HR>");
|
428
|
|
}
|
429
|
|
}
|
430
|
|
}
|
431
|
1038
|
protected String itemSummaryInfo(IDataRefOrDecl anAttrOrElem) {
|
432
|
1038
|
IElemRefOrDecl elem = (IElemRefOrDecl)anAttrOrElem;
|
433
|
1038
|
IRange r = myType.getContentModel().getRange(elem.getGlobalRef());
|
434
|
1038
|
StringBuffer sb = new StringBuffer();
|
435
|
1038
|
sb.append("minOccurs: " + r.getMinOccurs() + ";");
|
436
|
1038
|
sb.append(" maxOccurs: " + (r.isUnbounded() ? "unbounded" : "" + r.getMaxOccurs()) + ";");
|
437
|
1038
|
if (null != elem.getFixed()) {
|
438
|
6
|
sb.append(" fixed: ").append(elem.getFixed()).append(";");
|
439
|
|
}
|
440
|
1038
|
if (null != elem.getDefault()) {
|
441
|
20
|
sb.append(" default: ").append(elem.getDefault()).append(";");
|
442
|
|
}
|
443
|
1038
|
sb.append(" propertyName: ").append(DataInterfaceCartridge.this.propertyName(elem));
|
444
|
1038
|
return sb.toString();
|
445
|
|
}
|
446
|
1854
|
protected String attrOrElem() {
|
447
|
1854
|
return "element";
|
448
|
|
}
|
449
|
|
}
|
450
|
|
|
451
|
|
//
|
452
|
|
//
|
453
|
|
//
|
454
|
|
|
455
|
|
private abstract class AttrOrElemDocumenter {
|
456
|
|
|
457
|
|
protected JavaDoc myDoc;
|
458
|
|
protected IAnyType myType;
|
459
|
333
|
protected AttrOrElemDocumenter(JavaDoc aJavaDoc, IAnyType aType) {
|
460
|
333
|
myDoc = aJavaDoc;
|
461
|
333
|
myType = aType;
|
462
|
|
}
|
463
|
333
|
public void document() {
|
464
|
333
|
startSummaries();
|
465
|
333
|
doItemSummaries();
|
466
|
333
|
endSummaries();
|
467
|
333
|
myDoc.addLine("<P>");
|
468
|
333
|
startDetails();
|
469
|
333
|
doItemDetails();
|
470
|
333
|
endDetails();
|
471
|
333
|
myDoc.addLine("<P>");
|
472
|
|
}
|
473
|
333
|
private void startSummaries() {
|
474
|
333
|
myDoc.addLine("<A NAME=\"" + attrOrElem() + "_summary\"><!-- --></A>").addLine("<TABLE BORDER=\"1\" CELLPADDING=\"3\" CELLSPACING=\"0\" WIDTH=\"100%\">").addLine("<TR BGCOLOR=\"#CCCCFF\" CLASS=\"TableHeadingColor\">").addLine("<TD COLSPAN=\"2\"><FONT SIZE=\"+2\">").addLine("<B>" + StringUtil.firstUpper(attrOrElem()) + " Summary</B></FONT></TD>").addLine("</TR>");
|
475
|
|
}
|
476
|
333
|
private void endSummaries() {
|
477
|
333
|
myDoc.addLine("</TABLE>\n");
|
478
|
|
}
|
479
|
|
|
480
|
333
|
private void startDetails() {
|
481
|
333
|
myDoc.addLine("<A NAME=\"" + attrOrElem() + "_detail\"><!-- --></A>").addLine("<TABLE BORDER=\"1\" CELLPADDING=\"3\" CELLSPACING=\"0\" WIDTH=\"100%\">").addLine("<TR BGCOLOR=\"#CCCCFF\" CLASS=\"TableHeadingColor\">").addLine("<TD COLSPAN=\"1\"><FONT SIZE=\"+2\">").addLine("<B>" + StringUtil.firstUpper(attrOrElem()) + " Detail</B></FONT></TD>").addLine("</TR>").addLine("</TABLE>");
|
482
|
|
}
|
483
|
333
|
private void endDetails() {}
|
484
|
|
|
485
|
910
|
private String firstCommentSentence(IDataRefOrDecl anAttrOrElem) {
|
486
|
910
|
String comment = DataInterfaceCartridge.this.getComment(anAttrOrElem);
|
487
|
910
|
if (null == comment) {
|
488
|
909
|
return null;
|
489
|
|
}
|
490
|
1
|
BreakIterator i = BreakIterator.getSentenceInstance(Locale.ENGLISH);
|
491
|
1
|
i.setText(comment);
|
492
|
1
|
int first = i.first();
|
493
|
1
|
int next = i.next();
|
494
|
1
|
if (next != BreakIterator.DONE) {
|
495
|
1
|
return comment.substring(first, next);
|
496
|
|
}
|
497
|
0
|
return comment;
|
498
|
|
}
|
499
|
|
|
500
|
1820
|
private String getItemTypeName(IDataRefOrDecl anAttrOrElem) {
|
501
|
1820
|
boolean useDataClass = DataInterfaceCartridge.this.useDataClass(anAttrOrElem);
|
502
|
1820
|
String typeName = DataInterfaceCartridge.this.simpleTypeName(anAttrOrElem.getType(), useDataClass);
|
503
|
1820
|
return typeName;
|
504
|
|
}
|
505
|
|
|
506
|
866
|
private String getItemDataTypeName(IDataRefOrDecl anAttrOrElem) {
|
507
|
866
|
return DataInterfaceCartridge.this.interfaceName(anAttrOrElem.getType());
|
508
|
|
}
|
509
|
|
|
510
|
1820
|
private boolean hasPrimitiveType(IDataRefOrDecl anAttrOrElem) {
|
511
|
1820
|
boolean useDataClass = DataInterfaceCartridge.this.useDataClass(anAttrOrElem);
|
512
|
1820
|
return !useDataClass && (null != anAttrOrElem.getType().getSimpleStorageType()) && anAttrOrElem.getType().getSimpleStorageType().isPrimitive();
|
513
|
|
}
|
514
|
|
|
515
|
1820
|
private boolean hasSimpleStorageType(IDataRefOrDecl anAttrOrElem) {
|
516
|
1820
|
boolean useDataClass = DataInterfaceCartridge.this.useDataClass(anAttrOrElem);
|
517
|
1820
|
return !useDataClass && (null != anAttrOrElem.getType().getSimpleStorageType());
|
518
|
|
}
|
519
|
|
|
520
|
910
|
protected void summarizeItem(IDataRefOrDecl anAttrOrElem) {
|
521
|
910
|
myDoc.addLine("<TR BGCOLOR=\"white\" CLASS=\"TableRowColor\">").addLine("<TD ALIGN=\"right\" VALIGN=\"top\" WIDTH=\"1%\"><FONT SIZE=\"-1\">");
|
522
|
910
|
myDoc.startLine().append("<CODE> ");
|
523
|
910
|
if (hasPrimitiveType(anAttrOrElem)) {
|
524
|
46
|
myDoc.append(getItemTypeName(anAttrOrElem));
|
525
|
|
} else {
|
526
|
864
|
myDoc.append("{@link " + getItemTypeName(anAttrOrElem) + "}");
|
527
|
|
}
|
528
|
910
|
if (hasSimpleStorageType(anAttrOrElem)) {
|
529
|
433
|
myDoc.append("<BR> ({@link " + getItemDataTypeName(anAttrOrElem) + "})");
|
530
|
|
}
|
531
|
910
|
myDoc.append("</CODE></FONT></TD>").endLine().startLine().append("<TD><CODE><B><A HREF=\"#" + attrOrElem() + "_" + anAttrOrElem.getName() + "\">" + anAttrOrElem.getName() + "</A></B></CODE>").append(" " + itemSummaryInfo(anAttrOrElem)).endLine().addLine("<BR>").startLine().append(" ").append(firstCommentSentence(anAttrOrElem)).append("</TD>").endLine().addLine("</TR>");
|
532
|
|
}
|
533
|
|
|
534
|
910
|
protected void detailItem(IDataRefOrDecl anAttrOrElem) {
|
535
|
910
|
myDoc.addLine("<A NAME=\"" + attrOrElem() + "_" + anAttrOrElem.getName() + "\"><!-- --></A><H3>").addLine(anAttrOrElem.getName() + "</H3>").startLine().append("type: <CODE>");
|
536
|
910
|
if (hasPrimitiveType(anAttrOrElem)) {
|
537
|
46
|
myDoc.append(getItemTypeName(anAttrOrElem));
|
538
|
|
} else {
|
539
|
864
|
myDoc.append("{@link " + getItemTypeName(anAttrOrElem) + "}");
|
540
|
|
}
|
541
|
910
|
if (hasSimpleStorageType(anAttrOrElem)) {
|
542
|
433
|
myDoc.append(" ({@link " + getItemDataTypeName(anAttrOrElem) + "})");
|
543
|
|
}
|
544
|
910
|
myDoc.append("</CODE> " + itemSummaryInfo(anAttrOrElem)).endLine().addLine("<BR><DL><DD>").addLines(DataInterfaceCartridge.this.getComment(anAttrOrElem)).addLine("</DD></DL>");
|
545
|
|
}
|
546
|
|
|
547
|
|
protected abstract void doItemSummaries();
|
548
|
|
protected abstract void doItemDetails();
|
549
|
|
protected abstract String attrOrElem();
|
550
|
|
protected abstract String itemSummaryInfo(IDataRefOrDecl anAttrOrElem);
|
551
|
|
|
552
|
|
}
|
553
|
|
|
554
|
|
private static class JavaDoc {
|
555
|
|
|
556
|
|
private StringBuffer myStringBuffer;
|
557
|
437
|
public JavaDoc() {
|
558
|
437
|
myStringBuffer = new StringBuffer("/**\n");
|
559
|
|
}
|
560
|
60779
|
public JavaDoc append(Object anObject) {
|
561
|
60779
|
if (null != anObject) {
|
562
|
59870
|
myStringBuffer.append(anObject);
|
563
|
|
}
|
564
|
60779
|
return this;
|
565
|
|
}
|
566
|
|
|
567
|
17702
|
public JavaDoc startLine() {
|
568
|
17702
|
return append(" * ");
|
569
|
|
}
|
570
|
17702
|
public JavaDoc endLine() {
|
571
|
17702
|
return append("\n");
|
572
|
|
}
|
573
|
|
|
574
|
14062
|
public JavaDoc addLine(Object anObject) {
|
575
|
14062
|
return startLine().append(anObject).endLine();
|
576
|
|
}
|
577
|
437
|
public String endJavaDoc() {
|
578
|
437
|
append(" */\n");
|
579
|
437
|
return myStringBuffer.toString();
|
580
|
|
}
|
581
|
1347
|
public JavaDoc addLines(String aString) {
|
582
|
1347
|
if (null == aString) {
|
583
|
1345
|
return this;
|
584
|
|
}
|
585
|
2
|
for (Enumeration e = new StringTokenizer(aString, "\n");
|
586
|
4
|
e.hasMoreElements(); ) {
|
587
|
2
|
String s = (String)e.nextElement();
|
588
|
2
|
addLine(s);
|
589
|
|
}
|
590
|
2
|
return this;
|
591
|
|
}
|
592
|
|
}
|
593
|
|
}
|
594
|
|
|