⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractbeanwriter.java

📁 JAVA 文章管理系统源码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*
 * 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.io;

import java.beans.IntrospectionException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.commons.betwixt.AttributeDescriptor;
import org.apache.commons.betwixt.BindingConfiguration;
import org.apache.commons.betwixt.Descriptor;
import org.apache.commons.betwixt.ElementDescriptor;
import org.apache.commons.betwixt.XMLBeanInfo;
import org.apache.commons.betwixt.XMLIntrospector;
import org.apache.commons.betwixt.digester.XMLIntrospectorHelper;
import org.apache.commons.betwixt.expression.Context;
import org.apache.commons.betwixt.expression.Expression;
import org.apache.commons.betwixt.io.id.SequentialIDGenerator;
import org.apache.commons.collections.ArrayStack;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

// FIX ME!!!
// Logging logic!

// FIX ME!!
// Error handling strategy!
// i'm going to add SAXExceptions everywhere since it's the easiest way to make things work quick
// but this is a poor strategy

/**
  * <p>Abstract superclass for bean writers.
  * This class encapsulates the processing logic. 
  * Subclasses provide implementations for the actual expression of the xml.</p>
  * <h5>SAX Inspired Writing API</h5>
  * <p>
  * This class is intended to be used by subclassing: 
  * concrete subclasses perform the actual writing by providing
  * suitable implementations for the following methods inspired 
  * by <a href='http://www.saxproject.org'>SAX</a>:
  * </p>
  * <ul>
  *     <li> {@link #start} - called when processing begins</li>
  *     <li> {@link #startElement(WriteContext, String, String, String, Attributes)} 
  *     - called when the start of an element 
  *     should be written</li> 
  *     <li> {@link #bodyText(WriteContext, String)} 
  *     - called when the start of an element 
  *     should be written</li> 
  *     <li> {@link #endElement(WriteContext, String, String, String)} 
  *     - called when the end of an element 
  *     should be written</li> 
  *     <li> {@link #end} - called when processing has been completed</li>
  * </ul>
  * <p>
  * <strong>Note</strong> that this class contains many deprecated 
  * versions of the writing API. These will be removed soon so care
  * should be taken to use the latest version.
  * </p>
  * <p>
  * <strong>Note</strong> that this class is designed to be used
  * in a single threaded environment. When used in multi-threaded
  * environments, use of a common <code>XMLIntrospector</code>
  * and pooled writer instances should be considered. 
  * </p>
  *
  * @author <a href="mailto:rdonkin@apache.org">Robert Burrell Donkin</a>
  */
public abstract class AbstractBeanWriter {

    /** Introspector used */
    private XMLIntrospector introspector = new XMLIntrospector();

    /** Log used for logging (Doh!) */
    private Log log = LogFactory.getLog( AbstractBeanWriter.class );
    /** Map containing ID attribute values for beans */
    private HashMap idMap = new HashMap();
    /** Stack containing beans - used to detect cycles */
    private ArrayStack beanStack = new ArrayStack();
    /** Used to generate ID attribute values*/
    private IDGenerator idGenerator = new SequentialIDGenerator();
    /** Should empty elements be written out? */
    private boolean writeEmptyElements = true;
    /** Dynamic binding configuration settings */
    private BindingConfiguration bindingConfiguration = new BindingConfiguration();
    /** <code>WriteContext</code> implementation reused curing writing */
    private WriteContextImpl writeContext = new WriteContextImpl();
    /** Collection of namespaces which have already been declared */
    private Collection namespacesDeclared = new ArrayList();
    
    /**
     * Marks the start of the bean writing.
     * By default doesn't do anything, but can be used
     * to do extra start processing 
     * @throws IOException if an IO problem occurs during writing 
     * @throws SAXException if an SAX problem occurs during writing 
     */
    public void start() throws IOException, SAXException {
    }
    
    /**
     * Marks the start of the bean writing.
     * By default doesn't do anything, but can be used
     * to do extra end processing 
     * @throws IOException if an IO problem occurs during writing
     * @throws SAXException if an SAX problem occurs during writing 
     */
    
    public void end() throws IOException, SAXException {
    }
        
    /** 
     * <p> Writes the given bean to the current stream using the XML introspector.</p>
     * 
     * <p> This writes an xml fragment representing the bean to the current stream.</p>
     *
     * <p>This method will throw a <code>CyclicReferenceException</code> when a cycle
     * is encountered in the graph <strong>only</strong> if the <code>getMapIDs()</code>
     * setting of the </code>BindingConfiguration</code> is false.</p>
     *
     * @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 
     *
     * @param bean write out representation of this bean
     */
    public void write(Object bean) throws 
                                        IOException, 
                                        SAXException, 
                                        IntrospectionException {
        if (log.isDebugEnabled()) {
            log.debug( "Writing bean graph..." );
            log.debug( bean );
        }
        start();
        writeBean( null, null, null, bean, makeContext( bean ) );
        end();
        if (log.isDebugEnabled()) {
            log.debug( "Finished writing bean graph." );
        }
    }
    
