📄 abstractbeanwriter.java
字号:
}
}
/**
* Adds namespace declarations (if any are needed) to the given attributes.
* @param attributes Attributes, not null
* @param elementNamespaceUri the URI for the enclosing element, possibly null
* @return Attributes, not null
*/
private Attributes addNamespaceDeclarations(Attributes attributes, String elementNamespaceUri) {
Attributes result = attributes;
AttributesImpl withDeclarations = null;
for (int i=-1, size=attributes.getLength(); i<size ; i++) {
String uri = null;
if (i == -1) {
uri = elementNamespaceUri;
} else {
uri = attributes.getURI(i);
}
if (uri != null && !"".equals(uri) && !namespacesDeclared.contains(uri)) {
if (withDeclarations == null) {
withDeclarations = new AttributesImpl(attributes);
}
withDeclarations.addAttribute("", "", "xmlns:"
+ getXMLIntrospector().getConfiguration().getPrefixMapper().getPrefix(uri), "NOTATION", uri);
namespacesDeclared.add(uri);
}
}
if (withDeclarations != null) {
result = withDeclarations;
}
return result;
}
/**
* Writes the given element adding an ID attribute
*
* @param namespaceUri the namespace uri
* @param localName the local name
* @param qualifiedName the qualified name
* @param elementDescriptor the ElementDescriptor describing this element
* @param context the context being evaliated against
* @param idAttribute the qualified name of the <code>ID</code> attribute
* @param idValue the value for the <code>ID</code> attribute
* @throws IOException if an IO problem occurs during writing
* @throws SAXException if an SAX problem occurs during writing
* @throws IntrospectionException if a java beans introspection problem occurs
*/
private void writeElement(
String namespaceUri,
String localName,
String qualifiedName,
ElementDescriptor elementDescriptor,
Context context,
String idAttribute,
String idValue )
throws
IOException,
SAXException,
IntrospectionException {
if ( !ignoreElement( elementDescriptor, context ) ) {
writeContext.setCurrentDescriptor(elementDescriptor);
Attributes attributes = new IDElementAttributes(
elementDescriptor,
context,
idAttribute,
idValue );
startElement(
writeContext,
namespaceUri,
localName,
qualifiedName,
addNamespaceDeclarations(attributes, namespaceUri));
writeElementContent( elementDescriptor, context ) ;
writeContext.setCurrentDescriptor(elementDescriptor);
endElement( writeContext, namespaceUri, localName, qualifiedName );
} else if ( log.isTraceEnabled() ) {
log.trace( "Element " + qualifiedName + " is empty." );
}
}
/**
* Write attributes, child elements and element end
*
* @param uri the element namespace uri
* @param localName the local name of the element
* @param qualifiedName the qualified name of the element
* @param elementDescriptor the descriptor for this element
* @param context evaluate against this context
* @throws IOException if an IO problem occurs during writing
* @throws SAXException if an SAX problem occurs during writing
* @throws IntrospectionException if a java beans introspection problem occurs
*/
private void writeRestOfElement(
String uri,
String localName,
String qualifiedName,
ElementDescriptor elementDescriptor,
Context context )
throws
IOException,
SAXException,
IntrospectionException {
writeElementContent( elementDescriptor, context );
}
/**
* Writes an element with a <code>IDREF</code> attribute
*
* @param uri the namespace uri
* @param localName the local name
* @param qualifiedName of the element with <code>IDREF</code> attribute
* @param idrefAttributeName the qualified name of the <code>IDREF</code> attribute
* @param idrefAttributeValue the value for the <code>IDREF</code> attribute
* @throws IOException if an IO problem occurs during writing
* @throws SAXException if an SAX problem occurs during writing
* @throws IntrospectionException if a java beans introspection problem occurs
*/
private void writeIDREFElement(
ElementDescriptor elementDescriptor,
String uri,
String localName,
String qualifiedName,
String idrefAttributeName,
String idrefAttributeValue )
throws
IOException,
SAXException,
IntrospectionException {
// write IDREF element
AttributesImpl attributes = new AttributesImpl();
// XXX for the moment, assign IDREF to default namespace
attributes.addAttribute(
"",
idrefAttributeName,
idrefAttributeName,
"IDREF",
idrefAttributeValue);
writeContext.setCurrentDescriptor(elementDescriptor);
startElement( writeContext, uri, localName, qualifiedName, addNamespaceDeclarations(attributes, uri));
endElement( writeContext, uri, localName, qualifiedName );
}
/**
* Writes the element content.
*
* @param elementDescriptor the <code>ElementDescriptor</code> to write as xml
* @param context the <code>Context</code> to use to evaluate the bean expressions
*
* @throws IOException if an IO problem occurs during writing
* @throws SAXException if an SAX problem occurs during writing
* @throws IntrospectionException if a java beans introspection problem occurs
*/
private void writeElementContent(
ElementDescriptor elementDescriptor,
Context context )
throws
IOException,
SAXException,
IntrospectionException {
writeContext.setCurrentDescriptor( elementDescriptor );
Descriptor[] childDescriptors = elementDescriptor.getContentDescriptors();
if ( childDescriptors != null && childDescriptors.length > 0 ) {
// process child elements
for ( int i = 0, size = childDescriptors.length; i < size; i++ ) {
if (childDescriptors[i] instanceof ElementDescriptor) {
// Element content
ElementDescriptor childDescriptor = (ElementDescriptor) childDescriptors[i];
Context childContext = context;
Expression childExpression = childDescriptor.getContextExpression();
if ( childExpression != null ) {
Object childBean = childExpression.evaluate( context );
if ( childBean != null ) {
String qualifiedName = childDescriptor.getQualifiedName();
String namespaceUri = childDescriptor.getURI();
String localName = childDescriptor.getLocalName();
// XXXX: should we handle nulls better
if ( childBean instanceof Iterator ) {
for ( Iterator iter = (Iterator) childBean; iter.hasNext(); ) {
Object object = iter.next();
if (object == null) {
continue;
}
writeBean(
namespaceUri,
localName,
qualifiedName,
object,
context );
}
} else {
writeBean(
namespaceUri,
localName,
qualifiedName,
childBean,
context );
}
}
} else {
writeElement(
childDescriptor.getURI(),
childDescriptor.getLocalName(),
childDescriptor.getQualifiedName(),
childDescriptor,
childContext );
}
} else {
// Mixed text content
// evaluate the body text
Expression expression = childDescriptors[i].getTextExpression();
if ( expression != null ) {
Object value = expression.evaluate( context );
String text = convertToString(
value,
childDescriptors[i],
context );
if ( text != null && text.length() > 0 ) {;
bodyText( writeContext, text );
}
}
}
}
} else {
// evaluate the body text
Expression expression = elementDescriptor.getTextExpression();
if ( expression != null ) {
Object value = expression.evaluate( context );
String text = convertToString( value, elementDescriptor, context );
if ( text != null && text.length() > 0 ) {
bodyText( writeContext, text );
}
}
}
}
/**
* Pushes the bean onto the ancestry stack.
* If IDs are not being written, then check for cyclic references.
*
* @param bean push this bean onto the ancester stack
*/
protected void pushBean( Object bean ) {
// check that we don't have a cyclic reference when we're not writing IDs
if ( !getBindingConfiguration().getMapIDs() ) {
Iterator it = beanStack.iterator();
while ( it.hasNext() ) {
Object next = it.next();
// use absolute equality rather than equals
// we're only really bothered if objects are actually the same
if ( bean == next ) {
if ( log.isDebugEnabled() ) {
log.debug("Element stack: ");
Iterator debugStack = beanStack.iterator();
while ( debugStack.hasNext() ) {
log.debug(debugStack.next());
}
}
log.error("Cyclic reference at bean: " + bean);
throw new CyclicReferenceException();
}
}
}
if (log.isTraceEnabled()) {
log.trace( "Pushing onto object stack: " + bean );
}
beanStack.push( bean );
}
/**
* Pops the top bean off from the ancestry stack
*
* @return the last object pushed onto the ancester stack
*/
protected Object popBean() {
Object bean = beanStack.pop();
if (log.isTraceEnabled()) {
log.trace( "Popped from object stack: " + bean );
}
return bean;
}
/**
* Should this element (and children) be written out?
*
* @param descriptor the <code>ElementDescriptor</code> to evaluate
* @param context the <code>Context</code> against which the element will be evaluated
* @return true if this element should be written out
*/
private boolean ignoreElement( ElementDescriptor descriptor, Context context ) {
if ( ! getWriteEmptyElements() ) {
return isEmptyElement( descriptor, context );
}
return false;
}
/**
* <p>Will evaluating this element against this context result in an empty element?</p>
*
* <p>An empty element is one that has no attributes, no child elements
* and no body text.
* For example, <code><element/></code> is an empty element but
* <code><element attr='value'/></code> is not.</p>
*
* @param descriptor the <code>ElementDescriptor</code> to evaluate
* @param context the <code>Context</code> against which the element will be evaluated
* @return true if this element is empty on evaluation
*/
private boolean isEmptyElement( ElementDescriptor descriptor, Context context ) {
if ( log.isTraceEnabled() ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -