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

📄 beancreaterule.java

📁 JAVA 文章管理系统源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.betwixt.AttributeDescriptor;
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.MethodUpdater;
import org.apache.commons.betwixt.expression.Updater;
import org.apache.commons.digester.Rule;
import org.apache.commons.digester.Rules;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;

/** <p><code>BeanCreateRule</code> is a Digester Rule for creating beans
  * from the betwixt XML metadata.</p>
  *
  * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  * @author <a href="mailto:martin@mvdb.net">Martin van den Bemt</a>
  * @deprecated 0.5 this Rule does not allowed good integration with other Rules -
  * use {@link BeanRuleSet} instead.
  */
public class BeanCreateRule extends Rule {

    /** Logger */
    private static Log log = LogFactory.getLog( BeanCreateRule.class );
    
    /** 
     * Set log to be used by <code>BeanCreateRule</code> instances 
     * @param aLog the <code>Log</code> implementation for this class to log to
     */
    public static void setLog(Log aLog) {
        log = aLog;
    }
    
    /** The descriptor of this element */
    private ElementDescriptor descriptor;
    /** The Context used when evaluating Updaters */
    private Context context;
    /** Have we added our child rules to the digester? */
    private boolean addedChildren;
    /** In this begin-end loop did we actually create a new bean */
    private boolean createdBean;
    /** The type of the bean to create */
    private Class beanClass;
    /** The prefix added to digester rules */
    private String pathPrefix;
    /** Use id's to match beans? */
    private boolean matchIDs = true;
    /** allows an attribute to be specified to overload the types of beans used */
    private String classNameAttribute = "className";
    
    /**
     * Convenience constructor which uses <code>ID's</code> for matching.
     *
     * @param descriptor the <code>ElementDescriptor</code> describing the element mapped
     * @param beanClass the <code>Class</code> to be created
     * @param pathPrefix the digester style path
     */
    public BeanCreateRule(
                            ElementDescriptor descriptor, 
                            Class beanClass, 
                            String pathPrefix ) {
        this( descriptor, beanClass, pathPrefix, true );
    }
    
    /**
     * Constructor taking a class.
     *
     * @param descriptor the <code>ElementDescriptor</code> describing the element mapped
     * @param beanClass the <code>Class</code> to be created
     * @param pathPrefix the digester style path
     * @param matchIDs should <code>ID</code>/<code>IDREF</code>'s be used for matching
     */
    public BeanCreateRule(
                            ElementDescriptor descriptor, 
                            Class beanClass, 
                            String pathPrefix, 
                            boolean matchIDs ) {
        this( 
                descriptor, 
                beanClass, 
                new Context(), 
                pathPrefix,
                matchIDs);
    }
    
    /**
     * Convenience constructor which uses <code>ID's</code> for matching.
     *
     * @param descriptor the <code>ElementDescriptor</code> describing the element mapped
     * @param beanClass the <code>Class</code> to be created
     */    
    public BeanCreateRule( ElementDescriptor descriptor, Class beanClass ) {
        this( descriptor, beanClass, true );
    }
    
    /** 
     * Constructor uses standard qualified name.
     * 
     * @param descriptor the <code>ElementDescriptor</code> describing the element mapped
     * @param beanClass the <code>Class</code> to be created
     * @param matchIDs should <code>ID</code>/<code>IDREF</code>'s be used for matching
     */
    public BeanCreateRule( ElementDescriptor descriptor, Class beanClass, boolean matchIDs ) {
        this( descriptor, beanClass, descriptor.getQualifiedName() + "/" , matchIDs );
    }
  
    /**
     * Convenience constructor which uses <code>ID's</code> for match.
     *
     * @param descriptor the <code>ElementDescriptor</code> describing the element mapped
     * @param context the <code>Context</code> to be used to evaluate expressions
     * @param pathPrefix the digester path prefix
     */   
    public BeanCreateRule(
                            ElementDescriptor descriptor, 
                            Context context, 
                            String pathPrefix ) {    
        this( descriptor, context, pathPrefix, true );
    }
    
    /**
     * Constructor taking a context.
     *
     * @param descriptor the <code>ElementDescriptor</code> describing the element mapped
     * @param context the <code>Context</code> to be used to evaluate expressions
     * @param pathPrefix the digester path prefix
     * @param matchIDs should <code>ID</code>/<code>IDREF</code>'s be used for matching
     */
    public BeanCreateRule(
                            ElementDescriptor descriptor, 
                            Context context, 
                            String pathPrefix,
                            boolean matchIDs ) {
        this( 
                descriptor, 
                descriptor.getSingularPropertyType(), 
                context, 
                pathPrefix,
                matchIDs );
    }
    
