com.sun.jsftemplating.layout.xml.XMLLayoutDefinitionReader 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 2006 Sun Microsystems, Inc. All rights reserved.
*/
package com.sun.jsftemplating.layout.xml;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import com.sun.jsftemplating.layout.LayoutDefinitionManager;
import com.sun.jsftemplating.layout.SyntaxException;
import com.sun.jsftemplating.layout.descriptors.ComponentType;
import com.sun.jsftemplating.layout.descriptors.LayoutAttribute;
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.LayoutFacet;
import com.sun.jsftemplating.layout.descriptors.LayoutForEach;
import com.sun.jsftemplating.layout.descriptors.LayoutIf;
import com.sun.jsftemplating.layout.descriptors.LayoutMarkup;
import com.sun.jsftemplating.layout.descriptors.LayoutStaticText;
import com.sun.jsftemplating.layout.descriptors.LayoutWhile;
import com.sun.jsftemplating.layout.descriptors.Resource;
import com.sun.jsftemplating.layout.descriptors.handler.Handler;
import com.sun.jsftemplating.layout.descriptors.handler.HandlerDefinition;
import com.sun.jsftemplating.layout.descriptors.handler.IODescriptor;
import com.sun.jsftemplating.util.IncludeInputStream;
import com.sun.jsftemplating.util.LayoutElementUtil;
/**
* This class is responsible for doing the actual parsing of an XML
* document following the layout.dtd
. It produces a
* {@link LayoutElement} tree with a {@link LayoutDefinition} object at
* the root of the tree.
*
* @author Ken Paulsen ([email protected])
*/
public class XMLLayoutDefinitionReader {
/**
* Constructor.
*
* @param url A URL pointing to the {@link LayoutDefinition}
* @param entityResolver EntityResolver to use, may be (null)
* @param errorHandler ErrorHandler to use, may be (null)
* @param baseURI The base URI passed to DocumentBuilder.parse()
*/
public XMLLayoutDefinitionReader(URL url, EntityResolver entityResolver, ErrorHandler errorHandler, String baseURI) {
_url = url;
_entityResolver = entityResolver;
_errorHandler = errorHandler;
_baseURI = baseURI;
}
/**
* Accessor for the URL.
*/
public URL getURL() {
return _url;
}
/**
* Accessor for the entityResolver.
*/
public EntityResolver getEntityResolver() {
return _entityResolver;
}
/**
* Accessor for the ErrorHandler.
*/
public ErrorHandler getErrorHandler() {
return _errorHandler;
}
/**
* Accessor for the base URI.
*/
public String getBaseURI() {
return _baseURI;
}
/**
* The read method opens the given URL and parses the XML document
* that it points to. It then walks the DOM and populates a
* {@link LayoutDefinition} structure, which is returned.
*
* @return The {@link LayoutDefinition}
*
* @throws IOException
*/
public LayoutDefinition read() throws IOException {
// Open the URL
InputStream inputStream = new IncludeInputStream(
new BufferedInputStream(getURL().openStream()));
Document doc = null;
try {
// Get a DocumentBuilderFactory and set it up
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(true);
dbf.setIgnoringComments(true);
dbf.setIgnoringElementContentWhitespace(false);
dbf.setCoalescing(false);
// The opposite of creating entity ref nodes is expanding inline
dbf.setExpandEntityReferences(true);
// Get a DocumentBuilder...
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException ex) {
throw new RuntimeException(ex);
}
if (getEntityResolver() != null) {
db.setEntityResolver(getEntityResolver());
}
if (getErrorHandler() != null) {
db.setErrorHandler(getErrorHandler());
}
// Parse the XML file
try {
doc = db.parse(inputStream, getBaseURI());
} catch (IOException ex) {
throw new SyntaxException("Unable to parse XML file!", ex);
} catch (SAXException ex) {
throw new SyntaxException(ex);
}
} finally {
try {
inputStream.close();
} catch (Exception ex) {
// Ignore...
}
}
// Populate the LayoutDefinition from the Document
return createLayoutDefinition(doc);
}
/**
* This method is responsible for extracting all the information out
* of the supplied document and filling the {@link LayoutDefinition}
* structure.
*
* @param doc The Document
object to read.
*
* @return The new {@link LayoutDefinition} Object.
*/
private LayoutDefinition createLayoutDefinition(Document doc) {
// Get the document element (LAYOUT_DEFINITION_ELEMENT)
Node node = doc.getDocumentElement();
if (!node.getNodeName().equalsIgnoreCase(LAYOUT_DEFINITION_ELEMENT)) {
throw new RuntimeException("Document Element must be '"
+ LAYOUT_DEFINITION_ELEMENT + "'");
}
// Create a new LayoutDefinition (the id is not propagated here)
LayoutDefinition ld = new LayoutDefinition("");
// Do "resources" first, they are defined at the top of the document
List childElements = getChildElements(node, RESOURCES_ELEMENT);
Iterator it = childElements.iterator();
if (it.hasNext()) {
// Found the RESOURCES_ELEMENT, there is at most 1
addResources(ld, it.next());
}
// Do "types", they need to be defined before parsing the layout
childElements = getChildElements(node, TYPES_ELEMENT);
it = childElements.iterator();
if (it.hasNext()) {
// Found the TYPES_ELEMENT, there is at most 1
addTypes(ld, it.next());
}
// Do "handlers" next, they need to be defined before parsing the layout
childElements = getChildElements(node, HANDLERS_ELEMENT);
it = childElements.iterator();
if (it.hasNext()) {
// Found the HANDLERS_ELEMENT, there is at most 1
cacheHandlerDefs(it.next());
}
// Look to see if there is an EVENT_ELEMENT defined
childElements = getChildElements(node, EVENT_ELEMENT);
it = childElements.iterator();
if (it.hasNext()) {
// Found the EVENT_ELEMENT, there is at most 1
// Get the event type
Node eventNode = it.next();
String type = getAttributes(eventNode).get(TYPE_ATTRIBUTE);
// Set the Handlers for the given event type (name)
List handlers = ld.getHandlers(type);
ld.setHandlers(type, getHandlers(eventNode, handlers));
}
// Next look for "layout", there is exactly 1
childElements = getChildElements(node, LAYOUT_ELEMENT);
it = childElements.iterator();
if (it.hasNext()) {
// Found the LAYOUT_ELEMENT, there is only 1
addChildLayoutElements(ld, it.next());
} else {
throw new RuntimeException("A '" + LAYOUT_ELEMENT
+ "' element is required in the XML document!");
}
// Return the LayoutDefinition
return ld;
}
/**
* This method iterates throught the child RESOURCE_ELEMENT nodes and
* adds new resource objects to the {@link LayoutDefinition}.
*
* @param ld The {@link LayoutDefinition}
* @param node Parent Node
containing the
* {@link #RESOURCE_ELEMENT} nodes.
*/
private void addResources(LayoutDefinition ld, Node node) {
// Get the child nodes
Iterator it = getChildElements(node, RESOURCE_ELEMENT).iterator();
// Walk children (we only care about RESOURCE_ELEMENT)
while (it.hasNext()) {
// Found a RESOURCE_ELEMENT
ld.addResource(createResource(it.next()));
}
}
/**
* This method takes the given Resource Element node and reads the
* {@link #ID_ATTRIBUTE}, {@link #EXTRA_INFO_ATTRIBUTE} and
* {@link #FACTORY_CLASS_ATTRIBUTE} attributes. It then instantiates
* a new {@link Resource} with the values of these two attributes.
*
* @param node The {@link Resource} node to extract information from
* when creating the {@link Resource}.
*/
private Resource createResource(Node node) {
// Pull off the attributes
Map attributes = getAttributes(node);
String id = attributes.get(ID_ATTRIBUTE);
String extraInfo = attributes.get(EXTRA_INFO_ATTRIBUTE);
String factoryClass = attributes.get(FACTORY_CLASS_ATTRIBUTE);
// Make sure required values are present
if ((factoryClass == null) || (id == null) || (extraInfo == null)
|| (factoryClass.trim().equals("")) || (id.trim().equals(""))
|| (extraInfo.trim().equals(""))) {
throw new RuntimeException("'" + ID_ATTRIBUTE + "', '"
+ EXTRA_INFO_ATTRIBUTE + "', and '"
+ FACTORY_CLASS_ATTRIBUTE + "' are required attributes of '"
+ RESOURCE_ELEMENT + "' Element!");
}
// Create the new Resource
return new Resource(id, extraInfo, factoryClass);
}
/**
* This method iterates through the child
* {@link #COMPONENT_TYPE_ELEMENT} nodes and adds new
* {@link ComponentTypes} to the {@link LayoutDefinition}.
*
* @param ld The {@link LayoutDefinition}
* @param node Parent Node
containing the
* {@link #COMPONENT_TYPE_ELEMENT} nodes
*/
private void addTypes(LayoutDefinition ld, Node node) {
// Get the child nodes
Iterator it =
getChildElements(node, COMPONENT_TYPE_ELEMENT).iterator();
// Walk the COMPONENT_TYPE_ELEMENT elements
while (it.hasNext()) {
ld.addComponentType(createComponentType(it.next()));
}
}
/**
* This method takes the given {@link ComponentType} Element node and
* reads the {@link #ID_ATTRIBUTE} and {@link #FACTORY_CLASS_ATTRIBUTE}
* attributes. It then instantiates a new {@link ComponentType} with
* the values of these two attributes.
*
* @param node The {@link ComponentType} node to extract information
* from when creating the {@link ComponentType}.
*/
private ComponentType createComponentType(Node node) {
// Pull off the attributes
Map attributes = getAttributes(node);
String id = attributes.get(ID_ATTRIBUTE);
String factoryClass = attributes.get(FACTORY_CLASS_ATTRIBUTE);
// Make sure required values are present
if ((factoryClass == null) || (id == null)
|| (factoryClass.trim().equals("")) || (id.trim().equals(""))) {
throw new RuntimeException("Both '" + ID_ATTRIBUTE + "' and '"
+ FACTORY_CLASS_ATTRIBUTE + "' are required attributes of '"
+ COMPONENT_TYPE_ELEMENT + "' Element!");
}
// Create the new ComponentType
return new ComponentType(id, factoryClass);
}
/**
* This method iterates through the child
* {@link #HANDLER_DEFINITION_ELEMENT} nodes and caches them, so they
* may be retrieved later by {@link Handlers} referring to them.
*
* @param node Parent Node
containing
* {@link #HANDLER_DEFINITION_ELEMENT} nodes.
*/
private void cacheHandlerDefs(Node node) {
HandlerDefinition def = null;
// Get the child nodes
Iterator it =
getChildElements(node, HANDLER_DEFINITION_ELEMENT).iterator();
while (it.hasNext()) {
// Found a HANDLER_DEFINITION_ELEMENT, cache it
def = createHandlerDefinition(it.next());
_handlerDefs.put(def.getId(), def);
}
}
/**
* This method takes the given {@link #HANDLER_DEFINITION_ELEMENT}
* node and reads the {@link #ID_ATTRIBUTE},
* {@link #CLASS_NAME_ATTRIBUTE}, and {@link #METHOD_NAME_ATTRIBUTE}
* attributes. It then instantiates a new {@link HandlerDefinition}
* object.
*
* Next it looks to see if the {@link HandlerDefinition} has child
* inputDef, outputDef, and/or nested handler elements. If so it
* processes them.
*
* @param node The {@link #HANDLER_DEFINITION_ELEMENT} node to extract
* information from when creating the
* {@link HandlerDefinition}.
*
* @return The newly created {@link HandlerDefinition}.
*/
public HandlerDefinition createHandlerDefinition(Node node) {
// Create he HandlerDefinition
Map attributes = getAttributes(node);
String value = attributes.get(ID_ATTRIBUTE);
HandlerDefinition hd = new HandlerDefinition(value);
// hd.setDescription(_description)
// Check for a className
value = attributes.get(CLASS_NAME_ATTRIBUTE);
if ((value != null) && !value.equals("")) {
// Found a className, now get the methodName
String tmpStr = attributes.get(METHOD_NAME_ATTRIBUTE);
if ((tmpStr == null) || tmpStr.equals("")) {
throw new IllegalArgumentException("You must provide a '"
+ METHOD_NAME_ATTRIBUTE + "' attribute on the '"
+ HANDLER_DEFINITION_ELEMENT + "' element with "
+ CLASS_NAME_ATTRIBUTE + " atttribute equal to '"
+ value + "'.");
}
hd.setHandlerMethod(value, tmpStr);
}
// Add child handlers to this HandlerDefinition. This allows a
// HandlerDefinition to define handlers that should be invoked before
// the method defined by this handler definition is invoked.
List handlers = new ArrayList(hd.getChildHandlers());
hd.setChildHandlers(getHandlers(node, handlers));
// Add InputDef objects to the HandlerDefinition
addInputDefs(hd, node);
// Add OutputDef objects to the HandlerDefinition
addOutputDefs(hd, node);
// Return the newly created HandlerDefinition object
return hd;
}
/**
* This method creates a List
of {@link Handler}s from
* the provided Node
. It will look at the child
* Element
s for {@link #HANDLER_ELEMENT} elements. When
* found, it will create a new {@link Handler} object and add it to a
* List
that is created internally. This
* List
is returned.
*
* @param node Node
containing
* {@link #HANDLER_ELEMENT} elements.
* @param handlers List
of existing {@link Handler}s.
*
* @return A List
of {@link Handler} objects, empty
* List
if no {@link Handler}s found
*/
private List getHandlers(Node node, List handlers) {
// Get the child nodes
Iterator it = getChildElements(node, HANDLER_ELEMENT).iterator();
// Walk children (we only care about HANDLER_ELEMENT)
if (handlers == null) {
handlers = new ArrayList();
}
while (it.hasNext()) {
// Found a HANDLER_ELEMENT
handlers.add(createHandler(it.next()));
}
// Return the handlers
return handlers;
}
/**
* This method creates a {@link Handler} from the given handler
* Node
. It will add input and/or output mappings
* specified by any child Elements named {@link #INPUT_ELEMENT} or
* {@link #OUTPUT_MAPPING_ELEMENT}.
*
* @param handlerNode The Node
describing the
* {@link Handler} to be created.
*
* @return The newly created {@link Handler}.
*/
private Handler createHandler(Node handlerNode) {
// Pull off attributes...
String id = (String) getAttributes(handlerNode).
get(ID_ATTRIBUTE);
if ((id == null) || (id.trim().equals(""))) {
throw new RuntimeException("'" + ID_ATTRIBUTE
+ "' attribute not found on '" + HANDLER_ELEMENT
+ "' Element!");
}
// Find the HandlerDefinition associated with this Handler
HandlerDefinition handlerDef = getHandlerDef(id);
if (handlerDef == null) {
throw new IllegalArgumentException(HANDLER_ELEMENT + " elements "
+ ID_ATTRIBUTE + " attribute must match the "
+ ID_ATTRIBUTE + " attribute of a "
+ HANDLER_DEFINITION_ELEMENT + ". A HANDLER_ELEMENT with '"
+ id + "' was specified, however there is no cooresponding "
+ HANDLER_DEFINITION_ELEMENT + " with a matching "
+ ID_ATTRIBUTE + " attribute.");
}
// Create new Handler
Handler handler = new Handler(handlerDef);
// Add the inputs
Map attributes = null;
Node inputNode = null;
Iterator it = getChildElements(handlerNode, INPUT_ELEMENT).iterator();
while (it.hasNext()) {
// Processing an INPUT_ELEMENT
inputNode = it.next();
attributes = getAttributes(inputNode);
handler.setInputValue(attributes.get(NAME_ATTRIBUTE),
getValueFromNode(inputNode, attributes));
}
// Add the OutputMapping objects
it = getChildElements(handlerNode, OUTPUT_MAPPING_ELEMENT).iterator();
while (it.hasNext()) {
// Processing an OUTPUT_MAPPING_ELEMENT
attributes = getAttributes(it.next());
handler.setOutputMapping(
attributes.get(OUTPUT_NAME_ATTRIBUTE),
attributes.get(TARGET_KEY_ATTRIBUTE),
attributes.get(TARGET_TYPE_ATTRIBUTE));
}
// Return the newly created handler
return handler;
}
/**
* This method first attempts to find a locally defined
* {@link HandlerDefinition} with the given id
. If
* found, it will be returned, otherwise it attempts to return a
* globally defined {@link HandlerDefinition} via {@link
* LayoutDefinitionManager#getGlobalHandlerDefinition(String)}.
*
* @param id The desired {@link HandlerDefinition}'s id.
*
* @return The desired {@link HandlerDefinition} or null
.
*/
private HandlerDefinition getHandlerDef(String id) {
// Try local...
HandlerDefinition def = _handlerDefs.get(id);
if (def == null) {
// Try global...
def = LayoutDefinitionManager.getGlobalHandlerDefinition(id);
}
return def;
}
/**
* This method adds InputDefs to the given {@link HandlerDefinition}
* object. It will look at the child elements for those named
* {@link #INPUT_DEF_ELEMENT}. It will create an {@link #IODescriptor}
* for each and add it to the {@link HandlerDefinition}.
*
* @param hd {@link HandlerDefinition}.
* @param hdNode {@link HandlerDefinition} Node
, its
* children will be searched
*/
private void addInputDefs(HandlerDefinition hd, Node hdNode) {
// Get the child nodes
Iterator it =
getChildElements(hdNode, INPUT_DEF_ELEMENT).iterator();
// Walk children (we only care about INPUT_DEF_ELEMENT)
while (it.hasNext()) {
// Found a INPUT_DEF_ELEMENT
hd.addInputDef(createIODescriptor(it.next()));
}
}
/**
* This method adds OutputDefs to the given {@link HandlerDefinition}
* object. It will look at the child elements for those named
* {@link #OUTPUT_DEF_ELEMENT}. It will create an {@link #IODescriptor}
* for each and add it to the {@link HandlerDefinition}.
*
* @param hd {@link HandlerDefinition}.
* @param hdNode {@link HandlerDefinition} Node
, its
* children will be searched.
*/
private void addOutputDefs(HandlerDefinition hd, Node hdNode) {
// Get the child nodes
Iterator it =
getChildElements(hdNode, OUTPUT_DEF_ELEMENT).iterator();
// Walk children (we only care about OUTPUT_DEF_ELEMENT)
while (it.hasNext()) {
// Found a OUTPUT_DEF_ELEMENT
hd.addOutputDef(createIODescriptor(it.next()));
}
}
/**
* This method will create an {@link #IODescriptor} from the given
* node. The node must contain atleast a {@link #NAME_ATTRIBUTE} and a
* {@link #TYPE_ATTRIBUTE} attribute. It may also contain a
* {@link #DEFAULT_ATTRIBUTE} and a {@link #REQUIRED_ATTRIBUTE}. These
* are only meaningful for input {@link IODescriptors}, however --
* this method does not know the difference between input and output
* descriptors.
*
* @param node The Node
holding info used to create an
* {@link IODescriptor}.
*
* @return A newly created {@link IODescriptor}.
*/
private IODescriptor createIODescriptor(Node node) {
// Get the attributes
Map attributes = getAttributes(node);
String name = attributes.get(NAME_ATTRIBUTE);
if ((name == null) || name.equals("")) {
throw new IllegalArgumentException("Name must be provided!");
}
String type = attributes.get(TYPE_ATTRIBUTE);
if ((type == null) || type.equals("")) {
throw new IllegalArgumentException("Type must be provided!");
}
Object def = attributes.get(DEFAULT_ATTRIBUTE);
String req = attributes.get(REQUIRED_ATTRIBUTE);
// Create the IODescriptor
IODescriptor ioDesc = new IODescriptor(name, type);
ioDesc.setDefault(def);
if (req != null) {
ioDesc.setRequired(Boolean.valueOf(req).booleanValue());
}
// ioDesc.setDescription(attributes.get(DESCRIPTION_ATTRIBUTE))
// Return the new IODescriptor
return ioDesc;
}
/**
* This method adds child LayoutElements.
*
* @param layoutDefinition
* @param node
*/
private void addChildLayoutElements(LayoutElement layElt, Node node) {
// Get the child nodes
Iterator it = getChildElements(node).iterator();
// Walk children (we care about IF_ELEMENT, ATTRIBUTE_ELEMENT,
// MARKUP_ELEMENT, FACET_ELEMENT, STATIC_TEXT_ELEMENT,
// COMPONENT_ELEMENT, EVENT_ELEMENT, FOREACH_ELEMENT, EDIT_ELEMENT, and
// WHILE_ELEMENT)
Node childNode = null;
String name = null;
while (it.hasNext()) {
childNode = it.next();
name = childNode.getNodeName();
if (name.equalsIgnoreCase(IF_ELEMENT)) {
// Found a IF_ELEMENT
layElt.addChildLayoutElement(
createLayoutIf(layElt, childNode));
} else if (name.equalsIgnoreCase(ATTRIBUTE_ELEMENT)) {
// Found a ATTRIBUTE_ELEMENT
LayoutElement childElt =
createLayoutAttribute(layElt, childNode);
if (childElt != null) {
layElt.addChildLayoutElement(childElt);
}
} else if (name.equalsIgnoreCase(MARKUP_ELEMENT)) {
// Found a MARKUP_ELEMENT
layElt.addChildLayoutElement(
createLayoutMarkup(layElt, childNode));
} else if (name.equalsIgnoreCase(FACET_ELEMENT)) {
// Found a FACET_ELEMENT
layElt.addChildLayoutElement(
createLayoutFacet(layElt, childNode));
} else if (name.equalsIgnoreCase(STATIC_TEXT_ELEMENT)) {
// Found a STATIC_TEXT_ELEMENT
layElt.addChildLayoutElement(
createLayoutStaticText(layElt, childNode));
} else if (name.equalsIgnoreCase(COMPONENT_ELEMENT)) {
// Found a COMPONENT_ELEMENT
layElt.addChildLayoutElement(
createLayoutComponent(layElt, childNode));
} else if (name.equalsIgnoreCase(EVENT_ELEMENT)) {
// Found a EVENT_ELEMENT
// Get the event type
name = getAttributes(childNode).get(TYPE_ATTRIBUTE);
// Set the Handlers for the given event type (name)
List handlers = layElt.getHandlers(name);
layElt.setHandlers(name, getHandlers(childNode, handlers));
} else if (name.equalsIgnoreCase(FOREACH_ELEMENT)) {
// Found a FOREACH_ELEMENT
layElt.addChildLayoutElement(
createLayoutForEach(layElt, childNode));
} else if (name.equalsIgnoreCase(WHILE_ELEMENT)) {
// Found a WHILE_ELEMENT
layElt.addChildLayoutElement(
createLayoutWhile(layElt, childNode));
} else if (name.equalsIgnoreCase(EDIT_ELEMENT)) {
// Found an EDIT_ELEMENT
layElt.addChildLayoutElement(
createEditLayoutComponent(layElt, childNode));
} else {
throw new RuntimeException("Unknown Element Found: '"
+ childNode.getNodeName() + "' under '"
+ node.getNodeName() + "'.");
}
}
}
/**
* This method creates a new {@link LayoutIf}
* {@link LayoutElement}.
*
* @param parent The parent {@link LayoutElement}.
* @param node The {@link #IF_ELEMENT} node to extract information from
* when creating the {@link LayoutIf}
*/
private LayoutElement createLayoutIf(LayoutElement parent, Node node) {
// Pull off attributes...
String condition = (String) getAttributes(node).get(
CONDITION_ATTRIBUTE);
if ((condition == null) || (condition.trim().equals(""))) {
throw new RuntimeException("'" + CONDITION_ATTRIBUTE
+ "' attribute not found on '" + IF_ELEMENT + "' Element!");
}
// Create new LayoutIf
LayoutElement ifElt = new LayoutIf(parent, condition);
// Add children...
addChildLayoutElements(ifElt, node);
// Return the if
return ifElt;
}
/**
* This method creates a new {@link LayoutForEach}
* {@link LayoutElement}.
*
* @param parent The parent {@link LayoutElement}.
* @param node The {@link #FOREACH_ELEMENT} node to extract
* information from when creating the
* {@link LayoutForEach}.
*
* @return The new {@link LayoutForEach} {@link LayoutElement}.
*/
private LayoutElement createLayoutForEach(LayoutElement parent, Node node) {
// Pull off attributes...
String list = (String) getAttributes(node).get(
LIST_ATTRIBUTE);
if ((list == null) || (list.trim().equals(""))) {
throw new RuntimeException("'" + LIST_ATTRIBUTE
+ "' attribute not found on '" + FOREACH_ELEMENT
+ "' Element!");
}
String key = (String) getAttributes(node).get(
KEY_ATTRIBUTE);
if ((key == null) || (key.trim().equals(""))) {
throw new RuntimeException("'" + KEY_ATTRIBUTE
+ "' attribute not found on '" + FOREACH_ELEMENT
+ "' Element!");
}
// Create new LayoutForEach
LayoutElement forEachElt = new LayoutForEach(parent, list, key);
// Add children...
addChildLayoutElements(forEachElt, node);
// Return the forEach
return forEachElt;
}
/**
* This method creates a new {@link LayoutWhile}
* {@link LayoutElement}.
*
* @param parent The parent {@link LayoutElement}.
* @param node The {@link #WHILE_ELEMENT} node to extract information
* from when creating the LayoutWhile.
*
* @return The new {@link LayoutWhile} {@link LayoutElement}.
*/
private LayoutElement createLayoutWhile(LayoutElement parent, Node node) {
// Pull off attributes...
String condition = (String) getAttributes(node).get(
CONDITION_ATTRIBUTE);
if ((condition == null) || (condition.trim().equals(""))) {
throw new RuntimeException("'" + CONDITION_ATTRIBUTE
+ "' attribute not found on '" + WHILE_ELEMENT
+ "' Element!");
}
// Create new LayoutWhile
LayoutElement whileElt = new LayoutWhile(parent, condition);
// Add children...
addChildLayoutElements(whileElt, node);
// Return the while
return whileElt;
}
/**
*
*
* @param parent The parent {@link LayoutElement}.
* @param node The {@link #ATTRIBUTE_ELEMENT} node to extract
* information from when creating the
* {@link LayoutAttribute}
*/
private LayoutElement createLayoutAttribute(LayoutElement parent, Node node) {
// Pull off attributes...
Map attributes = getAttributes(node);
String name = attributes.get(NAME_ATTRIBUTE);
if ((name == null) || (name.trim().equals(""))) {
throw new RuntimeException("'" + NAME_ATTRIBUTE
+ "' attribute not found on '" + ATTRIBUTE_ELEMENT
+ "' Element!");
}
LayoutElement attributeElt = null;
// Check if we're setting this on a LayoutComponent vs. LayoutMarkup
// Do this after checking for "name" to show correct error message
LayoutComponent comp = null;
if (parent instanceof LayoutComponent) {
comp = (LayoutComponent) parent;
} else {
comp = LayoutElementUtil.getParentLayoutComponent(parent);
}
if (comp != null) {
// Treat this as a LayoutComponent "option" instead of "attribute"
addOption(comp, node);
} else {
String value = attributes.get(VALUE_ATTRIBUTE);
String property = attributes.get(PROPERTY_ATTRIBUTE);
// Create new LayoutAttribute
attributeElt = new LayoutAttribute(parent, name, value, property);
// Add children... (event children are supported)
addChildLayoutElements(attributeElt, node);
}
// Return the LayoutAttribute (or null if inside LayoutComponent)
return attributeElt;
}
/**
* This method creates a new {@link LayoutMarkup}.
*
* @param parent The parent {@link LayoutElement}.
* @param node The {@link #MARKUP_ELEMENT} node to extract information
* from when creating the {@link LayoutMarkup}.
*/
private LayoutElement createLayoutMarkup(LayoutElement parent, Node node) {
// Pull off attributes...
Map attributes = getAttributes(node);
String tag = attributes.get(TAG_ATTRIBUTE);
if ((tag == null) || (tag.trim().equals(""))) {
throw new RuntimeException("'" + TAG_ATTRIBUTE
+ "' attribute not found on '" + MARKUP_ELEMENT
+ "' Element!");
}
// Check to see if this is inside a LayoutComponent, if so, we must
// use a LayoutComponent for it to get rendered
LayoutElement markupElt = null;
if ((parent instanceof LayoutComponent)
|| LayoutElementUtil.isNestedLayoutComponent(parent)) {
// Make a "markup" LayoutComponent..
ComponentType type = ensureMarkupType(parent);
markupElt = new LayoutComponent(
parent, MARKUP_ELEMENT + _markupCount++, type);
LayoutComponent markupComp = ((LayoutComponent) markupElt);
markupComp.addOption("tag", tag);
markupComp.setNested(true);
// Add children...
addChildLayoutComponentChildren(markupComp, node);
} else {
// Create new LayoutMarkup
String type = attributes.get(TYPE_ATTRIBUTE);
markupElt = new LayoutMarkup(parent, tag, type);
// Add children...
addChildLayoutElements(markupElt, node);
}
// Return the LayoutMarkup
return markupElt;
}
/**
* This method is responsible for Creating a {@link LayoutFacet}
* {@link LayoutElement}.
*
* @param parent The parent {@link LayoutElement}.
* @param node The {@link #FACET_ELEMENT} node to extract information
* from when creating the {@link LayoutFacet}.
*
* @return The new {@link LayoutFacet} {@link LayoutElement}.
*/
private LayoutElement createLayoutFacet(LayoutElement parent, Node node) {
// Pull off attributes...
// id
String id = (String) getAttributes(node).get(ID_ATTRIBUTE);
if ((id == null) || (id.trim().equals(""))) {
throw new RuntimeException("'" + ID_ATTRIBUTE
+ "' attribute not found on '" + FACET_ELEMENT
+ "' Element!");
}
// Create new LayoutFacet
LayoutFacet facetElt = new LayoutFacet(parent, id);
// Set isRendered
String rendered = (String) getAttributes(node).get(RENDERED_ATTRIBUTE);
boolean isRendered = true;
if ((rendered == null) || rendered.trim().equals("")
|| rendered.equals(AUTO_RENDERED)) {
// Automatically determine if this LayoutFacet should be rendered
isRendered = !LayoutElementUtil.isNestedLayoutComponent(facetElt);
} else {
isRendered = Boolean.getBoolean(rendered);
}
facetElt.setRendered(isRendered);
// Add children...
addChildLayoutElements(facetElt, node);
// Return the LayoutFacet
return facetElt;
}
/**
*
* @param node The {@link #COMPONENT_ELEMENT} node to extract
* information from when creating the
* {@link LayoutComponent}.
*/
private LayoutElement createLayoutComponent(LayoutElement parent, Node node) {
// Pull off attributes...
Map attributes = getAttributes(node);
String id = attributes.get(ID_ATTRIBUTE);
String type = attributes.get(TYPE_ATTRIBUTE);
if ((type == null) || (type.trim().equals(""))) {
throw new RuntimeException("'" + TYPE_ATTRIBUTE
+ "' attribute not found on '" + COMPONENT_ELEMENT
+ "' Element!");
}
// Create new LayoutComponent
LayoutComponent component = new LayoutComponent(parent, id,
getComponentType(parent, type));
// Check for overwrite flag
String overwrite = attributes.get(OVERWRITE_ATTRIBUTE);
if ((overwrite != null) && (overwrite.length() > 0)) {
component.setOverwrite(Boolean.valueOf(overwrite).booleanValue());
}
// Set flag to indicate if this LayoutComponent is nested in another
// LayoutComponent. This is significant b/c during rendering, events
// will need to be fired differently (the TemplateRenderer /
// LayoutElements will not have any control). The strategy used will
// rely on "instance" handlers, this flag indicates that "instance"
// handlers should be used.
// NOTE: While this could be implemented on the LayoutComponent
// itself, I decided not to for performance reasons and to
// allow this value to be overruled if desired.
component.setNested(
LayoutElementUtil.isNestedLayoutComponent(component));
// Figure out if this should be stored as a facet, if so under what id
if (!LayoutElementUtil.isLayoutComponentChild(component)) {
// Need to add this so that it has the correct facet name
// Check to see if this LayoutComponent is inside a LayoutFacet
while (parent != null) {
if (parent instanceof LayoutFacet) {
// Inside a LayoutFacet, use its id... only if this facet
// is a child of a LayoutComponent (otherwise, it is a
// layout facet used for layout, not for defining a facet
// of a UIComponent)
if (LayoutElementUtil.isLayoutComponentChild(parent)) {
id = parent.getUnevaluatedId();
}
break;
}
parent = parent.getParent();
}
// Set the facet name
component.addOption(LayoutComponent.FACET_NAME, id);
}
// Add children... (different for component LayoutElements)
addChildLayoutComponentChildren(component, node);
// Return the LayoutComponent
return component;
}
/**
*
*/
private void addChildLayoutComponentChildren(LayoutComponent component, Node node) {
// Get the child nodes
Iterator it = getChildElements(node).iterator();
// Walk children (we care about COMPONENT_ELEMENT, FACET_ELEMENT,
// OPTION_ELEMENT, EVENT_ELEMENT, MARKUP_ELEMENT, and EDIT_ELEMENT)
Node childNode = null;
String name = null;
while (it.hasNext()) {
childNode = it.next();
name = childNode.getNodeName();
if (name.equalsIgnoreCase(COMPONENT_ELEMENT)) {
// Found a COMPONENT_ELEMENT
component.addChildLayoutElement(
createLayoutComponent(component, childNode));
} else if (name.equalsIgnoreCase(FACET_ELEMENT)) {
// Found a FACET_ELEMENT
component.addChildLayoutElement(
createLayoutFacet(component, childNode));
} else if (name.equalsIgnoreCase(OPTION_ELEMENT)) {
// Found a OPTION_ELEMENT
addOption(component, childNode);
} else if (name.equalsIgnoreCase(EVENT_ELEMENT)) {
// Found a EVENT_ELEMENT
// Get the event type
name = getAttributes(childNode).get(TYPE_ATTRIBUTE);
// Set the Handlers for the given event type (name)
List handlers = component.getHandlers(name);
component.setHandlers(name, getHandlers(childNode, handlers));
} else if (name.equalsIgnoreCase(EDIT_ELEMENT)) {
// Found an EDIT_ELEMENT
component.addChildLayoutElement(
createEditLayoutComponent(component, childNode));
} else if (name.equalsIgnoreCase(MARKUP_ELEMENT)) {
// Found an MARKUP_ELEMENT
component.addChildLayoutElement(
createLayoutMarkup(component, childNode));
} else if (name.equalsIgnoreCase(STATIC_TEXT_ELEMENT)) {
// Found a STATIC_TEXT_ELEMENT
component.addChildLayoutElement(
createLayoutStaticText(component, childNode));
} else if (name.equalsIgnoreCase(ATTRIBUTE_ELEMENT)) {
// Found a ATTRIBUTE_ELEMENT (actually in this case it will
// just add an "option" to the LayoutComponent), technically
// this case should only happen for LayoutMarkup components...
// this mess is caused by trying to support 2 .dtd's w/ 1 .dtd
// file... perhaps it's time to split.
createLayoutAttribute(component, childNode);
} else {
throw new RuntimeException("Unknown Element Found: '"
+ childNode.getNodeName() + "' under '<"
+ COMPONENT_ELEMENT + " id=\""
+ component.getUnevaluatedId() + "\"...'.");
}
}
}
/**
* This adds a special {@link LayoutComponent} to the
* UIComponent
tree that serves as a marker indicating
* that it is OK to edit this block of code. Editors can take
* advantage of this to know what is safe to edit. The type will be
* "markup" the id will be prefixed by {@link #EDITABLE} and an
* "option" named {@link #EDITABLE}, value == true
will
* be added.
*
* @param node The {@link #COMPONENT_ELEMENT} node to extract
* information from when creating the Edit
* {@link LayoutComponent}.
*/
private LayoutElement createEditLayoutComponent(LayoutElement parent, Node node) {
// First Add a popupMenu around this component... use it as the parent
parent = createEditPopupMenuLayoutComponent(parent, node);
// Pull off attributes...
Map attributes = getAttributes(node);
String id = attributes.get(ID_ATTRIBUTE);
// Create the LayoutComponent
ComponentType type = ensureEditAreaType(parent);
LayoutComponent component =
new LayoutComponent(parent, EDITABLE + id, type);
parent.addChildLayoutElement(component);
// Configure it...
component.setNested(
LayoutElementUtil.isNestedLayoutComponent(component));
component.addOption(EDITABLE, Boolean.TRUE); // Flag
// Add children... (different for component LayoutElements)
addChildLayoutComponentChildren(component, node);
return parent;
}
/**
* This method creates a PopupMenu component w/ the Editor
* commands.
*/
private LayoutElement createEditPopupMenuLayoutComponent(LayoutElement parent, Node node) {
// Pull off attributes...
Map attributes = getAttributes(node);
String id = attributes.get(ID_ATTRIBUTE);
// Create the LayoutComponent
ComponentType type = ensurePopupMenuType(parent);
LayoutComponent popupMenu =
new LayoutComponent(parent, EDIT_MENU + id, type);
// Configure it...
popupMenu.setNested(
LayoutElementUtil.isNestedLayoutComponent(popupMenu));
// Could add "menu" facet here, however, I decided to do it in the xml
// Return the result
return popupMenu;
}
/**
* This method ensures that a "popupMenu" {@link ComponentType} has
* been defined so that it can be used implicitly.
*/
private ComponentType ensurePopupMenuType(LayoutElement elt) {
// See if it is defined
LayoutDefinition ld = elt.getLayoutDefinition();
ComponentType type = null;
try {
type = getComponentType(elt, POPUP_MENU_TYPE);
} catch (IllegalArgumentException ex) {
// Nope, define it...
type = new ComponentType(POPUP_MENU_TYPE, POPUP_MENU_TYPE_CLASS);
ld.addComponentType(type);
}
// Return the type
return type;
}
/**
* This method ensures that a "editArea" {@link ComponentType} has
* been defined so that it can be used implicitly.
*/
private ComponentType ensureEditAreaType(LayoutElement elt) {
// See if it is defined
LayoutDefinition ld = elt.getLayoutDefinition();
ComponentType type = null;
try {
type = getComponentType(elt, EDIT_AREA_TYPE);
} catch (IllegalArgumentException ex) {
// Nope, define it...
type = new ComponentType(EDIT_AREA_TYPE, EDIT_AREA_TYPE_CLASS);
ld.addComponentType(type);
}
// Return the type
return type;
}
/**
* This method ensures that a "markup" {@link ComponentType} has been
* defined so that it can be used implicitly.
*/
private ComponentType ensureMarkupType(LayoutElement elt) {
// See if it is defined
LayoutDefinition ld = elt.getLayoutDefinition();
ComponentType type = null;
try {
type = getComponentType(elt, MARKUP_ELEMENT);
} catch (IllegalArgumentException ex) {
// Nope, define it...
type = new ComponentType(MARKUP_ELEMENT, MARKUP_FACTORY_CLASS);
ld.addComponentType(type);
}
// Return the type
return type;
}
/**
* This method adds an option to the given {@link LayoutComponent}
* based on the information in the given {@link #OPTION_ELEMENT}
* Node
.
*
* @param component The {@link LayoutComponent}.
* @param node The {@link #OPTION_ELEMENT} Node
.
*/
private void addOption(LayoutComponent component, Node node) {
// Pull off the attributes
Map attributes = getAttributes(node);
// Get the name
String name = attributes.get(NAME_ATTRIBUTE);
if ((name == null) || (name.trim().equals(""))) {
throw new RuntimeException("'" + NAME_ATTRIBUTE
+ "' attribute not found on '" + OPTION_ELEMENT
+ "' Element!");
}
name = name.trim();
// Get the value
Object value = getValueFromNode(node, attributes);
// Add the option to the component (value may be null)
component.addOption(name, value);
}
/**
* This method reads obtains the {@link #VALUE_ATTRIBUTE} from the
* given node, or from the child {@link #LIST_ELEMENT} element. If
* neither are provided, (null)
is returned. The
* attribute takes precedence over the child {@link #LIST_ELEMENT}
* element.
*
* @param node Node
containing the value attribute
* or {@link #LIST_ELEMENT}
* @param attributes Map
of attributes which may contain
* {@link #VALUE_ATTRIBUTE}
*
* @return The value (as a String
or List
), or
* (null)
if not specified.
*/
private Object getValueFromNode(Node node, Map attributes) {
Object value = attributes.get(VALUE_ATTRIBUTE);
if (value == null) {
// The value attribute may be null if multiple values are supplied.
// Walk children (we only care about LIST_ELEMENT)
List list = new ArrayList();
Iterator it = getChildElements(node, LIST_ELEMENT).iterator();
while (it.hasNext()) {
// Add a value to the List
list.add(getAttributes(it.next()).get(VALUE_ATTRIBUTE));
}
if (list.size() > 0) {
// Only use the list if it has values
value = list;
}
}
return value;
}
/**
*
* @param node The {@link #STATIC_TEXT_ELEMENT} node to extract
* information from when creating the
* {@link LayoutStaticText}.
*/
private LayoutElement createLayoutStaticText(LayoutElement parent, Node node) {
// Create new LayoutComponent
LayoutStaticText text =
new LayoutStaticText(parent, "", getTextNodesAsString(node));
// Add all the attributes from the static text as options
// component.addOptions(getAttributes(node));
// Add escape... FIXME
// Return the LayoutStaticText
return text;
}
//////////////////////////////////////////////////////////////////////
// Utility Methods
//////////////////////////////////////////////////////////////////////
/**
* This method returns a List
of all child
* Element
s below the given Node
.
*
* @param node The Node
to pull child elements from.
*
* @return List
of child Element
s found below
* the given Node
.
*/
public List getChildElements(Node node) {
return getChildElements(node, null);
}
/**
* This method returns a List of all child Elements below the given
* Node matching the given name. If name equals null, all Elements
* below this node will be returned.
*
* @param node The node to pull child elements from.
* @param name The name of the Elements to return.
*
* @return List of child elements found below the given node matching
* the name (if provided).
*/
public List getChildElements(Node node, String name) {
// Get the child nodes
NodeList nodes = node.getChildNodes();
if (nodes == null) {
// No children, just return an empty List
return new ArrayList(0);
}
// Create a new List to store the child Elements
List list = new ArrayList();
// Add all the child Elements to the List
Node childNode = null;
for (int idx = 0; idx < nodes.getLength(); idx++) {
childNode = nodes.item(idx);
if (childNode.getNodeType() != Node.ELEMENT_NODE) {
// Skip TEXT_NODE and other Node types
continue;
}
// Add to the list if name is null, or it matches the node name
if ((name == null) || childNode.getNodeName().equalsIgnoreCase(name)) {
list.add(childNode);
}
}
// Return the list of Elements
return list;
}
/**
* This method returns the String
representation of all
* the Node.TEXT_NODE
nodes that are children of the
* given Node
.
*
* @param node The Node
to pull child
* Element
s from.
*
* @return The String
representation of all the
* Node.TEXT_NODE
type nodes under the given
* Node
.
*/
public String getTextNodesAsString(Node node) {
// Get the child nodes
NodeList nodes = node.getChildNodes();
if (nodes == null) {
// No children, return null
return null;
}
// Create a StringBuffer
StringBuffer buf = new StringBuffer("");
// Add all the child Element values to the StringBuffer
Node childNode = null;
for (int idx = 0; idx < nodes.getLength(); idx++) {
childNode = nodes.item(idx);
if ((childNode.getNodeType() != Node.TEXT_NODE)
&& (childNode.getNodeType() != Node.CDATA_SECTION_NODE)) {
// Skip all other Node types
continue;
}
buf.append(childNode.getNodeValue());
}
// Return the String
return buf.toString();
}
/**
*
This method returns a Map
of all attributes for the
* given Node
. Each attribute name will be stored in the
* Map
in lower case so case can be ignored.
*
* @param node The node to pull attributes from.
*
* @return Map
of attributes found on the given
* Node
.
*/
public Map getAttributes(Node node) {
// Get the attributes
NamedNodeMap attributes = node.getAttributes();
if ((attributes == null) || (attributes.getLength() == 0)) {
// No attributes, just return an empty Map
return new HashMap(0);
}
// Create a Map to contain the attributes
Map map = new HashMap();
// Add all the attributes to the Map
Node attNode = null;
for (int idx = 0; idx < attributes.getLength(); idx++) {
attNode = attributes.item(idx);
map.put(attNode.getNodeName().toLowerCase(),
attNode.getNodeValue());
}
// Return the map
return map;
}
/**
* This utility method returns the requested {@link ComponentType}.
* If it is not found, it throws an
* IllegalArgumentException
.
*
* @param elt A {@link LayoutElement} whose root is a
* {@link LayoutDefinition}.
* @param type The String
type to lookup.
*
* @return The {@link ComponentType}.
*/
public ComponentType getComponentType(LayoutElement elt, String type) {
// Find the ComponentType
ComponentType compType =
elt.getLayoutDefinition().getComponentType(type);
if (compType == null) {
// Check global component types (defined via @annotations). This
// is now the preferred way to define types, however, locally
// defined types should have precedence
compType = LayoutDefinitionManager.
getGlobalComponentType(null, type);
if (compType == null) {
throw new IllegalArgumentException("ComponentType '" + type
+ "' not defined!");
}
}
return compType;
}
//////////////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////////////
public static final String ATTRIBUTE_ELEMENT =
"attribute";
public static final String COMPONENT_ELEMENT =
"component";
public static final String COMPONENT_TYPE_ELEMENT =
"componenttype";
public static final String EDIT_ELEMENT =
"edit";
public static final String EVENT_ELEMENT =
"event";
public static final String FACET_ELEMENT =
"facet";
public static final String FOREACH_ELEMENT =
"foreach";
public static final String HANDLER_ELEMENT =
"handler";
public static final String HANDLERS_ELEMENT =
"handlers";
public static final String HANDLER_DEFINITION_ELEMENT =
"handlerdefinition";
public static final String IF_ELEMENT =
"if";
public static final String INPUT_DEF_ELEMENT =
"inputdef";
public static final String INPUT_ELEMENT =
"input";
public static final String LAYOUT_DEFINITION_ELEMENT =
"layoutdefinition";
public static final String LAYOUT_ELEMENT =
"layout";
public static final String LIST_ELEMENT =
"list";
public static final String MARKUP_ELEMENT =
"markup";
public static final String OPTION_ELEMENT =
"option";
public static final String OUTPUT_DEF_ELEMENT =
"outputdef";
public static final String OUTPUT_MAPPING_ELEMENT =
"outputmapping";
public static final String STATIC_TEXT_ELEMENT =
"statictext";
public static final String TYPES_ELEMENT =
"types";
public static final String RESOURCES_ELEMENT =
"resources";
public static final String RESOURCE_ELEMENT =
"resource";
public static final String WHILE_ELEMENT =
"while";
public static final String CLASS_NAME_ATTRIBUTE =
"classname";
public static final String CONDITION_ATTRIBUTE =
"condition";
public static final String DEFAULT_ATTRIBUTE =
"default";
public static final String DESCRIPTION_ATTRIBUTE =
"description";
public static final String EXTRA_INFO_ATTRIBUTE =
"extrainfo";
public static final String FACTORY_CLASS_ATTRIBUTE =
"factoryclass";
public static final String ID_ATTRIBUTE =
"id";
public static final String KEY_ATTRIBUTE =
"key";
public static final String LIST_ATTRIBUTE =
"list";
public static final String METHOD_NAME_ATTRIBUTE =
"methodname";
public static final String NAME_ATTRIBUTE =
"name";
public static final String OUTPUT_NAME_ATTRIBUTE =
"outputname";
public static final String OVERWRITE_ATTRIBUTE =
"overwrite";
public static final String PROPERTY_ATTRIBUTE =
"property";
public static final String RENDERED_ATTRIBUTE =
"rendered";
public static final String REQUIRED_ATTRIBUTE =
"required";
public static final String TAG_ATTRIBUTE =
"tag";
public static final String TARGET_KEY_ATTRIBUTE =
"targetkey";
public static final String TARGET_TYPE_ATTRIBUTE =
"targettype";
public static final String TYPE_ATTRIBUTE =
"type";
public static final String VALUE_ATTRIBUTE =
"value";
public static final String AUTO_RENDERED =
"auto";
public static final String EDITABLE =
"editableContent";
public static final String EDIT_MENU =
"editMenu";
public static final String EDIT_AREA_TYPE =
"editArea";
public static final String POPUP_MENU_TYPE =
"popupMenu";
public static final String EDIT_AREA_TYPE_CLASS =
"com.sun.jsftemplating.component.factory.basic.EditAreaFactory";
public static final String MARKUP_FACTORY_CLASS =
"com.sun.jsftemplating.component.factory.basic.MarkupFactory";
public static final String POPUP_MENU_TYPE_CLASS =
"com.sun.jsftemplating.component.factory.basic.PopupMenuFactory";
/**
* This is used to set the "value" option for static text fields.
*/
// public static final String VALUE_OPTION = "value";
private URL _url = null;
private EntityResolver _entityResolver = null;
private ErrorHandler _errorHandler = null;
private String _baseURI = null;
private Map _handlerDefs =
new HashMap();
private int _markupCount = 1;
}