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

📄 modelbuilder.java

📁 该源代码为一些通用的程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* ========================================================================
 * JCommon : a free general purpose class library for the Java(tm) platform
 * ========================================================================
 *
 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
 * 
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 * 
 * -----------------
 * ModelBuilder.java
 * -----------------
 * (C)opyright 2003, 2004, by Thomas Morgner and Contributors.
 *
 * Original Author:  Thomas Morgner;
 * Contributor(s):   David Gilbert (for Object Refinery Limited);
 *
 * $Id: ModelBuilder.java,v 1.3 2005/10/18 13:32:20 mungady Exp $
 *
 * Changes
 * -------
 * 21-Jun-2003 : Initial version (TM);
 * 26-Nov-2003 : Updated header and Javadocs (DG);
 * 
 */

package org.jfree.xml.generator;

import java.beans.BeanInfo;
import java.beans.IndexedPropertyDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Properties;

import org.jfree.util.HashNMap;
import org.jfree.xml.generator.model.ClassDescription;
import org.jfree.xml.generator.model.DescriptionModel;
import org.jfree.xml.generator.model.MultiplexMappingInfo;
import org.jfree.xml.generator.model.PropertyInfo;
import org.jfree.xml.generator.model.PropertyType;
import org.jfree.xml.generator.model.TypeInfo;
import org.jfree.xml.util.BasicTypeSupport;

/**
 * A model builder.  This class performs the work of creating a class description model from
 * a set of source files.
 */
public final class ModelBuilder {

    /** The single instance. */
    private static ModelBuilder instance;

    /**
     * Returns the single instance of this class.
     * 
     * @return the single instance of this class.
     */
    public static ModelBuilder getInstance() {
        if (instance == null) {
            instance = new ModelBuilder();
        }
        return instance;
    }

    /** The handler mapping. */
    private Properties handlerMapping;

    /**
     * Creates a single instance.
     */
    private ModelBuilder() {
        this.handlerMapping = new Properties();
    }

    /**
     * Adds attribute handlers.
     * 
     * @param p  the handlers.
     */
    public void addAttributeHandlers(final Properties p) {
        this.handlerMapping.putAll(p);
    }

    /**
     * Builds a model from the classes provided by the {@link SourceCollector}. 
     * <P>
     * The {@link DescriptionGenerator} class invokes this.
     * 
     * @param c  the source collector.
     * @param model  the model under construction (<code>null</code> permitted).
     * 
     * @return The completed model.
     */
    public DescriptionModel buildModel(final SourceCollector c, DescriptionModel model) {
        
        Class[] classes = c.getClasses();

        if (model == null) {
            model = new DescriptionModel();
        }

        while (classes.length != 0) {
            classes = fillModel(classes, model);
        }

        fillSuperClasses(model);
        // search for multiplexer classes

        // first search all classes used in parameters and add them to
        // our list of possible base classes
        final Class[] baseClasses = findElementTypes(model);

        final HashNMap classMap = new HashNMap();
        for (int i = 0; i < baseClasses.length; i++) {

            final Class base = baseClasses[i];

            for (int j = 0; j < baseClasses.length; j++) {

                final Class child = baseClasses[j];
                if (Modifier.isAbstract(child.getModifiers())) {
                    continue;
                }
                if (base.isAssignableFrom(child)) {
                    classMap.add(base, child);
                }
            }
        }

        // at this point, the keys of 'classMap' represent all required
        // multiplexers, while the values assigned to these keys define the
        // possible childs
        final Iterator keys = classMap.keys();
        while (keys.hasNext()) {
            final Class base = (Class) keys.next();
            final Class[] childs = (Class[]) classMap.toArray(base, new Class[0]);
            if (childs.length < 2) {
                continue;
            }

            boolean isNew = false;
            MultiplexMappingInfo mmi = model.getMappingModel().lookupMultiplexMapping(base);
            final ArrayList typeInfoList;
            if (mmi == null) {
                mmi = new MultiplexMappingInfo(base);
                typeInfoList = new ArrayList();
                isNew = true;
            }
            else {
                typeInfoList = new ArrayList(Arrays.asList(mmi.getChildClasses()));
            }

            for (int i = 0; i < childs.length; i++) {
                // the generic information is only added, if no other information
                // is already present ...
                final TypeInfo typeInfo = new TypeInfo(childs[i].getName(), childs[i]);
                if (!typeInfoList.contains(typeInfo)) {
                    typeInfoList.add(typeInfo);
                }
            }

            mmi.setChildClasses((TypeInfo[]) typeInfoList.toArray(new TypeInfo[0]));
            if (isNew) {
                model.getMappingModel().addMultiplexMapping(mmi);
            }
        }

        // when resolving a class to an handler, the resolver first has to
        // search for an multiplexer before searching for handlers. Otherwise
        // non-abstract baseclasses will be found before the multiplexer can
        // resolve the situation.
        return model;
    }

    private Class[] findElementTypes(final DescriptionModel model) {
        final ArrayList baseClasses = new ArrayList();

        for (int i = 0; i < model.size(); i++) {
            final ClassDescription cd = model.get(i);
            if (!baseClasses.contains(cd.getObjectClass())) {
                baseClasses.add(cd.getObjectClass());
            }

            final PropertyInfo[] properties = cd.getProperties();
            for (int p = 0; p < properties.length; p++) {
                // filter primitive types ... they cannot form a generalization
                // relation
                if (!properties[p].getPropertyType().equals(PropertyType.ELEMENT)) {
                    continue;
                }
                final Class type = properties[p].getType();
                if (baseClasses.contains(type)) {
                    continue;
                }
                // filter final classes, they too cannot have derived classes
                if (Modifier.isFinal(type.getModifiers())) {
                    continue;
                }
                baseClasses.add(type);
            }
        }
        return (Class[]) baseClasses.toArray(new Class[baseClasses.size()]);
    }

    /**
     * Fills the super class for all object descriptions of the model. The
     * super class is only filled, if the object's super class is contained
     * in the model.
     *
     * @param model the model which should get its superclasses updated.
     */
    private void fillSuperClasses(final DescriptionModel model) {
        // Fill superclasses
        for (int i = 0; i < model.size(); i++) {
            final ClassDescription cd = model.get(i);
            final Class parent = cd.getObjectClass().getSuperclass();

⌨️ 快捷键说明

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