Author: nbelaevski
Date: 2009-08-12 13:36:57 -0400 (Wed, 12 Aug 2009)
New Revision: 15161
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBodyStatement.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBodyStatementsContainer.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/BaseTagBodyConsumer.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/BaseTemplateConsumer.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/ChooseTagBodyConsumer.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/Consumer.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/RootElementConsumer.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/StructuralTagBodyConsumer.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/TemplateBodyConsumer.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/TemplateReader.java
Modified:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaClass.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaLanguageElement.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaMethod.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaPackage.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBody.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/render/JavaClassRenderer.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/render/JavaMethodRenderer.java
Log:
Templates compilation functionality draft check-in
Modified:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaClass.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaClass.java 2009-08-12
15:54:40 UTC (rev 15160)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaClass.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -44,18 +44,29 @@
});
private JavaPackage pakg;
- private Class<?> superClass = Object.class;
+ private static final JavaClass DEFAULT_SUPERCLASS = new JavaClass(Object.class);
+
+ private JavaClass superClass = DEFAULT_SUPERCLASS;
+
public JavaClass(String shortName, JavaPackage pakg, Class<?> superClass) {
this(shortName, pakg);
- setSuperClass(superClass);
+ setSuperClass(new JavaClass(superClass));
}
+ public JavaClass() {
+ super();
+ }
+
public JavaClass(String shortName, JavaPackage pakg) {
super(shortName);
this.pakg = pakg;
}
+ public JavaClass(Class<?> clazz) {
+ this(clazz.getSimpleName(), new JavaPackage(clazz.getPackage()));
+ }
+
public void addImport(String name) {
imports.add(new RuntimeImport(name));
}
@@ -88,9 +99,9 @@
methods.add(method);
addImport(method.getReturnType());
- List<Class<Throwable>> exceptions = method.getExceptions();
+ List<Class<? extends Throwable>> exceptions = method.getExceptions();
- for (Class<Throwable> exception : exceptions) {
+ for (Class<? extends Throwable> exception : exceptions) {
addImport(exception);
}
@@ -123,14 +134,16 @@
public JavaPackage getPakg() {
return pakg;
}
- public Class<?> getSuperClass() {
+
+ public JavaClass getSuperClass() {
return superClass;
}
- public void setSuperClass(Class<?> superClass) {
+ public void setSuperClass(JavaClass superClass) {
this.superClass = superClass;
- addImport(superClass);
+ addImport(superClass.getFullName());
}
+
public void setPackage(JavaPackage s) {
pakg = s;
}
@@ -148,19 +161,31 @@
return imports;
}
+ public String getFullName() {
+ StringBuilder fullName = new StringBuilder();
+ fullName.append(getPackage().getName());
+ if (fullName.length() != 0) {
+ fullName.append('.');
+ fullName.append(getName());
+ }
+
+ return fullName.toString();
+ }
+
+ //FIXME: remodel this method so that it imports set is aligned when rendering
private boolean shouldAddToImports(Class<?> clas) {
boolean result = false;
if (clas != null) {
Package p = clas.getPackage();
+ JavaPackage jp = getPackage();
if (!(clas.isPrimitive() || p == null)) {
String importPackageName = p.getName();
if (importPackageName != null && importPackageName.length() != 0) {
- result = !(importPackageName.equals("java.lang") || importPackageName
- .equals(getPackage().getName()));
+ result = !(importPackageName.equals("java.lang") || (jp != null &&
importPackageName.equals(jp.getName())));
}
}
}
Modified:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaLanguageElement.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaLanguageElement.java 2009-08-12
15:54:40 UTC (rev 15160)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaLanguageElement.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -37,6 +37,10 @@
private List<JavaComment> comments = new ArrayList<JavaComment>();
private String name;
+ public JavaLanguageElement() {
+ super();
+ }
+
public JavaLanguageElement(String name) {
super();
this.name = name;
@@ -58,6 +62,10 @@
return name;
}
+ public void setName(String name) {
+ this.name = name;
+ }
+
public void addModifier(JavaModifier modifier) {
modifiers.add(modifier);
}
Modified:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaMethod.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaMethod.java 2009-08-12
15:54:40 UTC (rev 15160)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaMethod.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -36,13 +36,13 @@
private MethodBody methodBody;
private List <Argument> arguments = new ArrayList<Argument>();
- private List<Class<Throwable>> exceptions = new
ArrayList<Class<Throwable>>();
+ private List<Class<? extends Throwable>> exceptions = new
ArrayList<Class<? extends Throwable>>();
- public List<Class<Throwable>> getExceptions() {
+ public List<Class<? extends Throwable>> getExceptions() {
return exceptions;
}
- public void setExceptions(List<Class<Throwable>> exceptions) {
+ public void setExceptions(List<Class<? extends Throwable>> exceptions) {
this.exceptions = exceptions;
}
Modified:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaPackage.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaPackage.java 2009-08-12
15:54:40 UTC (rev 15160)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaPackage.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -36,6 +36,10 @@
super();
this.name = name;
}
+
+ public JavaPackage(Package pkg) {
+ this(pkg.getName());
+ }
}
Modified:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBody.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBody.java 2009-08-12
15:54:40 UTC (rev 15160)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBody.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -21,19 +21,23 @@
package org.richfaces.builder.model;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
/**
* @author Maksim Kaszynski
*
*/
-public class MethodBody {
+public class MethodBody implements MethodBodyStatementsContainer {
private JavaMethod method;
private Set<Class<?>> usedClasses = new HashSet<Class<?>>();
+ private List<MethodBodyStatement> body = new
ArrayList<MethodBodyStatement>();
+
public MethodBody() {
// TODO Auto-generated constructor stub
}
@@ -51,8 +55,20 @@
}
public String toCode() {
- return "";
+ StringBuilder builder = new StringBuilder();
+
+ for (MethodBodyStatement statement : body) {
+ statement.appendTo(builder);
+ }
+
+ return builder.toString();
}
+
+ public void addToBody(MethodBodyStatement... argStatements) {
+ for (MethodBodyStatement methodBodyStatement : argStatements) {
+ body.add(methodBodyStatement);
+ }
+ }
public void addType(Class<?> clazz) {
usedClasses.add(clazz);
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBodyStatement.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBodyStatement.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBodyStatement.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -0,0 +1,78 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.builder.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class MethodBodyStatement implements MethodBodyStatementsContainer {
+
+ private List<MethodBodyStatement> statements = new
ArrayList<MethodBodyStatement>();
+
+ private String start = null;
+
+ private String end = null;
+
+ public MethodBodyStatement() {
+ this(null);
+ }
+
+ public MethodBodyStatement(String expression) {
+ this(expression, null);
+ }
+
+ public MethodBodyStatement(String start, String end) {
+ super();
+ this.start = start;
+ this.end = end;
+ }
+
+ /**
+ * @param builder
+ */
+ public void appendTo(StringBuilder builder) {
+ if (start != null) {
+ builder.append(start);
+ builder.append('\n');
+ }
+
+ for (MethodBodyStatement statement : statements) {
+ statement.appendTo(builder);
+ builder.append('\n');
+ }
+
+ if (end != null) {
+ builder.append(end);
+ builder.append('\n');
+ }
+ }
+
+ public void addToBody(MethodBodyStatement... argStatements) {
+ for (MethodBodyStatement methodBodyStatement : argStatements) {
+ statements.add(methodBodyStatement);
+ }
+ }
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBodyStatementsContainer.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBodyStatementsContainer.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/MethodBodyStatementsContainer.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -0,0 +1,31 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.builder.model;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface MethodBodyStatementsContainer {
+
+ public void addToBody(MethodBodyStatement... s);
+}
Modified:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/render/JavaClassRenderer.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/render/JavaClassRenderer.java 2009-08-12
15:54:40 UTC (rev 15160)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/render/JavaClassRenderer.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -62,11 +62,11 @@
renderModifiers(javaClass, out);
out.print("class " + javaClass.getName() );
- Class<?> superClass =
+ JavaClass superClass =
javaClass.getSuperClass();
if (!Object.class.getName().equals(superClass.getName())) {
- out.print(" extends " + superClass.getSimpleName());
+ out.print(" extends " + superClass.getName() + " ");
}
out.println("{");
Modified:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/render/JavaMethodRenderer.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/render/JavaMethodRenderer.java 2009-08-12
15:54:40 UTC (rev 15160)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/render/JavaMethodRenderer.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -63,12 +63,12 @@
}
}
out.print(")");
- List<Class<Throwable>> exceptions = javaMethod.getExceptions();
+ List<Class<? extends Throwable>> exceptions = javaMethod.getExceptions();
if (exceptions != null && !exceptions.isEmpty()) {
out.print(" throws ");
- for (Iterator<Class<Throwable>> iterator = exceptions.iterator();
iterator.hasNext();) {
- Class<Throwable> class1 = iterator.next();
+ for (Iterator<Class<? extends Throwable>> iterator =
exceptions.iterator(); iterator.hasNext();) {
+ Class<? extends Throwable> class1 = iterator.next();
out.print(class1.getSimpleName());
if (iterator.hasNext()) {
out.print(", ");
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/BaseTagBodyConsumer.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/BaseTagBodyConsumer.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/BaseTagBodyConsumer.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -0,0 +1,73 @@
+package org.richfaces.builder.templates;
+import javax.xml.namespace.QName;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+
+import org.richfaces.builder.model.MethodBodyStatement;
+
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class BaseTagBodyConsumer extends BaseTemplateConsumer {
+
+ protected final MethodBodyStatement statement;
+
+ public BaseTagBodyConsumer(MethodBodyStatement methodBodyStatement) {
+ super();
+
+ this.statement = methodBodyStatement;
+ }
+
+ @Override
+ public void consumeEndElement(EndElement endElement) {
+ QName name = endElement.getName();
+
+ if (!isCdkNamespace(name)) {
+ statement.addToBody(createEndElement(endElement));
+ }
+ }
+
+ @Override
+ public Consumer consumeStartElement(StartElement startElement) {
+ QName name = startElement.getName();
+ if (isCdkNamespace(name)) {
+ if ("if".equals(name.getLocalPart())) {
+ MethodBodyStatement ifStatement = createIfExpression(startElement);
+
+ statement.addToBody(ifStatement);
+ return new BaseTagBodyConsumer(ifStatement);
+ } else if ("choose".equals(name.getLocalPart())) {
+ MethodBodyStatement whenStatement = new MethodBodyStatement();
+ statement.addToBody(whenStatement);
+ return new ChooseTagBodyConsumer(whenStatement);
+ }
+
+ } else {
+ statement.addToBody(createStartElement(startElement));
+ }
+
+ return this;
+ }
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/BaseTemplateConsumer.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/BaseTemplateConsumer.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/BaseTemplateConsumer.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -0,0 +1,266 @@
+package org.richfaces.builder.templates;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.text.MessageFormat;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+
+import org.richfaces.builder.model.MethodBodyStatement;
+
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class BaseTemplateConsumer implements Consumer {
+
+ private static final String XHTML_NAMESPACE =
"http://richfaces.org/xhtml-el";
+
+ private static final String CDK_NAMESPACE = "http://richfaces.org/cdk";
+
+ private static final Map<String, Set<String>> elementsAttributes;
+
+ private static final Pattern EL_EXPRESSION =
Pattern.compile("#\\{([^\\}]+)\\}");
+
+ private static final Pattern COMPONENT_ATTRIBUTES_EXPRESSION =
Pattern.compile("^component\\.attributes\\[(?:'|\")?([^'\"]+)(?:'|\")?\\]$");
+
+ static {
+ InputStream serializedAttributesStream =
BaseTemplateConsumer.class.getResourceAsStream("/attributes.ser");
+ try {
+ //TODO read default attributes values
+ //TODO detect URI attributes
+ ObjectInputStream ois = new ObjectInputStream(serializedAttributesStream);
+ elementsAttributes = (Map<String, Set<String>>) ois.readObject();
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ } finally {
+ try {
+ serializedAttributesStream.close();
+ } catch (IOException e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see Consumer#consumeCharacters(javax.xml.stream.events.Characters)
+ */
+ @Override
+ public void consumeCharacters(Characters characters) {
+ }
+
+ /* (non-Javadoc)
+ * @see Consumer#consumeEndElement(javax.xml.stream.events.EndElement)
+ */
+ @Override
+ public void consumeEndElement(EndElement endElement) {
+ }
+
+ /* (non-Javadoc)
+ * @see Consumer#consumeStartElement(javax.xml.stream.events.StartElement)
+ */
+ @Override
+ public Consumer consumeStartElement(StartElement startElement) {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see Consumer#enter()
+ */
+ @Override
+ public void enter() {
+ }
+
+ /* (non-Javadoc)
+ * @see Consumer#exit()
+ */
+ @Override
+ public void exit() {
+ }
+
+ protected boolean isDefaultNamespace(QName name) {
+ return name.getNamespaceURI().length() == 0;
+ }
+
+ protected boolean isXhtmlNamespace(QName name) {
+ return XHTML_NAMESPACE.equals(name.getNamespaceURI());
+ }
+
+ protected boolean isCdkNamespace(QName name) {
+ return CDK_NAMESPACE.equals(name.getNamespaceURI());
+ }
+
+ private String quote(String s) {
+ return '\"' + s.replaceAll("\"", "\\\\\"") +
'\"';
+ }
+
+ protected String elExpressionToJava(String elExpression) {
+ if ("clientId".equalsIgnoreCase(elExpression)) {
+ return "component.getClientId(facesContext)";
+ } else {
+ Matcher matcher = COMPONENT_ATTRIBUTES_EXPRESSION.matcher(elExpression);
+ if (matcher.matches()) {
+ String componentAttributeName = matcher.group(1);
+ return
MessageFormat.format("component.getAttributes().get(\"{0}\")",
componentAttributeName);
+ }
+ }
+
+ return elExpression;
+ }
+
+ protected String compileEl(String elString) {
+ Matcher matcher = EL_EXPRESSION.matcher(elString);
+ StringBuffer buffer = new StringBuffer();
+
+ int start = 0;
+ int elStart;
+ while (matcher.find(start)) {
+ elStart = matcher.start();
+
+ if (elStart != start) {
+ if (buffer.length() != 0) {
+ buffer.append(" + ");
+ }
+ buffer.append(quote(elString.substring(start, elStart)));
+ }
+
+ String elExpression = matcher.group(1);
+ if (buffer.length() != 0) {
+ buffer.append(" + ");
+ }
+ buffer.append(elExpressionToJava(elExpression));
+
+
+ start = matcher.end();
+ }
+
+ if (start != elString.length()) {
+ if (buffer.length() != 0) {
+ buffer.append(" + ");
+ }
+ buffer.append(quote(elString.substring(start)));
+ }
+ return buffer.toString();
+ }
+
+ protected MethodBodyStatement createStartElement(StartElement startElement) {
+ MethodBodyStatement rootStatement = new MethodBodyStatement();
+ String elementName = startElement.getName().getLocalPart();
+ rootStatement.addToBody(new MethodBodyStatement(
+ MessageFormat.format("responseWriter.startElement(\"{0}\",
component);",
+ elementName)));
+
+ Map<String, String> attributes = new LinkedHashMap<String, String>();
+ boolean usePassThrough = false;
+ Set<String> passThroughSkip = new HashSet<String>();
+
+ Iterator<Attribute> attributesItr = startElement.getAttributes();
+ while (attributesItr.hasNext()) {
+ Attribute attribute = attributesItr.next();
+ QName attributeName = attribute.getName();
+ String value = attribute.getValue();
+
+ if (isXhtmlNamespace(attributeName) || isDefaultNamespace(attributeName)) {
+ attributes.put(attributeName.getLocalPart(), value);
+ } else if (isCdkNamespace(attributeName)) {
+ if ("passThroughWithExclusions".equals(attributeName.getLocalPart())) {
+ usePassThrough = true;
+ if (!"#none".equals(value)) {
+ String[] split = value.split(",");
+ for (String s : split) {
+ passThroughSkip.add(s.trim());
+ }
+ }
+ } else {
+ throw new IllegalArgumentException(attributeName.toString());
+ }
+ } else {
+ throw new IllegalArgumentException(attributeName.toString());
+ }
+ }
+
+ if (usePassThrough) {
+ Set<String> schemaAttributes = elementsAttributes.get(elementName);
+ if (schemaAttributes != null) {
+ for (String schemaAttribute : schemaAttributes) {
+ if (passThroughSkip.contains(schemaAttribute)) {
+ continue;
+ }
+
+ if (attributes.containsKey(schemaAttribute)) {
+ continue;
+ }
+
+ attributes.put(schemaAttribute,
+ MessageFormat.format("#'{'component.attributes[{0}]'}'",
schemaAttribute));
+ }
+ }
+ }
+
+ for (Entry<String, String> attributeEntry : attributes.entrySet()) {
+ //TODO add check for default values
+ rootStatement.addToBody(new MethodBodyStatement(
+ MessageFormat.format("responseWriter.writeAttribute(\"{0}\", {1},
\"{0}\");",
+ attributeEntry.getKey(), compileEl(attributeEntry.getValue()))));
+ }
+
+ return rootStatement;
+ }
+
+ protected MethodBodyStatement createEndElement(EndElement startElement) {
+ String elementName = startElement.getName().getLocalPart();
+ return new
MethodBodyStatement(MessageFormat.format("responseWriter.endElement(\"{0}\");",
elementName));
+ }
+
+ protected MethodBodyStatement createWriteText(Characters characters) {
+ return new MethodBodyStatement(MessageFormat.format("responseWriter.writeText({0},
component, null);",
+ compileEl(characters.getData().trim())));
+ }
+
+ protected MethodBodyStatement createIfExpression(StartElement element) {
+ Attribute testAttribute = element.getAttributeByName(new QName("test"));
+ String testExpression = compileEl(testAttribute.getValue());
+ return new MethodBodyStatement(
+ MessageFormat.format("if ({0}) '{'", testExpression),
"}");
+ }
+
+ protected MethodBodyStatement createIfElseExpression(StartElement element) {
+ Attribute testAttribute = element.getAttributeByName(new QName("test"));
+ String testExpression = compileEl(testAttribute.getValue());
+ return new MethodBodyStatement(
+ MessageFormat.format("else if ({0}) '{'", testExpression),
"}");
+ }
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/ChooseTagBodyConsumer.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/ChooseTagBodyConsumer.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/ChooseTagBodyConsumer.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -0,0 +1,77 @@
+package org.richfaces.builder.templates;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.events.StartElement;
+
+import org.richfaces.builder.model.MethodBodyStatement;
+
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class ChooseTagBodyConsumer extends BaseTagBodyConsumer {
+
+ private List<MethodBodyStatement> statements = new
ArrayList<MethodBodyStatement>();
+
+ public ChooseTagBodyConsumer(MethodBodyStatement methodBodyStatement) {
+ super(methodBodyStatement);
+ }
+
+ /* (non-Javadoc)
+ * @see BaseTagBodyConsumer#consumeStartElement(javax.xml.stream.events.StartElement)
+ */
+ @Override
+ public Consumer consumeStartElement(StartElement startElement) {
+ QName name = startElement.getName();
+ if (isCdkNamespace(name)) {
+ MethodBodyStatement bodyStatement;
+
+ if (statements.isEmpty()) {
+ if ("when".equals(name.getLocalPart())) {
+ bodyStatement = createIfExpression(startElement);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ } else {
+ if ("when".equals(name.getLocalPart())) {
+ bodyStatement = createIfElseExpression(startElement);
+ } else if ("otherwise".equals(name.getLocalPart())) {
+ bodyStatement = new MethodBodyStatement("else {", "}");
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ statement.addToBody(bodyStatement);
+
+ statements.add(bodyStatement);
+ return new BaseTagBodyConsumer(bodyStatement);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/Consumer.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/Consumer.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/Consumer.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -0,0 +1,43 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.richfaces.builder.templates;
+
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface Consumer {
+
+ public void enter();
+
+ public void exit();
+
+ public Consumer consumeStartElement(StartElement startElement);
+
+ public void consumeEndElement(EndElement endElement);
+
+ public void consumeCharacters(Characters characters);
+
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/RootElementConsumer.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/RootElementConsumer.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/RootElementConsumer.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -0,0 +1,110 @@
+package org.richfaces.builder.templates;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
+import javax.xml.namespace.QName;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+
+import org.richfaces.builder.model.JavaClass;
+import org.richfaces.builder.model.JavaModifier;
+import org.richfaces.builder.model.JavaPackage;
+
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class RootElementConsumer extends BaseTemplateConsumer {
+
+ private JavaClass javaClass;
+
+ public JavaClass getJavaClass() {
+ return javaClass;
+ }
+
+ private String getAttributeValue(StartElement element, String attributeName) {
+ Attribute attribute = element.getAttributeByName(new QName(attributeName));
+ if (attribute != null) {
+ String attributeValue = attribute.getValue();
+ if (attributeValue != null && attributeValue.length() != 0) {
+ return attributeValue;
+ }
+ }
+
+ return null;
+ }
+
+ private JavaClass createJavaClassByName(String fullName) {
+ String simpleName = null;
+ String packageName = "";
+
+ int lastDotIdx = fullName.lastIndexOf('.');
+
+ if (lastDotIdx != -1) {
+ simpleName = fullName.substring(lastDotIdx + 1);
+ packageName = fullName.substring(0, lastDotIdx);
+ } else {
+ simpleName = fullName;
+ }
+
+ return new JavaClass(simpleName, new JavaPackage(packageName));
+ }
+
+ @Override
+ public Consumer consumeStartElement(StartElement startElement) {
+ QName name = startElement.getName();
+ if (isCdkNamespace(name) && "root".equals(name.getLocalPart())) {
+ javaClass = new JavaClass();
+ javaClass.getModifiers().add(JavaModifier.PUBLIC);
+
+ javaClass.addImport(ResponseWriter.class);
+ javaClass.addImport(FacesContext.class);
+ javaClass.addImport(UIComponent.class);
+ javaClass.addImport(Renderer.class);
+
+ String className = getAttributeValue(startElement, "class");
+ if (className != null) {
+ javaClass.setName(className);
+ }
+
+ String superClassName = getAttributeValue(startElement, "superclass");
+ if (superClassName != null) {
+ javaClass.setSuperClass(createJavaClassByName(superClassName));
+ } else {
+ javaClass.setSuperClass(new JavaClass(Renderer.class));
+ }
+
+ String packageName = getAttributeValue(startElement, "package");
+ if (packageName != null) {
+ javaClass.setPackage(new JavaPackage(packageName));
+ }
+
+ return new TemplateBodyConsumer(javaClass);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/StructuralTagBodyConsumer.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/StructuralTagBodyConsumer.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/StructuralTagBodyConsumer.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -0,0 +1,75 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.richfaces.builder.templates;
+import javax.xml.namespace.QName;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+
+import org.richfaces.builder.model.MethodBodyStatement;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class StructuralTagBodyConsumer extends BaseTemplateConsumer {
+
+ private MethodBodyStatement statement;
+
+ public StructuralTagBodyConsumer(MethodBodyStatement methodBodyStatement) {
+ super();
+
+ this.statement = methodBodyStatement;
+ }
+
+ @Override
+ public void consumeCharacters(Characters characters) {
+ String trimmedText = characters.getData().trim();
+
+ if (trimmedText.length() != 0) {
+ statement.addToBody(createWriteText(characters));
+ }
+ }
+
+ @Override
+ public void consumeEndElement(EndElement endElement) {
+ QName name = endElement.getName();
+
+ if (isCdkNamespace(name) && name.getLocalPart().equals("body")) {
+ throw new IllegalArgumentException();
+ } else {
+ statement.addToBody(createEndElement(endElement));
+ }
+ }
+
+ @Override
+ public Consumer consumeStartElement(StartElement startElement) {
+ QName name = startElement.getName();
+ if (isCdkNamespace(name) && name.getLocalPart().equals("body")) {
+ throw new IllegalArgumentException();
+ } else {
+ statement.addToBody(createStartElement(startElement));
+ }
+
+ return this;
+ }
+
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/TemplateBodyConsumer.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/TemplateBodyConsumer.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/TemplateBodyConsumer.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -0,0 +1,128 @@
+package org.richfaces.builder.templates;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+
+import org.richfaces.builder.model.Argument;
+import org.richfaces.builder.model.JavaClass;
+import org.richfaces.builder.model.JavaMethod;
+import org.richfaces.builder.model.JavaModifier;
+import org.richfaces.builder.model.MethodBody;
+import org.richfaces.builder.model.MethodBodyStatement;
+
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class TemplateBodyConsumer extends BaseTemplateConsumer {
+
+ private JavaClass javaClass;
+
+ private List<MethodBodyStatement> statements = new
ArrayList<MethodBodyStatement>();
+
+ public TemplateBodyConsumer(JavaClass javaClass) {
+ super();
+
+ this.javaClass = javaClass;
+ }
+
+ @Override
+ public void consumeCharacters(Characters characters) {
+ String trimmedText = characters.getData().trim();
+
+ if (trimmedText.length() != 0) {
+ statements.add(createWriteText(characters));
+ }
+ }
+
+ @Override
+ public void consumeEndElement(EndElement endElement) {
+ QName name = endElement.getName();
+
+ if (isCdkNamespace(name)) {
+ if (name.getLocalPart().equals("body")) {
+ flushStatements("encodeChildren");
+ }
+ } else {
+ statements.add(createEndElement(endElement));
+ }
+ }
+
+ private void flushStatements(String methodName) {
+ JavaMethod javaMethod = new JavaMethod(methodName, new
Argument("facesContext", FacesContext.class),
+ new Argument("component", UIComponent.class));
+
+ javaMethod.getModifiers().add(JavaModifier.PUBLIC);
+ javaMethod.getExceptions().add(IOException.class);
+ MethodBody methodBody = new MethodBody(javaMethod);
+ javaMethod.setMethodBody(methodBody);
+
+ methodBody.addToBody(
+ new MethodBodyStatement("ResponseWriter responseWriter =
facesContext.getResponseWriter();"));
+
+ for (MethodBodyStatement methodBodyStatement : statements) {
+ methodBody.addToBody(methodBodyStatement);
+ }
+ statements.clear();
+
+ javaClass.addMethod(javaMethod);
+ }
+
+ @Override
+ public Consumer consumeStartElement(StartElement startElement) {
+ QName name = startElement.getName();
+ if (isCdkNamespace(name)) {
+ if ("body".equals(name.getLocalPart())) {
+ flushStatements("encodeBegin");
+ } else if ("if".equals(name.getLocalPart())) {
+ MethodBodyStatement ifStatement = createIfExpression(startElement);
+ statements.add(ifStatement);
+ return new StructuralTagBodyConsumer(ifStatement);
+ } else if ("choose".equals(name.getLocalPart())) {
+ MethodBodyStatement chooseStatement = new MethodBodyStatement();
+ statements.add(chooseStatement);
+ return new ChooseTagBodyConsumer(chooseStatement);
+ }
+ } else {
+ statements.add(createStartElement(startElement));
+ }
+
+ return this;
+ }
+
+ @Override
+ public void exit() {
+ super.exit();
+
+ flushStatements("encodeEnd");
+ }
+
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/TemplateReader.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/TemplateReader.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/templates/TemplateReader.java 2009-08-12
17:36:57 UTC (rev 15161)
@@ -0,0 +1,156 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.builder.templates;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+import org.richfaces.builder.model.JavaClass;
+import org.richfaces.builder.render.JavaClassRenderer;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class TemplateReader {
+
+ private static final class ConsumersTracker {
+
+ private final class ConsumerEntry {
+
+ public ConsumerEntry(Consumer consumer) {
+ this.consumer = consumer;
+ }
+
+ private Consumer consumer;
+
+ private int depth = 0;
+
+ public void increaseDepth() {
+ depth++;
+ }
+
+ public void decreaseDepth() {
+ depth--;
+ }
+
+ public boolean isZeroDepth() {
+ return depth == 0;
+ }
+ }
+
+ private Deque<ConsumerEntry> consumerEntries = new
ArrayDeque<ConsumerEntry>();
+
+ private ConsumerEntry consumerEntry = null;
+
+ public void pushConsumer(Consumer consumer) {
+ if (consumerEntry != null && consumer == consumerEntry.consumer) {
+ consumerEntry.increaseDepth();
+ } else {
+ if (consumerEntry != null) {
+ consumerEntries.push(consumerEntry);
+ }
+
+ consumerEntry = new ConsumerEntry(consumer);
+ consumer.enter();
+ }
+ }
+
+ public Consumer peekConsumer() {
+ return consumerEntry.consumer;
+ }
+
+ public Consumer popConsumer() {
+ if (consumerEntry.isZeroDepth()) {
+ consumerEntry.consumer.exit();
+ if (!consumerEntries.isEmpty()) {
+ consumerEntry = consumerEntries.pop();
+ } else {
+ consumerEntry = null;
+ }
+ } else {
+ consumerEntry.decreaseDepth();
+ }
+
+ if (consumerEntry != null) {
+ return consumerEntry.consumer;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private static class XMLInputFactoryHolder {
+ static final XMLInputFactory factory = XMLInputFactory.newInstance();
+
+ static {
+ factory.setProperty("javax.xml.stream.isNamespaceAware", Boolean.TRUE);
+ factory.setProperty("javax.xml.stream.isCoalescing", Boolean.TRUE);
+ }
+ }
+
+ public static JavaClass parse(InputStream stream) throws XMLStreamException {
+ XMLEventReader xmlEventReader =
XMLInputFactoryHolder.factory.createXMLEventReader(stream);
+
+ ConsumersTracker tracker = new ConsumersTracker();
+ RootElementConsumer consumer = new RootElementConsumer();
+ tracker.pushConsumer(consumer);
+
+ while (xmlEventReader.hasNext()) {
+ XMLEvent event = xmlEventReader.nextEvent();
+
+ if (event.isStartElement()) {
+ StartElement startElement = event.asStartElement();
+ Consumer currentConsumer = tracker.peekConsumer();
+ Consumer nextConsumer = currentConsumer.consumeStartElement(startElement);
+
+ tracker.pushConsumer(nextConsumer);
+ } else if (event.isEndElement()) {
+ EndElement endElement = event.asEndElement();
+ Consumer currentConsumer = tracker.popConsumer();
+ currentConsumer.consumeEndElement(endElement);
+ } else if (event.isCharacters()) {
+ Characters characters = event.asCharacters();
+ tracker.peekConsumer().consumeCharacters(characters);
+ }
+ }
+
+ tracker.popConsumer();
+
+ JavaClass javaClass = consumer.getJavaClass();
+ return javaClass;
+ }
+
+ public static void main(String[] args) throws Exception {
+ JavaClass javaClass =
TemplateReader.parse(TemplateReader.class.getResourceAsStream("/test.xml"));
+ new JavaClassRenderer().render(javaClass, new PrintWriter(System.out));
+ }
+}