    /**
     * Base constructor (used by other constructors).
     *
     * @param descriptor the <code>ElementDescriptor</code> describing the element mapped
     * @param beanClass the <code>Class</code> of the bean to be created
     * @param context the <code>Context</code> to be used to evaluate expressions
     * @param pathPrefix the digester path prefix
     * @param matchIDs should <code>ID</code>/<code>IDREF</code>'s be used for matching
     */
    private BeanCreateRule(
                            ElementDescriptor descriptor, 
                            Class beanClass,
                            Context context, 
                            String pathPrefix,
                            boolean matchIDs ) {
        this.descriptor = descriptor;        
        this.context = context;
        this.beanClass = beanClass;
        this.pathPrefix = pathPrefix;
        this.matchIDs = matchIDs;
        if (log.isTraceEnabled()) {
            log.trace("Created bean create rule");
            log.trace("Descriptor=" + descriptor);
            log.trace("Class=" + beanClass);
            log.trace("Path prefix=" + pathPrefix);
        }
    }
    
    
        
    // Rule interface
    //-------------------------------------------------------------------------    
    
    /**
     * Process the beginning of this element.
     *
     * @param attributes The attribute list of this element
     */
    public void begin(Attributes attributes) {
        log.debug( "Called with descriptor: " + descriptor 
                    + " propertyType: " + descriptor.getPropertyType() );
        
        if (log.isTraceEnabled()) {
            int attributesLength = attributes.getLength();
            if (attributesLength > 0) {
                log.trace("Attributes:");
            }
            for (int i=0, size=attributesLength; i<size; i++) {
                log.trace("Local:" + attributes.getLocalName(i));
                log.trace("URI:" + attributes.getURI(i));
                log.trace("QName:" + attributes.getQName(i));
            }
        }
        

        
        // XXX: if a single rule instance gets reused and nesting occurs
        // XXX: we should probably use a stack of booleans to test if we created a bean
        // XXX: or let digester take nulls, which would be easier for us ;-)
        createdBean = false;
                
        Object instance = null;
        if ( beanClass != null ) {
            instance = createBean(attributes);
            if ( instance != null ) {
                createdBean = true;

                context.setBean( instance );
                digester.push(instance);
                
        
                // if we are a reference to a type we should lookup the original
                // as this ElementDescriptor will be 'hollow' and have no child attributes/elements.
                // XXX: this should probably be done by the NodeDescriptors...
                ElementDescriptor typeDescriptor = getElementDescriptor( descriptor );
                //ElementDescriptor typeDescriptor = descriptor;
        
                // iterate through all attributes        
                AttributeDescriptor[] attributeDescriptors 
                    = typeDescriptor.getAttributeDescriptors();
                if ( attributeDescriptors != null ) {
                    for ( int i = 0, size = attributeDescriptors.length; i < size; i++ ) {
                        AttributeDescriptor attributeDescriptor = attributeDescriptors[i];
                        
                        // The following isn't really the right way to find the attribute
                        // but it's quite robust.
                        // The idea is that you try both namespace and local name first
                        // and if this returns null try the qName.
                        String value = attributes.getValue( 
                            attributeDescriptor.getURI(),
                            attributeDescriptor.getLocalName() 
                        );
                        
                        if (value == null) {
                            value = attributes.getValue(attributeDescriptor.getQualifiedName());
                        }
                        
                        if (log.isTraceEnabled()) {
                            log.trace("Attr URL:" + attributeDescriptor.getURI());
                            log.trace("Attr LocalName:" + attributeDescriptor.getLocalName() );
                            log.trace(value);
                        }
                        
                        Updater updater = attributeDescriptor.getUpdater();
                        log.trace(updater);
                        if ( updater != null && value != null ) {
                            updater.update( context, value );
                        }
                    }
                }
                
                addChildRules();
                
                // add bean for ID matching
                if ( matchIDs ) {
                    // XXX need to support custom ID attribute names
                    // XXX i have a feeling that the current mechanism might need to change
                    // XXX so i'm leaving this till later
                    String id = attributes.getValue( "id" );
                    if ( id != null ) {
                        getBeansById().put( id, instance );
                    }
                }
            }
        }
    }

    /**
     * Process the end of this element.
     */
    public void end() {
        if ( createdBean ) {
            
            // force any setters of the parent bean to be called for this new bean instance
            Updater updater = descriptor.getUpdater();
            Object instance = context.getBean();

            Object top = digester.pop();
            if (digester.getCount() == 0) {
                context.setBean(null);
            }else{
                context.setBean( digester.peek() );
            }

            if ( updater != null ) {
                if ( log.isDebugEnabled() ) {
                    log.debug( "Calling updater for: " + descriptor + " with: " 
                        + instance + " on bean: " + context.getBean() );
                }
                updater.update( context, instance );
            } else {
                if ( log.isDebugEnabled() ) {
                    log.debug( "No updater for: " + descriptor + " with: " 
                        + instance + " on bean: " + context.getBean() );
                }
            }

⌨️ 快捷键说明

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