1 /* $Id: FlattenerHelper.java 1 2010-02-24 13:03:05Z haidw $ */
2 package dol.helper.flattener;
6 import org.jdom.Document;
7 import org.jdom.Element;
9 import dol.datamodel.XmlTag;
12 * Helper class to generate the source code of a class for writing
13 * an XML file based on an XML file with iterators. For details, refer
14 * to removeIterators().
16 * @see #removeIterators(org.jdom.Document doc)
18 public class FlattenerHelper {
20 protected String _preamble = "public class Generator {\n\n public "
21 + "Generator() {\n //nothing to be done here\n }\n"
22 + "\n public static void main(String[] args) {\n";
25 //true, when an element is generated. places a restriction on the append
26 //element, namely that it must be a single variable, no function of a
28 protected boolean _generateElement = false;
30 protected String _indent = ""; //indentation of lines in Generator class
32 //code for obtaining range of iterator variables. is updated in each
33 //call of generateAppend
34 protected String _iteratorRangeCode = "";
36 //indentation of XML elements (use increaseXmlIndent() and
37 //decreaseXmlIndent() to change the indentation)
38 protected String _xmlIndent = "";
41 * Default constructor. The generated class will have the name
44 public FlattenerHelper() {
50 * @param classname class name of the generated class
52 public FlattenerHelper(String classname) {
53 _preamble = _preamble.replace("Generator", classname);
56 public String processElement(Element element) {
61 * Generate source code for println statement that prints out an XML
63 * @param element the XML element itself
64 * @param attributes attributes to include in the XML element
65 * @param standalone true, when element shall be closed. false, otherwise
66 * @return println statement which prints out the XML element
68 protected String generateElement(Element element,
69 String[] attributes, boolean standalone)
71 String sourceCode = _indent + "System.out.println(\"";
72 sourceCode += _xmlIndent + "<" + element.getName();
73 for (int i = 0; i < attributes.length; i++) {
75 if (attributes[i].equals("basename")) {
76 sourceCode += " " + attributes[i] + "=\\\"";
77 sourceCode += element.getAttributeValue("name");
79 if (!generateAppend(element).equals("")) {
81 sourceCode += " range=\\\"" + _iteratorRangeCode;
84 } else if (attributes[i].equals("name")) {
85 sourceCode += " " + attributes[i] + "=\\\"";
86 sourceCode += element.getAttributeValue("name");
87 sourceCode += generateAppend(element);
89 } else if (attributes[i].equals("size")
90 && element.getName().equals(_xt.getSWChannelTag())) {
91 sourceCode += " " + attributes[i] + "=\\\"";
92 sourceCode += "\" + ";
93 sourceCode += element.getAttributeValue("size");
96 } else if (attributes[i].equals("tokensize")
97 && element.getName().equals(_xt.getSWChannelTag())) {
98 if (element.getAttributeValue("tokensize") != null) {
99 sourceCode += " " + attributes[i] + "=\\\"";
102 sourceCode += element.getAttributeValue("tokensize");
103 sourceCode += "+ \"";
104 sourceCode += "\\\"";
107 sourceCode += " " + attributes[i] + "=\\\"";
108 sourceCode += element.getAttributeValue(attributes[i]);
109 sourceCode += "\\\"";
116 sourceCode +=">\");\n";
124 @SuppressWarnings("unchecked")
125 public String removeIterators(Document doc)
126 throws RuntimeException {
127 String sourceCode = _preamble;
128 String functionString = "";
129 String rootName = "";
132 Element root = doc.getRootElement();
133 String xmlns = root.getNamespaceURI();
134 String xsiLocation = "";
135 for (org.jdom.Attribute attr :
136 (List<org.jdom.Attribute>)root.getAttributes()) {
137 //System.out.println(attr.getName() + ": ");
138 //System.out.println(attr.getValue());
139 if (attr.getName().equals("schemaLocation"))
140 xsiLocation = attr.getValue();
143 if (!root.getChildren().isEmpty()) {
144 //if there are any elements in the document, create a new header
145 //for the xml document
146 rootName = root.getName();
148 sourceCode += _indent
149 + "java.util.Hashtable<String, Integer> table = "
150 + "new java.util.Hashtable<String, Integer>();\n";
152 sourceCode += _indent + "System.out.println(\""
153 + "<?xml version=\\\"1.0\\\" "
154 + "encoding=\\\"UTF-8\\\"?>\");\n";
155 sourceCode += _indent + "System.out.println(\"<"
156 + rootName + " xmlns=\\\"" + xmlns
157 + "\\\" xmlns:xsi=\\\"http://www.w3.org/2001/"
158 + "XMLSchema-instance\\\" \\n xsi:schemaLocation=\\\""
159 + xsiLocation + "\\\" name=\\\""
160 + root.getAttributeValue("name") + "_flattened"
165 for (Element elmt : (List<Element>)root.getChildren()) {
167 if (elmt.getName().equalsIgnoreCase(_xt.getIteratorTag())) {
168 sourceCode += generateIterator(elmt);
170 else if (elmt.getName().equalsIgnoreCase(_xt.getVariableTag())) {
171 sourceCode += generateVariable(elmt);
173 else if (elmt.getName().equalsIgnoreCase(_xt.getFunctionTag())) {
174 functionString += generateFunction(elmt);
177 sourceCode += processElement(elmt);
180 catch (RuntimeException e) {
181 String elementName = "";
182 System.out.println(e.getMessage());
183 if (!elmt.getName().equalsIgnoreCase(_xt.getIteratorTag()) &&
184 !elmt.getName().equalsIgnoreCase(_xt.getVariableTag())) {
185 elementName = elmt.getAttributeValue("name");
187 throw new RuntimeException(
188 "Error: An error occurred while parsing the <"
189 + elmt.getName() + "> element \""
190 + elementName + "\".");
194 sourceCode += _indent + "System.out.println(\"</"
195 + rootName +">\");\n }\n";
197 sourceCode += functionString;
207 @SuppressWarnings("unchecked")
208 protected String generateIterator(Element element) {
209 String variableName = element.getAttributeValue("variable");
211 //extract the upper iteration boundary and construct the for loop
212 String forLoop = element.getAttributeValue("range");
213 String boundary = forLoop.replaceAll(
214 "for.*;[ ]*\\w*[ ]*[<>=]* *(.*);.*", "$1");
216 String forLoop = "for (int " + variableName + " = 0; " + variableName
217 + " < " + element.getAttributeValue("range") + "; "
218 + variableName + "++)";
220 String sourceCode = _indent + "table.put(\"" + variableName
221 + "\", " + element.getAttributeValue("range") + ");\n";
223 sourceCode += _indent + forLoop + " {\n";
226 for (Element el : (List<Element>)element.getChildren()) {
228 if (el.getName().equalsIgnoreCase(_xt.getIteratorTag())) {
229 sourceCode += generateIterator(el);
232 sourceCode += processElement(el);
235 catch (RuntimeException e) {
236 System.out.println(e.getMessage());
237 throw new RuntimeException(
238 "Error: An error occurred while parsing the <"
239 + el.getName() + "> element \""
240 + el.getAttributeValue("name") + "\".");
243 _indent = _indent.substring(0, _indent.length() - 2);
244 sourceCode += _indent + "}\n";
245 sourceCode += _indent + "table.remove(\"" + variableName + "\");\n";
253 @SuppressWarnings("unchecked")
254 protected String generateAppend(Element element)
255 throws RuntimeException {
256 String sourceCode = "";
258 _iteratorRangeCode = "";
259 for (Element childElement : (List<Element>)element.getChildren()) {
260 if (childElement.getName().equalsIgnoreCase("append")) {
261 if (_generateElement &&
262 !childElement.getAttributeValue(_xt.getFunctionTag()).replaceAll(
263 "\\w", "").equals("")) {
264 throw new RuntimeException("Error: Found \""
265 + childElement.getAttributeValue("function")
266 + "\" in <append>. When constructing elements with an "
267 + "iterator using <append function=\"xxx\">, xxx must "
268 + "be a single variable. No mathematical operations "
271 sourceCode += "\" + \"_\" + ("
272 + childElement.getAttributeValue(_xt.getFunctionTag())
275 if (!_iteratorRangeCode.equals(""))
276 _iteratorRangeCode += ";";
278 _iteratorRangeCode += "\" + table.get(\""
279 + childElement.getAttributeValue(_xt.getFunctionTag())
286 protected String generateVariable(Element element) {
287 String sourceCode = _indent + "int ";
288 sourceCode += element.getAttributeValue("name");
290 sourceCode += element.getAttributeValue("value");
295 protected String generateFunction(Element element) {
296 return element.getText();
300 * Increase the XML indentation.
302 protected void increaseXmlIndent() {
307 * Decrease the XML indentation.
309 protected void decreaseXmlIndent() {
310 _xmlIndent = _xmlIndent.substring(0, _xmlIndent.length() - 2);
313 protected XmlTag _xt = XmlTag.getInstance();