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

📄 xmlintrospector.java

📁 JAVA 文章管理系统源码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
     * @param nameMapper the NameMapper to use for the convertion
     * @deprecated 0.6 use getConfiguration().setAttributeNameMapper
     */
    public void setAttributeNameMapper(NameMapper nameMapper) {
        getConfiguration().setAttributeNameMapper( nameMapper );
    }
    
    /**
     * Should the original <code>java.reflect.Introspector</code> bean info search path be used?
     * By default it will be false.
     * 
     * @return boolean if the beanInfoSearchPath should be used.
     * @deprecated 0.6 use getConfiguration().useBeanInfoSearchPath
     */
    public boolean useBeanInfoSearchPath() {
        return getConfiguration().useBeanInfoSearchPath();
    }

    /**
     * Specifies if you want to use the beanInfoSearchPath 
     * @see java.beans.Introspector for more details
     * @param useBeanInfoSearchPath 
     * @deprecated 0.6 use getConfiguration().setUseBeanInfoSearchPath
     */
    public void setUseBeanInfoSearchPath(boolean useBeanInfoSearchPath) {
        getConfiguration().setUseBeanInfoSearchPath( useBeanInfoSearchPath );
    }
    
    // Methods
    //------------------------------------------------------------------------- 
    
    /**
     * Flush existing cached <code>XMLBeanInfo</code>'s.
     *
     * @deprecated 0.5 use flushable registry instead
     */
    public void flushCache() {}
    
    
    /** Create a standard <code>XMLBeanInfo</code> by introspection
      * The actual introspection depends only on the <code>BeanInfo</code>
      * associated with the bean.
      * 
      * @param bean introspect this bean
      * @return XMLBeanInfo describing bean-xml mapping
      * @throws IntrospectionException when the bean introspection fails
      */
    public XMLBeanInfo introspect(Object bean) throws IntrospectionException {
        if (getLog().isDebugEnabled()) {
            getLog().debug( "Introspecting..." );
            getLog().debug(bean);
        }
        
        if ( bean instanceof DynaBean ) {
            // allow DynaBean implementations to be overridden by .betwixt files
            XMLBeanInfo xmlBeanInfo = findByXMLDescriptor( bean.getClass() );
            if (xmlBeanInfo != null) {
                return xmlBeanInfo;
            }
            // this is DynaBean use the DynaClass for introspection
            return introspect( ((DynaBean) bean).getDynaClass() );
            
        } else {
            // normal bean so normal introspection
            Class normalClass = getClassNormalizer().getNormalizedClass( bean );
            return introspect( normalClass );
        }
    }
    
    /**
     * Creates XMLBeanInfo by reading the DynaProperties of a DynaBean.
     * Customizing DynaBeans using betwixt is not supported.
     * 
     * @param dynaClass the DynaBean to introspect
     * 
     * @return XMLBeanInfo for the DynaClass
     */
    public XMLBeanInfo introspect(DynaClass dynaClass) {

        // for now this method does not do much, since XMLBeanInfoRegistry cannot
        // use a DynaClass as a key
        // TODO: add caching for DynaClass XMLBeanInfo
        // need to work out if this is possible
        
        // this line allows subclasses to change creation strategy
        XMLBeanInfo xmlInfo = createXMLBeanInfo( dynaClass );
        
        // populate the created info with 
        DynaClassBeanType beanClass = new DynaClassBeanType( dynaClass );
        populate( xmlInfo, beanClass );
        
        return xmlInfo;  
    }
    
    /** Create a standard <code>XMLBeanInfo</code> by introspection.
      * The actual introspection depends only on the <code>BeanInfo</code>
      * associated with the bean.    
      *    
      * @param aClass introspect this class
      * @return XMLBeanInfo describing bean-xml mapping
      * @throws IntrospectionException when the bean introspection fails
      */
    public XMLBeanInfo introspect(Class aClass) throws IntrospectionException {
        // we first reset the beaninfo searchpath.
        String[] searchPath = null;
        if ( !getConfiguration().useBeanInfoSearchPath() ) {
            searchPath = Introspector.getBeanInfoSearchPath();
            Introspector.setBeanInfoSearchPath(new String[] { });
        }
        
        XMLBeanInfo xmlInfo = registry.get( aClass );
        
        if ( xmlInfo == null ) {
            // lets see if we can find an XML descriptor first
            if ( getLog().isDebugEnabled() ) {
                getLog().debug( "Attempting to lookup an XML descriptor for class: " + aClass );
            }
            
            xmlInfo = findByXMLDescriptor( aClass );
            if ( xmlInfo == null ) {
                BeanInfo info = Introspector.getBeanInfo( aClass );
                xmlInfo = introspect( info );
            }
            
            if ( xmlInfo != null ) {
                registry.put( aClass, xmlInfo );
            }
        } else {
            getLog().trace( "Used cached XMLBeanInfo." );
        }
        
        if ( getLog().isTraceEnabled() ) {
            getLog().trace( xmlInfo );
        }
        if ( !getConfiguration().useBeanInfoSearchPath() ) {
            // we restore the beaninfo searchpath.
            Introspector.setBeanInfoSearchPath( searchPath );
        }
        
        return xmlInfo;
    }
    
    /** Create a standard <code>XMLBeanInfo</code> by introspection. 
      * The actual introspection depends only on the <code>BeanInfo</code>
      * associated with the bean.
      *
      * @param beanInfo the BeanInfo the xml-bean mapping is based on
      * @return XMLBeanInfo describing bean-xml mapping
      * @throws IntrospectionException when the bean introspection fails
      */
    public XMLBeanInfo introspect(BeanInfo beanInfo) throws IntrospectionException {    
        XMLBeanInfo xmlBeanInfo = createXMLBeanInfo( beanInfo );
        populate( xmlBeanInfo, new JavaBeanType( beanInfo ) );
        return xmlBeanInfo;
    }
    
    /**
     * Populates the given <code>XMLBeanInfo</code> based on the given type of bean.
     *
     * @param xmlBeanInfo populate this, not null
     * @param bean the type definition for the bean, not null
     */
    private void populate(XMLBeanInfo xmlBeanInfo, BeanType bean) {    
        String name = bean.getBeanName();
        
        ElementDescriptor elementDescriptor = new ElementDescriptor();
        elementDescriptor.setLocalName( 
            getElementNameMapper().mapTypeToElementName( name ) );
        elementDescriptor.setPropertyType( bean.getElementType() );
        
        if (getLog().isTraceEnabled()) {
            getLog().trace("Populating:" + bean);
        }

        // add default string value for primitive types
        if ( bean.isPrimitiveType() ) {
            getLog().trace("Bean is primitive");
            elementDescriptor.setTextExpression( StringExpression.getInstance() );
            
        } else if ( bean.isLoopType() ) {
            getLog().trace("Bean is loop");
            ElementDescriptor loopDescriptor = new ElementDescriptor();
            loopDescriptor.setContextExpression(
                new IteratorExpression( EmptyExpression.getInstance() )
            );
            if ( bean.isMapType() ) {
                loopDescriptor.setQualifiedName( "entry" );
            }
            elementDescriptor.setElementDescriptors( new ElementDescriptor[] { loopDescriptor } );
            
        } else {
            getLog().trace("Bean is standard type");
            List elements = new ArrayList();
            List attributes = new ArrayList();
            List contents = new ArrayList();

            addProperties( bean.getProperties(), elements, attributes, contents );    

            int size = elements.size();
            if ( size > 0 ) {
                ElementDescriptor[] descriptors = new ElementDescriptor[size];
                elements.toArray( descriptors );
                elementDescriptor.setElementDescriptors( descriptors );
            }
            size = attributes.size();
            if ( size > 0 ) {
                AttributeDescriptor[] descriptors = new AttributeDescriptor[size];
                attributes.toArray( descriptors );
                elementDescriptor.setAttributeDescriptors( descriptors );
            }
            size = contents.size();
            if ( size > 0 ) {
                if ( size > 0 ) {
                    Descriptor[] descriptors = new Descriptor[size];
                    contents.toArray( descriptors );
                    elementDescriptor.setContentDescriptors( descriptors );
                }
            }
        }
        
        xmlBeanInfo.setElementDescriptor( elementDescriptor );        
        
        // default any addProperty() methods
        defaultAddMethods( elementDescriptor, bean.getElementType() );
        
        if (getLog().isTraceEnabled()) {
            getLog().trace("Populated descriptor:");
            getLog().trace(elementDescriptor);
        }
    }

    
    /**
     * Creates XMLBeanInfo for the given DynaClass.
     * 
     * @param dynaClass the class describing a DynaBean
     * 
     * @return XMLBeanInfo that describes the properties of the given 
     * DynaClass
     */
    protected XMLBeanInfo createXMLBeanInfo(DynaClass dynaClass) {
        // XXX is the chosen class right?
        XMLBeanInfo beanInfo = new XMLBeanInfo(dynaClass.getClass());
        return beanInfo;
    }




    /** 
     * Create a XML descriptor from a bean one. 
     * Go through and work out whether it's a loop property, a primitive or a standard.
     * The class property is ignored.
     *
     * @param propertyDescriptor create a <code>NodeDescriptor</code> for this property
     * @param useAttributesForPrimitives write primitives as attributes (rather than elements)
     * @return a correctly configured <code>NodeDescriptor</code> for the property
     * @throws IntrospectionException when bean introspection fails
     * @deprecated 0.5 use {@link #createXMLDescriptor}.
     */
    public Descriptor createDescriptor(
        PropertyDescriptor propertyDescriptor, 
        boolean useAttributesForPrimitives
    ) throws IntrospectionException {
        return createXMLDescriptor( new BeanProperty( propertyDescriptor ) );
    }
 
    /** 
     * Create a XML descriptor from a bean one. 
     * Go through and work out whether it's a loop property, a primitive or a standard.
     * The class property is ignored.
     *
     * @param beanProperty the BeanProperty specifying the property
     * @return a correctly configured <code>NodeDescriptor</code> for the property
     * @since 0.5
     */
    public Descriptor createXMLDescriptor( BeanProperty beanProperty ) {
        return beanProperty.createXMLDescriptor( configuration );
    }


    /** 
     * Add any addPropety(PropertyType) methods as Updaters 
     * which are often used for 1-N relationships in beans.
     * <br>
     * The tricky part here is finding which ElementDescriptor corresponds
     * to the method. e.g. a property 'items' might have an Element descriptor
     * which the method addItem() should match to. 
     * <br>
     * So the algorithm we'll use 
     * by default is to take the decapitalized name of the property being added
     * and find the first ElementDescriptor that matches the property starting with
     * the string. This should work for most use cases. 
     * e.g. addChild() would match the children property.
     * <br>
     * TODO this probably needs refactoring. It probably belongs in the bean wrapper
     * (so that it'll work properly with dyna-beans) and so that the operations can 
     * be optimized by caching. Multiple hash maps are created and getMethods is
     * called multiple times. This is relatively expensive and so it'd be better
     * to push into a proper class and cache.
     * <br>
     * TODO this probably does work properly with DynaBeans: need to push
     * implementation into an class and expose it on BeanType.
     *
     * @param introspector use this <code>XMLIntrospector</code> for introspection
     * @param rootDescriptor add defaults to this descriptor
     * @param beanClass the <code>Class</code> to which descriptor corresponds
     */
    public void defaultAddMethods( 
                                            ElementDescriptor rootDescriptor, 
                                            Class beanClass ) {
                                              
        // lets iterate over all methods looking for one of the form
        // add*(PropertyType)
        if ( beanClass != null ) {
            ArrayList singleParameterAdders = new ArrayList();
            ArrayList twinParameterAdders = new ArrayList();
            
            Method[] methods = beanClass.getMethods();
            for ( int i = 0, size = methods.length; i < size; i++ ) {
                Method method = methods[i];
                String name = method.getName();
                if ( name.startsWith( "add" )) {
                    // TODO: should we filter out non-void returning methods?
                    // some beans will return something as a helper
                    Class[] types = method.getParameterTypes();
                    if ( types != null) {
                        if ( getLog().isTraceEnabled() ) {
                            getLog().trace("Searching for match for " + method);
                        }
                        
                        switch (types.length)
                        {
                            case 1:
                                singleParameterAdders.add(method);
                                break;
                            case 2:
                                twinParameterAdders.add(method);
                                break;
                            default:
                                // ignore
                                break;
                        }
                    }
                }
            }

⌨️ 快捷键说明

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