package org.anodyneos.xpImpl.translater;
import java.util.Enumeration;
import java.util.List;
import org.anodyneos.commons.xml.sax.ElementProcessor;
import org.anodyneos.xp.tagext.FunctionInfo;
import org.anodyneos.xp.tagext.TagLibraryRegistry;
import org.anodyneos.xpImpl.util.CodeWriter;
import org.anodyneos.xpImpl.util.FunctionUtil;
import org.anodyneos.xpImpl.util.JavaClass;
import org.anodyneos.xpImpl.util.Util;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
/**
* ProcessorPage handles the xp:page element.
*
* <pre>
* <xp:page>
* <xp:output/>
* <xp:xsl/>...
* <xp:content/>
* </xp:page>
* </pre>
*
* @author jvas
*/
class ProcessorPage extends TranslaterProcessor {
private JavaClass jc = new JavaClass();
//private ArrayList xmlPiplineProcessors = new ArrayList();
private ProcessorOutput outputProcessor;
private ProcessorContent contentProcessor;
//static final String E_XML_PIPELINE = "xml-pipeline";
public static final String E_OUTPUT = "output";
public static final String E_CONTENT = "content";
public ProcessorPage(TranslaterContext ctx) throws SAXException {
super(ctx);
outputProcessor = new ProcessorOutput(ctx);
}
public ElementProcessor getProcessorFor(String uri, String localName, String qName) throws SAXException {
if (URI_XP.equals(uri)) {
if (E_CONTENT.equals(localName)) {
// lazy load contentProcessor so the constructor can use results from the outputProcessor
if (null == contentProcessor) {
contentProcessor = new ProcessorContent(getTranslaterContext());
}
return contentProcessor;
} else if (E_OUTPUT.equals(localName)) {
return outputProcessor;
} else {
return super.getProcessorFor(uri, localName, qName);
}
} else {
return super.getProcessorFor(uri, localName, qName);
}
}
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
printJavaHeader();
}
public void endElement(String uri, String localName, String qName) throws SAXException {
printJavaFooter();
}
private void printJavaHeader() throws SAXException {
// package, imports, class header
JavaClass c = new JavaClass();
c.setFullClassName(getTranslaterContext().getFullClassName());
c.addInterface("org.anodyneos.xp.XpPage");
c.setExtends("org.anodyneos.xpImpl.runtime.AbstractXpPage");
CodeWriter out = getTranslaterContext().getCodeWriter();
String systemId = getTranslaterContext().getInputSource().getSystemId();
c.printHeader(out);
// output properties
out.printIndent().println("private static final java.util.Properties defaultProperties = new java.util.Properties();");
if (null != systemId) {
out.printIndent().println("private static final java.net.URI sourceURI;");
} else {
out.printIndent().println("private static java.net.URI sourceURI = null;");
}
out.println();
out.printIndent().println("static {");
out.indentPlus();
if (null != systemId) {
out.printIndent().println("java.net.URI tmp = null;");
out.printIndent().println("try {");
out.indentPlus();
out.printIndent().println("tmp = new java.net.URI(\"" + Util.escapeString(systemId) + "\");");
out.indentMinus();
out.printIndent().println("} catch ( java.net.URISyntaxException e) {");
out.indentPlus();
out.endBlock();
out.printIndent().println("sourceURI = tmp;");
}
/*
TODO: should these properties have defaults? It is probably better for them not to since the serializer (XSL) has its own defaults.
out.printIndent().println("defaultProperties.setProperty(\"cdataSectionElements\", \"\");");
out.printIndent().println("defaultProperties.setProperty(\"doctypePublic\", \"\");");
out.printIndent().println("defaultProperties.setProperty(\"doctypeSystem\", \"\");");
out.printIndent().println("defaultProperties.setProperty(\"encoding\", \"\");");
out.printIndent().println("defaultProperties.setProperty(\"indent\", \"no\");");
out.printIndent().println("defaultProperties.setProperty(\"mediaType\", \"text/xml\");");
out.printIndent().println("defaultProperties.setProperty(\"method\", \"xml\");");
out.printIndent().println("defaultProperties.setProperty(\"omitXmlDeclaration\", \"no\");");
out.printIndent().println("defaultProperties.setProperty(\"xhtmlCompat\", \"\");");
out.printIndent().println("defaultProperties.setProperty(\"xsltURI\", \"\");");
*/
out.endBlock();
out.println();
out.printIndent().println("private java.util.Properties outputProperties = new java.util.Properties(defaultProperties);");
// functionMapper
out.println();
TagLibraryRegistry tlr = getTranslaterContext().getTagLibraryRegistry();
String[] uris = tlr.getURIs();
out.printIndent().println("private static org.anodyneos.xpImpl.runtime.XpFunctionResolver fResolver = "
+ "new org.anodyneos.xpImpl.runtime.XpFunctionResolver();");
out.printIndent().println("static {");
out.indentPlus();
for (int i = 0; i < uris.length; i++) {
String uri = uris[i];
FunctionInfo[] finfos = tlr.getTagLibraryInfo(uri).getFunctionInfos();
if (null != finfos) {
for (int j = 0; j < finfos.length; j++) {
// TODO: this work should be done when we read the TLD, not now.
String args = FunctionUtil.getParameterCode(finfos[j].getFunctionSignature());
String methodName = FunctionUtil.getMethod(finfos[j].getFunctionSignature());
out.printIndent().println("fResolver.mapFunctionWithURI("
+ Util.escapeStringQuoted(uri)
+ ", " + Util.escapeStringQuoted(finfos[j].getName())
+ ", " + finfos[j].getFunctionClass().trim() + ".class"
+ ", " + Util.escapeStringQuoted(methodName)
+ ", " + args
+ ");");
}
}
}
out.endBlock();
out.println();
// constructor()
out.printIndent().println("public " + c.getClassName() + "() throws org.anodyneos.xp.XpException {");
out.indentPlus();
out.printIndent().println("initOutputProperties();");
//out.printIndent().println("super.init();");
out.endBlock();
out.println();
// getSourceURI()
out.printIndent().println("public java.net.URI getSourceURI() {");
out.indentPlus();
out.printIndent().println("return sourceURI;");
out.endBlock();
out.println();
// main()
out.printIndent().println("public static void main(String[] args) throws Exception {");
out.indentPlus();
out.printIndent().println("long start;");
out.printIndent().println("start = System.currentTimeMillis();");
out.printIndent().println(c.getFullClassName() + " obj = new " + c.getFullClassName() + "();");
out.printIndent().println("org.anodyneos.xp.standalone.StandaloneXpContext xpContext = new org.anodyneos.xpImpl.standalone.StandaloneXpContextImpl();");
out.printIndent().println("org.anodyneos.xp.util.XMLStreamer.process(new org.anodyneos.xpImpl.runtime.XpPageReader(obj, xpContext), System.out);");
out.printIndent().println("System.out.println(\"Completed in \" + (System.currentTimeMillis() - start) + \" milliseconds\");");
out.endBlock();
out.println();
}
private void printJavaFooter() {
CodeWriter out = getTranslaterContext().getCodeWriter();
// output properties
out.printIndent().println("private void initOutputProperties() {");
out.indentPlus();
if (null != getTranslaterContext().getOutputProperties()) {
Enumeration keys = getTranslaterContext().getOutputProperties().keys();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
String value = (String) outputProcessor.getTranslaterContext().getOutputProperties().get(key);
out.printIndent().println(
"outputProperties.setProperty("
+ Util.escapeStringQuoted(key)
+ ", "
+ Util.escapeStringQuoted(value)
+ ");");
}
}
out.endBlock();
out.println();
// implementing methods of XpPage interface
out.printIndent().println("public java.util.Properties getOutputProperties() {");
out.indentPlus();
out.printIndent().println("return new java.util.Properties(outputProperties);");
out.endBlock();
out.println();
out.printIndent().println("public static java.util.List getDependents(){");
out.indentPlus();
out.printIndent().println("java.util.List dependents = new java.util.ArrayList();");
List dependents = getTranslaterContext().getDependents();
for (int i = 0; i < dependents.size(); i++){
out.printIndent().println("dependents.add(\"" + dependents.get(i) + "\");");
}
out.printIndent().println("return dependents;");
out.endBlock();
out.println();
if(getTranslaterContext().getFragmentCount() > 0) {
// Output Fragments
out.flush();
out.printIndent().println("private final class FragmentHelper extends org.anodyneos.xp.tagext.XpFragment {");
out.indentPlus();
out.println();
out.printIndent().println("private int fragNum;");
out.printIndent().println("private org.anodyneos.xp.XpContext xpContext;");
out.printIndent().println("private org.anodyneos.xp.tagext.XpTag xpTagParent;");
out.printIndent().println("private boolean parentElClosed = false;");
out.printIndent().println("private org.anodyneos.xp.XpContentHandler origXpCH;");
out.printIndent().println("private int origContextVersion;");
out.printIndent().println("private int origAncestorsWithPrefixMasking;");
out.printIndent().println("private int origPhantomPrefixCount;");
out.println();
out.printIndent().println("public FragmentHelper(int fragNum, org.anodyneos.xp.XpContext xpContext, org.anodyneos.xp.tagext.XpTag xpTagParent, org.anodyneos.xp.XpContentHandler origXpCH) {");
out.indentPlus();
out.printIndent().println("this.fragNum = fragNum;");
out.printIndent().println("this.xpContext = xpContext;");
out.printIndent().println("this.xpTagParent = xpTagParent;");
out.printIndent().println("this.origXpCH = origXpCH;");
out.printIndent().println("this.origContextVersion = origXpCH.getContextVersion();");
out.printIndent().println("this.origAncestorsWithPrefixMasking = origXpCH.getAncestorsWithPrefixMasking();");
out.printIndent().println("this.origPhantomPrefixCount = origXpCH.getPhantomPrefixCount();");
out.endBlock();
out.println();
out.printIndent().println("public org.anodyneos.xp.XpContext getXpContext() {");
out.indentPlus();
out.printIndent().println("return xpContext;");
out.endBlock();
out.println();
out.printIndent().println("public void setParentElClosed(boolean closed) {");
out.indentPlus();
out.printIndent().println("this.parentElClosed = closed;");
out.endBlock();
out.println();
out.printIndent().println("public void invoke(org.anodyneos.xp.XpOutput out) throws org.anodyneos.xp.XpException, javax.servlet.jsp.el.ELException, org.xml.sax.SAXException {");
out.indentPlus();
out.printIndent().println("switch(this.fragNum) {");
out.indentPlus();
for (int i = 0; i < getTranslaterContext().getFragmentCount(); i++) {
out.printIndent().println("case " + i + ":");
out.indentPlus();
out.printIndent().println("invoke" + i + "(out);");
out.printIndent().println("break;");
out.indentMinus();
}
out.endBlock();
out.endBlock();
out.println();
for (int i = 0; i < getTranslaterContext().getFragmentCount(); i++) {
out.printIndent().println("public void invoke" + i + "(org.anodyneos.xp.XpOutput xpOut) throws org.anodyneos.xp.XpException, javax.servlet.jsp.el.ELException, org.xml.sax.SAXException {");
out.indentPlus();
out.printIndent().println("javax.servlet.jsp.el.ExpressionEvaluator elEvaluator = xpContext.getExpressionEvaluator();");
out.printIndent().println("javax.servlet.jsp.el.VariableResolver varResolver = xpContext.getVariableResolver();");
out.printIndent().println("org.anodyneos.xp.XpContentHandler xpCH = xpOut.getXpContentHandler();");
out.println();
out.print(getTranslaterContext().getFragment(i));
out.endBlock();
out.println();
}
out.println();
out.endBlock();
out.println();
}
// end of class definition
out.println();
out.endBlock();
}
}