    /** 
     * <p>Writes the given bean to the current stream 
     * using the given <code>qualifiedName</code>.</p>
     *
     * <p>This method will throw a <code>CyclicReferenceException</code> when a cycle
     * is encountered in the graph <strong>only</strong> if the <code>getMapIDs()</code>
     * setting of the <code>BindingConfiguration</code> is false.</p>
     *
     * @param qualifiedName the string naming root element
     * @param bean the <code>Object</code> to write out as xml
     * 
     * @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
     */
    public void write(
                String qualifiedName, 
                Object bean) 
                    throws 
                        IOException, 
                        SAXException,
                        IntrospectionException {
        start();
        writeBean( "", qualifiedName, qualifiedName, bean, makeContext( bean ) );
        end();
    }
    
    /** 
     * <p>Writes the given bean to the current stream 
     * using the given <code>qualifiedName</code>.</p>
     *
     * <p>This method will throw a <code>CyclicReferenceException</code> when a cycle
     * is encountered in the graph <strong>only</strong> if the <code>getMapIDs()</code>
     * setting of the <code>BindingConfiguration</code> is false.</p>
     *
     * @param namespaceUri the namespace uri
     * @param localName the local name
     * @param qualifiedName the string naming root element
     * @param bean the <code>Object</code> to write out as xml
     * @param context not null
     * 
     * @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 writeBean (
                String namespaceUri,
                String localName,
                String qualifiedName, 
                Object bean,
                Context context) 
                    throws 
                        IOException, 
                        SAXException,
                        IntrospectionException {                    
        
        if ( log.isTraceEnabled() ) {
            log.trace( "Writing bean graph (qualified name '" + qualifiedName + "'" );
        }
        
        // introspect to obtain bean info
        XMLBeanInfo beanInfo = introspector.introspect( bean );
        if ( beanInfo != null ) {
            ElementDescriptor elementDescriptor = beanInfo.getElementDescriptor();
            if ( elementDescriptor != null ) {
                context = context.newContext( bean );
                if ( qualifiedName == null ) {
                    qualifiedName = elementDescriptor.getQualifiedName();
                }
                if ( namespaceUri == null ) {
                    namespaceUri = elementDescriptor.getURI();
                }
                if ( localName == null ) {
                    localName = elementDescriptor.getLocalName();
                }

                String ref = null;
                String id = null;
                
                // simple type should not have IDs
                if ( elementDescriptor.isSimple() ) {
                    // write without an id
                    writeElement( 
                        namespaceUri,
                        localName,
                        qualifiedName, 
                        elementDescriptor, 
                        context );
                        
                } else {
                    pushBean ( context.getBean() );
                    if ( getBindingConfiguration().getMapIDs() ) {
                        ref = (String) idMap.get( context.getBean() );
                    }
                    if ( ref == null ) {
                        // this is the first time that this bean has be written
                        AttributeDescriptor idAttribute = beanInfo.getIDAttribute();
                        if (idAttribute == null) {
                            // use a generated id
                            id = idGenerator.nextId();
                            idMap.put( bean, id );
                            
                            if ( getBindingConfiguration().getMapIDs() ) {
                                // write element with id
                                writeElement(
                                    namespaceUri,
                                    localName,
                                    qualifiedName, 
                                    elementDescriptor, 
                                    context , 
                                    beanInfo.getIDAttributeName(),
                                    id);
                                    
                            } else {    
                                // write element without ID
                                writeElement( 
                                    namespaceUri,
                                    localName,
                                    qualifiedName, 
                                    elementDescriptor, 
                                    context );
                            }
                                                        
                        } else {
                            // use id from bean property
                            // it's up to the user to ensure uniqueness
                            // XXX should we trap nulls?
                            Object exp = idAttribute.getTextExpression().evaluate( context );
                            if (exp == null) {
                                // we'll use a random id
                                log.debug("Using random id");
                                id = idGenerator.nextId();
                                
                            } else {
                                // convert to string
                                id = exp.toString();
                            }
                            idMap.put( bean, id);
                            
                            // the ID attribute should be written automatically
                            writeElement( 
                                namespaceUri,
                                localName,
                                qualifiedName, 
                                elementDescriptor, 
                                context );
                        }
                    } else {
                        
                        if ( !ignoreElement( elementDescriptor, context )) {
                            // we've already written this bean so write an IDREF
                            writeIDREFElement( 
                                            elementDescriptor,
                                            namespaceUri,
                                            localName,
                                            qualifiedName,  
                                            beanInfo.getIDREFAttributeName(), 
                                            ref);
                        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -