
org.enhydra.xml.xmlc.compiler.ElementInfo Maven / Gradle / Ivy
The newest version!
/*
* Enhydra Java Application Server Project
*
* The contents of this file are subject to the Enhydra Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License on
* the Enhydra web site ( http://www.enhydra.org/ ).
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific terms governing rights and limitations
* under the License.
*
* The Initial Developer of the Enhydra Application Server is Lutris
* Technologies, Inc. The Enhydra Application Server and portions created
* by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
* All Rights Reserved.
*
* Contributor(s):
*
* $Id: ElementInfo.java,v 1.5 2005/11/19 21:30:41 jkjome Exp $
*/
package org.enhydra.xml.xmlc.compiler;
import org.enhydra.xml.xmlc.codegen.JavaLang;
import org.enhydra.xml.xmlc.dom.XMLCDocument;
import org.enhydra.xml.xmlc.metadata.DocumentClass;
import org.enhydra.xml.xmlc.metadata.MetaData;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.html.HTMLElement;
//FIXME: this is designed to evolve forward to something that provides
//information taken from both the DOM and metadata.
//FIXME: Maybe really need a clientdata instead of adjust size & buildMethodFlags.
//FIXME: are sizes still needed??
// jrk_20040703 - I think the setText fixme is solved (see comment in the constructor
// for details), but leaving the note here for posterity.
//FIXME: `accessor' terminology is broken; sometimes accessor includes
// setText and sometimes it doesn.
/**
* Information about a particular Element. Several fields are also
* kept for code generators, although this is not do in a general
* way.
*/
public final class ElementInfo {
/**
* Information about an accessor method (getElementXXX, getTagXXX) to
* create for this element.
*/
public class AccessorInfo {
/** Name of the method to create */
public final String fName;
/** Return type of accessor */
public final String fReturnType;
/**
* Constructor.
*/
public AccessorInfo(String name,
String returnType) {
fName = name;
fReturnType = returnType;
}
}
/**
* Container for DOM.
*/
private XMLCDocument fXmlcDoc;
/**
* The element this object is associated with.
*/
private Element fElement;
/**
* The interface or class name to use in referencing the element.
*/
private String fReferenceName;
/**
* The XML id for the element (value of the id field).
*/
private String fXmlId;
/**
* The java id for element. Will be null if a valid Java id could not
* be formed.
*/
private String fJavaId;
/**
* List of accessors to create, or null if none.
*/
private AccessorInfo[] fAccessorInfo;;
/**
* Should a setText method be generated for this element?
*/
private boolean fCreateSetText;
/**
* Size of the element, in nodes, excluding children
*/
private int fNodeSize;
/**
* Size of the subtree of this element, in number of nodes.
*/
private int fSubTreeNodeSize;
/**
* Adjusted size of subtree. This is used by the code generators
* to store a size that is used in optimizing subtree creation.
* Initialized to the subtree node-size.
*/
private int fAdjustedSubTreeNodeSize;
/**
* Constructor.
*/
public ElementInfo(Element element,
int nodeSize,
int subTreeNodeSize,
MetaData metaData,
XMLCDocument xmlcDoc) {
if (element == null) {
throw new IllegalArgumentException("element null");
}
fElement = element;
fNodeSize = nodeSize;
fSubTreeNodeSize = subTreeNodeSize;
fAdjustedSubTreeNodeSize = subTreeNodeSize;
fXmlcDoc = xmlcDoc;
determineIds();
initAccessorInfo(metaData);
// Create setTextXXX() if there is a legal Java id, #PCDATA is in the
// content model and getTagXXX() or getElementXXX() methods also being generated
fCreateSetText = (fJavaId != null && fReferenceName != null)
&& fXmlcDoc.hasPCDataInContentModel(fElement);
//&& (XMLCUtil.findFirstText(fElement) != null); //jrk_20040703 - XMLObjectImpl.doSetText() now creates a text node if it doesn't already exist, so no need to avoid setText*() creation!
}
/**
* Translate the accessor return type from the MetaData to a actual return
* type. They translates various short-cuts to actual class names.
*/
private String getAccessorReturnType(String typeSpec) {
if (typeSpec == null) return null; //expected if getCreateGetTagMethods() is false and getSuppressGetElementMethods() is true, so avoid null pointer exception below
if (typeSpec.equals(DocumentClass.ACCESSOR_TYPE_INTERFACE)) {
return fXmlcDoc.getDomFactory().nodeClassToInterface(fElement);
} else if (typeSpec.equals(DocumentClass.ACCESSOR_TYPE_CLASS)) {
return fElement.getClass().getName();
} else if (typeSpec.equals(DocumentClass.ACCESSOR_TYPE_ELEMENT)) {
return Element.class.getName();
} else if (typeSpec.equals(DocumentClass.ACCESSOR_TYPE_HTML_ELEMENT)) {
return HTMLElement.class.getName();
} else {
return typeSpec;
}
}
/**
* Initialize the information of the accessors to create.
*/
private void initAccessorInfo(MetaData metaData) {
boolean createGetElement = (fJavaId != null)
&& !metaData.getDocumentClass().getSuppressGetElementMethods();
boolean createGetTag = (fJavaId != null)
&& metaData.getDocumentClass().getCreateGetTagMethods();
int numAccessors = (createGetElement ? 1 : 0)
+ (createGetTag ? 1 : 0);
if (numAccessors == 0) {
return;
}
fAccessorInfo = new AccessorInfo[numAccessors];
int idx = 0;
fReferenceName = metaData.getDocumentClass().getGetTagReturnType();
if (createGetElement) {
fReferenceName =
fXmlcDoc.getDomFactory().nodeClassToInterface(fElement);
fAccessorInfo[idx++]
= new AccessorInfo("getElement" + fJavaId, fReferenceName);
}
if (createGetTag) {
fAccessorInfo[idx++]
= new AccessorInfo("getTag" + fJavaId,
getAccessorReturnType(metaData.getDocumentClass().getGetTagReturnType()));
}
}
/**
* Adjust an element id to conform to the Java naming convention.
* Upshifts the first character.
*/
private String adjustElementId(String id) {
return id.substring(0, 1).toUpperCase() + id.substring(1);
}
/**
* Determine the XML and Java ids for the element.
*/
private void determineIds() {
// Get id attribute
String idAttrName = fXmlcDoc.getIdAttrName(fElement);
if (idAttrName != null) {
Attr idAttr = fElement.getAttributeNode(idAttrName);
if (idAttr != null) {
fXmlId = idAttr.getNodeValue();
if (JavaLang.legalJavaIdentifier(fXmlId)) {
fJavaId = adjustElementId(fXmlId);
}
}
}
}
/**
* Get the element.
*/
public Element getElement() {
return fElement;
}
/**
* Get the Java class name of the element.
*/
public String getClassName() {
return fElement.getClass().getName();
}
/**
* Get the reference name for this element. In general, this is
* the name of the return type for the "getElementXXX()" accessor.
*/
public String getReferenceName() {
return getAccessorReturnType(fReferenceName);
}
/**
* Get the XML id, or null if there isn't one.
*/
public String getXmlId() {
return fXmlId;
}
/**
* Get the Java id, or null if there isn't one.
*/
public String getJavaId() {
return fJavaId;
}
/**
* Get the element class (attribute) names
*/
public String[] getElementClassNames() {
return fXmlcDoc.getElementClassNames(fElement);
}
/**
* Get the element name (name attribute in HTML).
*/
public String getElementName() {
return fXmlcDoc.getElementName(fElement);
}
/**
* Is the element id an invalid Java identifier?
*/
public boolean hasInvalidJavaId() {
return (fXmlId != null) && (fJavaId == null);
}
/**
* Get the total number of access methods for this element.
*/
public int getNumAccessMethods() {
return ((fAccessorInfo != null) ? fAccessorInfo.length : 0)
+ (fCreateSetText ? 1 : 0);
}
/**
* Get the list of accessors to create.
*/
public AccessorInfo[] getAccessors() {
return fAccessorInfo;
}
/**
* Should a setText method be generated for this element?
*/
public boolean createSetText() {
return fCreateSetText;
}
/*
* Get the size of the element, in nodes. This includes the element
* itself, and attributes and their descendents, but not children.
*/
public int getNodeSize() {
return fNodeSize;
}
/*
* Get the size of the subtree, in nodes, rooted at this element.
*/
public int getSubTreeNodeSize() {
return fSubTreeNodeSize;
}
/*
* Get the adjusted size of the subtree. This value is initially
* the same as the subtree node-size, but can be adjusted by a
* code generator for it's own purposes.
*/
public int getAdjustedSubTreeNodeSize() {
return fAdjustedSubTreeNodeSize;
}
/*
* Set the adjusted size of the subtree.
*/
public void setAdjustedSubTreeNodeSize(int size) {
fAdjustedSubTreeNodeSize = size;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy