1 /**
2  *   Copyright © 2008-2012 NetAllied Systems GmbH, Ravensburg, Germany.
3  *
4  *   Licensed under the MIT Open Source License,
5  *   for details please see LICENSE file or the website
6  *   http://www.opensource.org/licenses/mit-license.php
7 */
8 package de.netallied.xsd2cppsax.printers;
9 
10 import java.io.FileNotFoundException;
11 import java.io.PrintStream;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.SortedMap;
15 import java.util.TreeMap;
16 
17 import org.apache.xerces.xs.XSAttributeUse;
18 import org.apache.xerces.xs.XSElementDeclaration;
19 import org.apache.xerces.xs.XSSimpleTypeDefinition;
20 
21 import de.netallied.xsd2cppsax.IGenerationDataProvider;
22 import de.netallied.xsd2cppsax.TemplateEngine;
23 import de.netallied.xsd2cppsax.Util;
24 import de.netallied.xsd2cppsax.Variety;
25 
26 /**
27  * Prints a specialized Parser for coherence testing of COLLADA 1.4 documents.
28  *
29  */
30 public class SaxCoherencyTest14ParserPrinter extends AbstractParserImplementationPrinter {
31 
32     /** Name of C++ count attribute member. */
33     private String countAttributeName;
34 
35     /** Name of C++ error handler. */
36     private String errorHandlerName;
37 
38     /** Generated example C++ header file. */
39     private PrintStream headerFile;
40 
41     /** Name of C++ ID counter map. */
42     private String idCounterMapName;
43 
44     /** Name of C++ list count member. */
45     private String listCountName;
46 
47     /** Generated example C++ source file. */
48     private PrintStream sourceFile;
49 
50     /**
51      * C-tor.
52      *
53      * @param dataProvider
54      *            {@link IGenerationDataProvider} to be used.
55      */
SaxCoherencyTest14ParserPrinter(IGenerationDataProvider dataProvider)56     public SaxCoherencyTest14ParserPrinter(IGenerationDataProvider dataProvider) {
57         super(dataProvider);
58         errorHandlerName = getConfig().getCoherencyTestErrorHandlerName();
59         idCounterMapName = getConfig().getCoherencyTestIdCounterMapName();
60         countAttributeName = getConfig().getCoherencyTestCountAttributeMemberName();
61         listCountName = getConfig().getCoherencyTestListCountMemberName();
62     }
63 
64     /**
65      * Prints begin-method test which compares count attribute and list length.
66      *
67      */
checkCountSimpleBegin(String cppElementName, XSElementDeclaration element)68     protected void checkCountSimpleBegin(String cppElementName, XSElementDeclaration element) {
69         List<XSAttributeUse> attributeUses = Util.collectAttributeUses(element);
70         for (XSAttributeUse attrUse : attributeUses) {
71             String attributeName = Util.getAttributeName(attrUse, getConfig());
72             if (attributeName.equals("count")) {
73                 String cppCode = getConfig().getTemplateCoherencyTestSimpleCountCheckBegin();
74                 cppCode = TemplateEngine.fillInCoherencyTestTemplate(cppCode, getGenerationDataProvider());
75                 cppCode = TemplateEngine.fillInTemplate(cppCode, cppElementName, element, attrUse, null, null, null,
76                         getGenerationDataProvider());
77                 sourceFile.println(cppCode);
78                 break;
79             }
80         }
81     }
82 
83     /**
84      * Prints data-method test which compares count attribute and list length.
85      *
86      */
checkCountSimpleData(String cppElementName, XSElementDeclaration element)87     protected void checkCountSimpleData(String cppElementName, XSElementDeclaration element) {
88         List<XSAttributeUse> attributeUses = Util.collectAttributeUses(element);
89         for (XSAttributeUse attrUse : attributeUses) {
90             String attributeName = Util.getAttributeName(attrUse, getConfig());
91             if (attributeName.equals("count")) {
92                 String cppCode = getConfig().getTemplateCoherencyTestSimpleCountCheckData();
93                 cppCode = TemplateEngine.fillInCoherencyTestTemplate(cppCode, getGenerationDataProvider());
94                 cppCode = TemplateEngine.fillInTemplate(cppCode, cppElementName, element, attrUse, null, null, null,
95                         getGenerationDataProvider());
96                 sourceFile.println(cppCode);
97                 break;
98             }
99         }
100     }
101 
102     /**
103      * Prints end-method test which compares count attribute and list length.
104      *
105      */
checkCountSimpleEnd(String cppElementName, XSElementDeclaration element)106     protected void checkCountSimpleEnd(String cppElementName, XSElementDeclaration element) {
107         List<XSAttributeUse> attributeUses = Util.collectAttributeUses(element);
108         for (XSAttributeUse attrUse : attributeUses) {
109             String attributeName = Util.getAttributeName(attrUse, getConfig());
110             if (attributeName.equals("count")) {
111                 String cppCode = getConfig().getTemplateCoherencyTestSimpleCountCheckEnd();
112                 cppCode = TemplateEngine.fillInCoherencyTestTemplate(cppCode, getGenerationDataProvider());
113                 cppCode = TemplateEngine.fillInTemplate(cppCode, cppElementName, element, attrUse, null, null, null,
114                         getGenerationDataProvider());
115                 sourceFile.println(cppCode);
116                 break;
117             }
118         }
119     }
120 
121     /**
122      * Prints test which checks for unique IDs.
123      *
124      */
checkIdUnique(String cppElementName, XSElementDeclaration element)125     protected void checkIdUnique(String cppElementName, XSElementDeclaration element) {
126         List<XSAttributeUse> attributeUses = Util.collectAttributeUses(element);
127         for (XSAttributeUse attrUse : attributeUses) {
128             String attributeName = Util.getAttributeName(attrUse, getConfig());
129             if (attributeName.toLowerCase().equals("id")) {
130                 String cppCode = getConfig().getTemplateCoherencyTestCheckIdUnique();
131                 cppCode = TemplateEngine.fillInCoherencyTestTemplate(cppCode, getGenerationDataProvider());
132                 cppCode = TemplateEngine.fillInTemplate(cppCode, cppElementName, element, attrUse, null, null, null,
133                         getGenerationDataProvider());
134                 sourceFile.println(cppCode);
135                 break;
136             }
137         }
138     }
139 
140     /**
141      * {@inheritDoc}
142      *
143      * @see de.netallied.xsd2cppsax.printers.ICodePrinter#cleanupOutputFiles()
144      */
cleanupOutputFiles()145     public void cleanupOutputFiles() {
146         if (headerFile != null) {
147             printHeaderFileEnd();
148             headerFile.close();
149         }
150         if (sourceFile != null) {
151             printSourceFileEnd();
152             sourceFile.close();
153         }
154     }
155 
156     /**
157      * {@inheritDoc}
158      *
159      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getAdditionalBaseClasses()
160      */
161     @Override
getAdditionalBaseClasses()162     protected List<String> getAdditionalBaseClasses() {
163         return new ArrayList<String>();
164     }
165 
166     /**
167      * {@inheritDoc}
168      *
169      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getClassName()
170      */
171     @Override
getClassName()172     protected String getClassName() {
173         return getConfig().getCoherencyTestParserClassName();
174     }
175 
176     /**
177      * {@inheritDoc}
178      *
179      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getCtorParas()
180      */
181     @Override
getCtorParas()182     protected String getCtorParas() {
183         return getConfig().getCoherencyTestCtorParas();
184     }
185 
186     /**
187      * {@inheritDoc}
188      *
189      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getCtorTmpl()
190      */
191     @Override
getCtorTmpl()192     protected String getCtorTmpl() {
193         return new String();
194     }
195 
196     /**
197      * {@inheritDoc}
198      *
199      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getDtorTmpl()
200      */
201     @Override
getDtorTmpl()202     protected String getDtorTmpl() {
203         return new String();
204     }
205 
206     /**
207      * {@inheritDoc}
208      *
209      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getHeaderFile()
210      */
211     @Override
getHeaderFile()212     protected PrintStream getHeaderFile() {
213         return headerFile;
214     }
215 
216     /**
217      * {@inheritDoc}
218      *
219      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getHeaderFileName()
220      */
221     @Override
getHeaderFileName()222     protected String getHeaderFileName() {
223         return getConfig().getOutputCoherencyTestHeaderFileName();
224     }
225 
226     /**
227      * {@inheritDoc}
228      *
229      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getIncludeFiles()
230      */
231     @Override
getIncludeFiles()232     protected List<String> getIncludeFiles() {
233         List<String> incs = new ArrayList<String>();
234         incs.add("CoherencyTestErrorHandler.h");
235         incs.add("map");
236         return incs;
237     }
238 
239     /**
240      * {@inheritDoc}
241      *
242      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getInitializationList()
243      */
244     @Override
getInitializationList()245     protected List<String> getInitializationList() {
246         return getConfig().getCoherencyTestInitializationList();
247     }
248 
249     /**
250      * {@inheritDoc}
251      *
252      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getMembers()
253      */
254     @Override
getMembers()255     protected SortedMap<String, String> getMembers() {
256         SortedMap<String, String> members = new TreeMap<String, String>();
257         members.put(errorHandlerName, "CoherencyTestErrorHandler*");
258         members.put(idCounterMapName, "IDCounterMap");
259         members.put(countAttributeName, "uint64");
260         members.put(listCountName, "uint64");
261         return members;
262     }
263 
264     /**
265      * {@inheritDoc}
266      *
267      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getNamespace()
268      */
269     @Override
getNamespace()270     protected String getNamespace() {
271         return getConfig().getCoherencyTestParserNamespace();
272     }
273 
274     /**
275      * {@inheritDoc}
276      *
277      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#getSourceFile()
278      */
279     @Override
getSourceFile()280     protected PrintStream getSourceFile() {
281         return sourceFile;
282     }
283 
284     /**
285      * {@inheritDoc}
286      *
287      * @see de.netallied.xsd2cppsax.printers.ICodePrinter#handleEnum(java.lang.String,
288      *      com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition)
289      */
handleEnum(String cppEnumTypeName, XSSimpleTypeDefinition simpleType)290     public void handleEnum(String cppEnumTypeName, XSSimpleTypeDefinition simpleType) {
291     }
292 
293     /**
294      * {@inheritDoc}
295      *
296      * @see de.netallied.xsd2cppsax.printers.ICodePrinter#handleUnion(java.lang.String,
297      *      com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition)
298      */
handleUnion(String cppUnionTypeName, XSSimpleTypeDefinition simpleType)299     public void handleUnion(String cppUnionTypeName, XSSimpleTypeDefinition simpleType) {
300     }
301 
302     /**
303      * Indicates if it is necessary to print simple count check of given
304      * element. That check tests if count attribute and list length are the
305      * same.
306      */
isSimpleCountCheckRequired(XSElementDeclaration element)307     protected boolean isSimpleCountCheckRequired(XSElementDeclaration element) {
308         List<XSAttributeUse> attributeUses = Util.collectAttributeUses(element);
309         boolean countAttrPresent = false;
310         for (XSAttributeUse attrUse : attributeUses) {
311             String attributeName = Util.getAttributeName(attrUse, getConfig());
312             if (attributeName.equals("count")) {
313                 countAttrPresent = true;
314                 break;
315             }
316         }
317         if (countAttrPresent) {
318             XSSimpleTypeDefinition simpleType = Util.findSimpleTypeDefinition(element.getTypeDefinition());
319             if (simpleType != null) {
320                 Variety variety = Util.findVariety(simpleType);
321                 if (variety == Variety.LIST) {
322                     return true;
323                 }
324             }
325         }
326         return false;
327     }
328 
329     /**
330      * {@inheritDoc}
331      *
332      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#printBeginMethodImpl(java.lang.String,
333      *      java.lang.String, java.lang.String,
334      *      com.sun.org.apache.xerces.internal.xs.XSElementDeclaration, boolean)
335      */
336     @Override
printBeginMethodImpl(String methodName, String parameterList, String cppElementName, XSElementDeclaration element, boolean attributesRequired)337     protected void printBeginMethodImpl(String methodName, String parameterList, String cppElementName,
338             XSElementDeclaration element, boolean attributesRequired) {
339 
340         sourceFile.println("{");
341 
342         if (attributesRequired) {
343             checkIdUnique(cppElementName, element);
344             if (isSimpleCountCheckRequired(element)) {
345                 checkCountSimpleBegin(cppElementName, element);
346             }
347         }
348 
349         sourceFile.print(getConfig().getIndentation());
350         sourceFile.println("return true;");
351         sourceFile.print("}");
352     }
353 
354     /**
355      * {@inheritDoc}
356      *
357      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#printDataMethodImpl(java.lang.String,
358      *      java.lang.String, java.lang.String,
359      *      com.sun.org.apache.xerces.internal.xs.XSElementDeclaration)
360      */
361     @Override
printDataMethodImpl(String methodName, String parameterList, String cppElementName, XSElementDeclaration element)362     protected void printDataMethodImpl(String methodName, String parameterList, String cppElementName,
363             XSElementDeclaration element) {
364 
365         sourceFile.println("{");
366 
367         if (isSimpleCountCheckRequired(element)) {
368             checkCountSimpleData(cppElementName, element);
369         }
370 
371         sourceFile.print(getConfig().getIndentation());
372         sourceFile.println("return true;");
373         sourceFile.print("}");
374     }
375 
376     /**
377      * {@inheritDoc}
378      *
379      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#printEndMethodImpl(java.lang.String,
380      *      java.lang.String, java.lang.String,
381      *      com.sun.org.apache.xerces.internal.xs.XSElementDeclaration)
382      */
383     @Override
printEndMethodImpl(String methodName, String parameterList, String cppElementName, XSElementDeclaration element)384     protected void printEndMethodImpl(String methodName, String parameterList, String cppElementName,
385             XSElementDeclaration element) {
386 
387         sourceFile.println("{");
388 
389         if (isSimpleCountCheckRequired(element)) {
390             checkCountSimpleEnd(cppElementName, element);
391         }
392 
393         sourceFile.print(getConfig().getIndentation());
394         sourceFile.println("return true;");
395         sourceFile.print("}");
396     }
397 
398     /**
399      * {@inheritDoc}
400      *
401      * @see de.netallied.xsd2cppsax.printers.AbstractParserImplementationPrinter#printHeaderFileBeginning()
402      */
403     @Override
printHeaderFileBeginning()404     public void printHeaderFileBeginning() {
405         super.printHeaderFileBeginning();
406 
407         getHeaderFile().println("typedef std::map<String, size_t> IDCounterMap;");
408         getHeaderFile().println();
409         getHeaderFile().println();
410         getHeaderFile().println();
411     }
412 
413     /**
414      * {@inheritDoc}
415      *
416      * @see de.netallied.xsd2cppsax.printers.ICodePrinter#setupOutputFiles()
417      */
setupOutputFiles()418     public void setupOutputFiles() throws FileNotFoundException {
419         headerFile = new PrintStream(getConfig().getOutputCoherencyTestHeaderFileName());
420         printHeaderFileBeginning();
421         sourceFile = new PrintStream(getConfig().getOutputCoherencyTestSourceFileName());
422         printSourceFileBeginning();
423     }
424 
425 }
426