com.sun.jsftemplating.layout.template.TemplateWriter Maven / Gradle / Ivy
/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* https://jsftemplating.dev.java.net/cddl1.html or
* jsftemplating/cddl1.txt.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at jsftemplating/cddl1.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* you own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
*/
package com.sun.jsftemplating.layout.template;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import com.sun.jsftemplating.layout.descriptors.LayoutComponent;
import com.sun.jsftemplating.layout.descriptors.LayoutDefinition;
import com.sun.jsftemplating.layout.descriptors.LayoutElement;
import com.sun.jsftemplating.layout.descriptors.LayoutStaticText;
import com.sun.jsftemplating.layout.descriptors.handler.Handler;
import com.sun.jsftemplating.layout.descriptors.handler.HandlerDefinition;
import com.sun.jsftemplating.layout.descriptors.handler.OutputMapping;
/**
* This class is responsible for writing templates. It processes a
* {@link LayoutElement} tree with a {@link LayoutDefinition} object at
* the root of the tree and writes it to a file.
*
* This class is intended to "write" one template, however, it does not
* close the given OutputStream
or prevent the
* {@link #write(LayoutDefinition)} method from being called multiple
* times.
*
* @author Ken Paulsen ([email protected])
*/
public class TemplateWriter {
/**
* Constructor.
*
* @param stream OutputStream
to the
* {@link LayoutDefinition} file.
*/
public TemplateWriter(OutputStream stream) {
_writer = new PrintWriter(stream);
}
/**
* This method should be invoked to write the given
* {@link LayoutDefinition} to the OutputStream
. This
* is the primary method of this Class.
*
* @param def The {@link LayoutDefinition}.
*
* @throws IOException
*/
public void write(LayoutDefinition def) throws IOException {
// Write out the LayoutDefinition (nothing to do except body for LDs)
writeBody("", def);
// Flush @ the end...
_writer.flush();
}
/**
* This method writes {@link Handler}s and child
* {@link LayoutElement}s.
*/
protected void writeBody(String prefix, LayoutElement elt) throws IOException {
writeHandlers(prefix, elt.getHandlersByTypeMap());
for (LayoutElement child : elt.getChildLayoutElements()) {
if (child instanceof LayoutStaticText) {
writeLayoutStaticText(prefix, (LayoutStaticText) child);
} else if (child instanceof LayoutComponent) {
writeLayoutComponent(prefix, (LayoutComponent) child);
}
}
}
/**
* This method simply writes the given str
to the
* OutputStream
.
*/
protected void write(String str) throws IOException {
_writer.print(str);
}
/**
* This method is responsible for producing the output for
* {@link Handler}s.
*/
protected void writeHandlers(String prefix, Map> handlerMap) throws IOException {
for (String eventType : handlerMap.keySet()) {
write(prefix + "\n");
}
}
/**
* This method writes output for the given {@link Handler}.
*/
protected void writeHandler(String prefix, Handler handler) throws IOException {
// Start the handler...
HandlerDefinition def = handler.getHandlerDefinition();
write(prefix + def.getId() + "(");
// Add inputs
String seperator = "";
for (String inputKey : def.getInputDefs().keySet()) {
write(seperator + inputKey + "=\""
+ handler.getInputValue(inputKey) + "\"");
seperator = ", ";
}
// Add outputs
OutputMapping output = null;
// FIXME: Support EL output mappings, e.g.: output1="#{requestScope.bar}"
for (String outputKey : def.getOutputDefs().keySet()) {
output = handler.getOutputValue(outputKey);
write(seperator + outputKey + "=>$" + output.getStringOutputType()
+ "{" + output.getOutputKey() + "}");
seperator = ", ";
}
// Close the Handler
write(");\n");
}
/**
* Write a {@link LayoutStaticText} to the
* OutputStream
.
*/
protected void writeLayoutStaticText(String prefix, LayoutStaticText text) throws IOException {
String value = "" + text.getOptions().get("value");
if (value.contains("\n")) {
// Check for multi-line comment
write(prefix + "" + value + " \n");
} else {
write(prefix + "\"" + text.getOptions().get("value") + "\n");
}
}
/**
* Write a {@link LayoutComponent} to the
* OutputStream
.
*/
protected void writeLayoutComponent(String prefix, LayoutComponent comp) throws IOException {
String type = comp.getType().getId();
write(prefix + "<" + type);
write(" id=\"" + comp.getUnevaluatedId() + "\"");
if (comp.isOverwrite()) {
write(" overwrite=\"true\"");
}
Map options = comp.getOptions();
for (String key : options.keySet()) {
write(" " + key + "=\"" + options.get(key) + "\"");
}
write(">\n");
writeBody(INDENT + prefix, comp);
write(prefix + "" + type + ">\n");
}
/**
* The PrintWriter
used to send output the the
* OutputStream
.
*/
private PrintWriter _writer = null;
/**
* This is the value used when indenting is needed.
*/
private static final String INDENT = " ";
}