📄 elementdescriptor.java
字号:
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.betwixt;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.betwixt.digester.XMLIntrospectorHelper;
import org.apache.commons.betwixt.expression.Expression;
/** <p><code>ElementDescriptor</code> describes the XML elements
* to be created for a bean instance.</p>
*
* <p> It contains <code>AttributeDescriptor</code>'s for all it's attributes
* and <code>ElementDescriptor</code>'s for it's child elements.
*
* @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
* @author <a href="mailto:martin@mvdb.net">Martin van den Bemt</a>
*/
public class ElementDescriptor extends NodeDescriptor {
/**
* Descriptors for attributes this element contains.
* <strong>Note:</strong> Constructed lazily on demand from a List.
* {@link #getAttributeDescriptor()} should be called rather than accessing this
* field directly.
*/
private AttributeDescriptor[] attributeDescriptors;
/**
* Descriptors for child elements.
* <strong>Note:</strong> Constructed lazily on demand from a List.
* {@link #getElementDescriptor()} should be called rather than accessing this
* field directly.
*/
private ElementDescriptor[] elementDescriptors;
/**
* Descriptors for child content.
* <strong>Note:</strong> Constructed lazily on demand from a List.
* {@link #getContentDescriptor()} should be called rather than accessing this
* field directly.
*/
private Descriptor[] contentDescriptors;
/**
* The List used on construction. It will be GC'd
* after initilization and the array is lazily constructed
*/
private List attributeList;
/**
* The List used on construction. It will be GC'd
* after initilization and the array is lazily constructed
*/
private List elementList;
/**
* The list used o construct array. It will be GC'd after
* initialization when the array is lazily constructed.
*/
private List contentList;
/** the expression used to evaluate the new context of this node
* or null if the same context is to be used */
private Expression contextExpression;
/** Whether this element refers to a primitive type (or property of a parent object) */
private boolean primitiveType;
/**
* Is this element hollow?
* In other words, is this descriptor a place holder indicating the name
* and update for a root ElementDescriptor for this type obtained by introspection
* TODO: this would probably be better modeled as a separate subclass
*/
private boolean isHollow = false;
/**
* Whether this collection element can be used
* as a collection element. Defaults to true
*/
private boolean wrapCollectionsInElement = true;
/** specifies a separate implementation class that should be instantiated
* when reading beans
* or null if there is no separate implementation */
private Class implementationClass = null;
/**
* Constructs an <code>ElementDescriptor</code> that refers to a primitive type.
*/
public ElementDescriptor() {
}
/**
* Base constructor.
* @param primitiveType if true, this element refers to a primitive type
* @deprecated 0.6 PrimitiveType property has been removed
*/
public ElementDescriptor(boolean primitiveType) {
this.primitiveType = primitiveType;
}
/**
* Creates a ElementDescriptor with no namespace URI or prefix.
*
* @param localName the (xml) local name of this node.
* This will be used to set both qualified and local name for this name.
*/
public ElementDescriptor(String localName) {
super( localName );
}
/**
* Creates a <code>ElementDescriptor</code> with namespace URI and qualified name
* @param localName the (xml) local name of this node
* @param qualifiedName the (xml) qualified name of this node
* @param uri the (xml) namespace prefix of this node
*/
public ElementDescriptor(String localName, String qualifiedName, String uri) {
super(localName, qualifiedName, uri);
}
/**
* Returns true if this element has child <code>ElementDescriptors</code>
* @return true if this element has child elements
* @see #getElementDescriptors
*/
public boolean hasChildren() {
return getElementDescriptors().length > 0;
}
/**
* Returns true if this element has <code>AttributeDescriptors</code>
* @return true if this element has attributes
* @see #getAttributeDescriptors
*/
public boolean hasAttributes() {
return getAttributeDescriptors().length > 0;
}
/**
* Returns true if this element has child content.
* @return true if this element has either child mixed content or child elements
* @see #getContentDescriptors
* @since 0.5
*/
public boolean hasContent() {
return getContentDescriptors().length > 0;
}
/**
* Is this a simple element?
* A simple element is one without child elements or attributes.
* This corresponds to the simple type concept used in XML Schema.
* TODO: need to consider whether it's sufficient to calculate
* which are simple types (and so don't get IDs assigned etc)
* @return true if it is a <code>SimpleType</code> element
*/
public boolean isSimple() {
return !(hasAttributes()) && !(hasChildren());
}
/**
* Sets whether <code>Collection</code> bean properties should wrap items in a parent element.
* In other words, should the mapping for bean properties which are <code>Collection</code>s
* enclosed the item elements within a parent element.
* Normally only used when this describes a collection bean property.
*
* @param wrapCollectionsInElement true if the elements for the items in the collection
* should be contained in a parent element
* @deprecated 0.6 moved to a declarative style of descriptors where the alrogithmic should
* be done during introspection
*/
public void setWrapCollectionsInElement(boolean wrapCollectionsInElement) {
this.wrapCollectionsInElement = wrapCollectionsInElement;
}
/**
* Returns true if collective bean properties should wrap the items in a parent element.
* In other words, should the mapping for bean properties which are <code>Collection</code>s
* enclosed the item elements within a parent element.
* Normally only used when this describes a collection bean property.
*
* @return true if the elements for the items in the collection should be contained
* in a parent element
* @deprecated 0.6 moved to a declarative style of descriptors where the alrogithmic should
* be done during introspection
*/
public boolean isWrapCollectionsInElement() {
return this.wrapCollectionsInElement;
}
/**
* Adds an attribute to the element this <code>ElementDescriptor</code> describes
* @param descriptor the <code>AttributeDescriptor</code> that will be added to the
* attributes associated with element this <code>ElementDescriptor</code> describes
*/
public void addAttributeDescriptor(AttributeDescriptor descriptor) {
if ( attributeList == null ) {
attributeList = new ArrayList();
}
getAttributeList().add( descriptor );
attributeDescriptors = null;
}
/**
* Returns the attribute descriptors for this element
*
* @return descriptors for the attributes of the element that this
* <code>ElementDescriptor</code> describes
*/
public AttributeDescriptor[] getAttributeDescriptors() {
if ( attributeDescriptors == null ) {
if ( attributeList == null ) {
attributeDescriptors = new AttributeDescriptor[0];
} else {
attributeDescriptors = new AttributeDescriptor[ attributeList.size() ];
attributeList.toArray( attributeDescriptors );
// allow GC of List when initialized
attributeList = null;
}
}
return attributeDescriptors;
}
/**
* Sets the <code>AttributesDescriptors</code> for this element.
* This sets descriptors for the attributes of the element describe by the
* <code>ElementDescriptor</code>.
*
* @param attributeDescriptors the <code>AttributeDescriptor</code> describe the attributes
* of the element described by this <code>ElementDescriptor</code>
*/
public void setAttributeDescriptors(AttributeDescriptor[] attributeDescriptors) {
this.attributeDescriptors = attributeDescriptors;
this.attributeList = null;
}
/**
* Adds a descriptor for a child element.
*
* @param descriptor the <code>ElementDescriptor</code> describing the child element to add
*/
public void addElementDescriptor(ElementDescriptor descriptor) {
if ( elementList == null ) {
elementList = new ArrayList();
}
getElementList().add( descriptor );
elementDescriptors = null;
addContentDescriptor( descriptor );
}
/**
* Returns descriptors for the child elements of the element this describes.
* @return the <code>ElementDescriptor</code> describing the child elements
* of the element that this <code>ElementDescriptor</code> describes
*/
public ElementDescriptor[] getElementDescriptors() {
if ( elementDescriptors == null ) {
if ( elementList == null ) {
elementDescriptors = new ElementDescriptor[0];
} else {
elementDescriptors = new ElementDescriptor[ elementList.size() ];
elementList.toArray( elementDescriptors );
// allow GC of List when initialized
elementList = null;
}
}
return elementDescriptors;
}
/**
* Gets a child ElementDescriptor matching the given name if one exists.
* Note that (so long as there are no better matches), a null name
* acts as a wildcard. In other words, an
* <code>ElementDescriptor</code> the first descriptor
* with a null name will match any name
* passed in, unless some other matches the name exactly.
*
* @param name the localname to be matched, not null
* @returns the child ElementDescriptor with the given name if one exists,
* otherwise null
*/
public ElementDescriptor getElementDescriptor(String name) {
ElementDescriptor elementDescriptor = null;
ElementDescriptor descriptorWithNullName = null;
ElementDescriptor[] elementDescriptors = getElementDescriptors();
for (int i=0, size=elementDescriptors.length; i<size; i++) {
String elementName = elementDescriptors[i].getQualifiedName();
if (name.equals(elementName)) {
elementDescriptor = elementDescriptors[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -