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

📄 beancreaterule.java

📁 JAVA 文章管理系统源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        }
    }

    /** 
     * Tidy up.
     */
    public void finish() {}


    // Properties
    //-------------------------------------------------------------------------    
    

    /**
     * The name of the attribute which can be specified in the XML to override the
     * type of a bean used at a certain point in the schema.
     *
     * <p>The default value is 'className'.</p>
     * 
     * @return The name of the attribute used to overload the class name of a bean
     */
    public String getClassNameAttribute() {
        return classNameAttribute;
    }

    /**
     * Sets the name of the attribute which can be specified in 
     * the XML to override the type of a bean used at a certain 
     * point in the schema.
     *
     * <p>The default value is 'className'.</p>
     * 
     * @param classNameAttribute The name of the attribute used to overload the class name of a bean
     */
    public void setClassNameAttribute(String classNameAttribute) {
        this.classNameAttribute = classNameAttribute;
    }

    // Implementation methods
    //-------------------------------------------------------------------------    
    
    /** 
     * Factory method to create new bean instances 
     *
     * @param attributes the <code>Attributes</code> used to match <code>ID/IDREF</code>
     * @return the created bean
     */
    protected Object createBean(Attributes attributes) {
        //
        // See if we've got an IDREF
        //
        // XXX This should be customizable but i'm not really convinced by the existing system
        // XXX maybe it's going to have to change so i'll use 'idref' for nows
        //
        if ( matchIDs ) {
            String idref = attributes.getValue( "idref" );
            if ( idref != null ) {
                // XXX need to check up about ordering
                // XXX this is a very simple system that assumes that id occurs before idrefs
                // XXX would need some thought about how to implement a fuller system
                log.trace( "Found IDREF" );
                Object bean = getBeansById().get( idref );
                if ( bean != null ) {
                    if (log.isTraceEnabled()) {
                        log.trace( "Matched bean " + bean );
                    }
                    return bean;
                }
                log.trace( "No match found" );
            }
        }
        
        Class theClass = beanClass;
        try {
            
            String className = attributes.getValue(classNameAttribute);
            if (className != null) {
                // load the class we should instantiate
                theClass = getDigester().getClassLoader().loadClass(className);
            }
            if (log.isTraceEnabled()) {
                log.trace( "Creating instance of " + theClass );
            }
            return theClass.newInstance();
            
        } catch (Exception e) {
            log.warn( "Could not create instance of type: " + theClass.getName() );
            return null;
        }
    }    
        
    /** Adds the rules to the digester for all child elements */
    protected void addChildRules() {
        if ( ! addedChildren ) {
            addedChildren = true;
            
            addChildRules( pathPrefix, descriptor );
        }
    }
                        
    /** 
     * Add child rules for given descriptor at given prefix 
     *
     * @param prefix add child rules at this (digester) path prefix
     * @param currentDescriptor add child rules for this descriptor
     */
    protected void addChildRules(String prefix, ElementDescriptor currentDescriptor ) {         
        
        if (log.isTraceEnabled()) {
            log.trace("Adding child rules for " + currentDescriptor + "@" + prefix);
        }
        
        // 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( currentDescriptor );
        //ElementDescriptor typeDescriptor = descriptor;

        
        ElementDescriptor[] childDescriptors = typeDescriptor.getElementDescriptors();
        if ( childDescriptors != null ) {
            for ( int i = 0, size = childDescriptors.length; i < size; i++ ) {
                final ElementDescriptor childDescriptor = childDescriptors[i];
                if (log.isTraceEnabled()) {
                    log.trace("Processing child " + childDescriptor);
                }
                
                String qualifiedName = childDescriptor.getQualifiedName();
                if ( qualifiedName == null ) {
                    log.trace( "Ignoring" );
                    continue;
                }
                String path = prefix + qualifiedName;
                // this code is for making sure that recursive elements
                // can also be used..
                
                if ( qualifiedName.equals( currentDescriptor.getQualifiedName() ) 
                        && currentDescriptor.getPropertyName() != null ) {
                    log.trace("Creating generic rule for recursive elements");
                    int index = -1;
                    if (childDescriptor.isWrapCollectionsInElement()) {
                        index = prefix.indexOf(qualifiedName);
                        if (index == -1) {
                            // shouldn't happen.. 
                            log.debug( "Oops - this shouldn't happen" );
                            continue;
                        }
                        int removeSlash = prefix.endsWith("/")?1:0;
                        path = "*/" + prefix.substring(index, prefix.length()-removeSlash);
                    }else{
                        // we have a element/element type of thing..
                        ElementDescriptor[] desc = currentDescriptor.getElementDescriptors();
                        if (desc.length == 1) {
                            path = "*/"+desc[0].getQualifiedName();
                        }
                    }
                    Rule rule = new BeanCreateRule( childDescriptor, context, path, matchIDs);
                    addRule(path, rule);
                    continue;
                }
                if ( childDescriptor.getUpdater() != null ) {
                    if (log.isTraceEnabled()) {
                        log.trace("Element has updater "
                         + ((MethodUpdater) childDescriptor.getUpdater()).getMethod().getName());
                    }
                    if ( childDescriptor.isPrimitiveType() ) {
                        addPrimitiveTypeRule(path, childDescriptor);
                        
                    } else {
                        // add the first child to the path
                        ElementDescriptor[] grandChildren = childDescriptor.getElementDescriptors();
                        if ( grandChildren != null && grandChildren.length > 0 ) {
                            ElementDescriptor grandChild = grandChildren[0];
                            String grandChildQName = grandChild.getQualifiedName();
                            if ( grandChildQName != null && grandChildQName.length() > 0 ) {
                                if (childDescriptor.isWrapCollectionsInElement()) {
                                    path += '/' + grandChildQName;
                                    
                                } else {
                                    path = prefix + (prefix.endsWith("/")?"":"/") + grandChildQName;
                                }
                            }
                        }
                        
                        // maybe we are adding a primitve type to a collection/array
                        Class beanClass = childDescriptor.getSingularPropertyType();
                        if ( XMLIntrospectorHelper.isPrimitiveType( beanClass ) ) {
                            addPrimitiveTypeRule(path, childDescriptor);
                            
                        } else {
                            Rule rule = new BeanCreateRule( 
                                                        childDescriptor, 
                                                        context, 
                                                        path + '/', 
                                                        matchIDs );
                            addRule( path, rule );
                        }
                    }
                } else {
                    log.trace("Element does not have updater");
                }

                ElementDescriptor[] grandChildren = childDescriptor.getElementDescriptors();
                if ( grandChildren != null && grandChildren.length > 0 ) {
                    log.trace("Adding grand children");
                    addChildRules( path + '/', childDescriptor );
                }
            }
        }
    }
    
    /**
     * Get the associated bean reader.
     *
     * @return the <code>BeanReader</code digesting the xml
     */
    protected BeanReader getBeanReader() {
        // XXX this breaks the rule contact
        // XXX maybe the reader should be passed in the constructor
        return (BeanReader) getDigester();
    }
    
    /** Allows the navigation from a reference to a property object to the descriptor defining what 
     * the property is. i.e. doing the join from a reference to a type to lookup its descriptor.
     * This could be done automatically by the NodeDescriptors. Refer to TODO.txt for more info.
     *
     * @param propertyDescriptor find descriptor for property object referenced by this descriptor
     * @return descriptor for the singular property class type referenced.
     */
    protected ElementDescriptor getElementDescriptor( ElementDescriptor propertyDescriptor ) {
        Class beanClass = propertyDescriptor.getSingularPropertyType();
        if ( beanClass != null ) {
            XMLIntrospector introspector = getBeanReader().getXMLIntrospector();
            try {
                XMLBeanInfo xmlInfo = introspector.introspect( beanClass );
                return xmlInfo.getElementDescriptor();
                
            } catch (Exception e) {
                log.warn( "Could not introspect class: " + beanClass, e );
            }
        }
        // could not find a better descriptor so use the one we've got
        return propertyDescriptor;
    }
    
    /** 
     * Adds a new Digester rule to process the text as a primitive type
     *
     * @param path digester path where this rule will be attached
     * @param childDescriptor update this <code>ElementDescriptor</code> with the body text
     */
    protected void addPrimitiveTypeRule(String path, final ElementDescriptor childDescriptor) {
        Rule rule = new Rule() {
            public void body(String text) throws Exception {
                childDescriptor.getUpdater().update( context, text );
            }        
        };
        addRule( path, rule );
    }
    
    /**
     * Safely add a rule with given path.
     *
     * @param path the digester path to add rule at
     * @param rule the <code>Rule</code> to add
     */
    protected void addRule(String path, Rule rule) {
        Rules rules = digester.getRules();
        List matches = rules.match(null, path);
        if ( matches.isEmpty() ) {
            if ( log.isDebugEnabled() ) {
                log.debug( "Adding digester rule for path: " + path + " rule: " + rule );
            }
            digester.addRule( path, rule );
            
        } else {
            if ( log.isDebugEnabled() ) {
                log.debug( "Ignoring duplicate digester rule for path: " 
                            + path + " rule: " + rule );
                log.debug( "New rule (not added): " + rule );
                log.debug( "Existing rule:" + matches.get(0) );
            }
        }
    }    

    /**
     * Get the map used to index beans (previously read in) by id.
     * This is stored in the evaluation context.
     *
     * @return map indexing beans created by id
     */
    protected Map getBeansById() {
        //
        // we need a single index for beans read in by id
        // so that we can use them for idref-matching
        // store this in the context
        //
        Map beansById = (Map) context.getVariable( "beans-index" );
        if ( beansById == null ) {
            // lazy creation
            beansById = new HashMap();
            context.setVariable( "beans-index", beansById );
            log.trace( "Created new index-by-id map" );
        }
        
        return beansById;
    }
    
    /**
     * Return something meaningful for logging.
     *
     * @return something useful for logging
     */
    public String toString() {
        return "BeanCreateRule [path prefix=" + pathPrefix + " descriptor=" + descriptor + "]";
    }
    
}

⌨️ 快捷键说明

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