alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.schema2beansdev;

import java.util.*;
import java.io.*;

import org.netbeans.modules.schema2beans.*;
import org.netbeans.modules.schema2beansdev.metadd.*;
import org.netbeans.modules.schema2beansdev.beangraph.*;
import org.netbeans.modules.schema2beansdev.gen.*;

/**
 *  This class implements the Document Definition handler in order to build
 *  the internal tree representation of the DD DTD.
 */
public class BeanBuilder {
    private static final String UNIQUE_PREFIX = "My";
    protected GenBeans.Config config;
    protected CodeGeneratorFactory codeGenFactory;
    protected BeanElement rootElement;
    protected String genDir;
    protected String packagePath;
    protected String packageName = null;
    protected TreeParser parser;
    protected Map constNameMap = null;	// LinkedHashMap

    protected Map illegalClassNames = new HashMap();
    
    class BeanElement {
        GraphNode	node;
        String 		beanName;
	
        int		type;
        String		classType;
        private boolean typeSetExternally = false;
	
        boolean		isRoot;

        private boolean canBeEmpty = false;

        private Map usedTypes;
	
        BeanElement(GraphNode node) {
            this.node = node;
        }
	
        void initialize(boolean isRoot) {
            //	Make up a bean name: xxx-yyy has to be XxxYyy
            this.beanName = Common.convertName(this.node.getName());
	    
            //
            //	As each node ends up as a property, we have to find out the
            //	type of the property. The default value is Common.TYPE_BEAN.
            //
            this.type = Common.TYPE_BEAN;
            this.isRoot = isRoot;
            
            calculateType();
        }
	
        public GraphNode getGraphNode() {
            return this.node;
        }

        /**
         * Call this to change whether or not we will actually generate
         * this as a bean.  Should we create it or not?
         * Users need to call this method instead of node.setCreated directly,
         * because some of this object's state depends on that value.
         */
        public void setNodeCreated(boolean value) {
            node.setCreated(value);
            calculateType();
        }

        protected void calculateType() {
            // If we arn't going to create it, then it must not be a bean.
            if (!node.isCreated())
                this.type = Common.TYPE_STRING;
            GraphNode[] nodes = node.getNodes();
            // If it is the root, then it must be a bean.
            if (nodes.length == 1 && !isRoot) {
                if (Common.DTD_STRING.equals(nodes[0].getName()))
                    this.type = Common.TYPE_STRING;
                else {
                    if (Common.DTD_EMPTY.equals(nodes[0].getName())) {
                        this.type = Common.TYPE_BOOLEAN;
                        this.canBeEmpty = true;
                    }
                }
            }
        }

        void setCanBeEmpty(boolean value) {
            canBeEmpty = value;
            if (canBeEmpty) {
                //type = Common.TYPE_BOOLEAN;
            }
        }
	
        /**
         * setName allows you to change the name of the generated class.
         */
        public void setName(String name) {
            this.beanName = name;
        }
		
        public String getName() {
            return this.beanName;
        }
	
        public String getDTDName() {
            return this.node.getName();
        }

        public void setDTDName(String dtdName) {
            node.setName(dtdName);
        }

        public String getNamespace() {
            return node.getNamespace();
        }
	
        public boolean isBean() {
            return Common.isBean(this.type);
        }
	
        public boolean isBoolean() {
            return Common.isBoolean(this.type);
        }
	
        public boolean isRoot() {
            return this.isRoot;
        }
	
        public String typeToString() {
            switch(this.type) {
            case Common.TYPE_STRING:
                return Common.CLASS_STRING;
            case Common.TYPE_BOOLEAN:
                return Common.CLASS_BOOLEAN;
            default:
                return this.beanName;
            }
        }
	
        public String getClassType() {
            if (classType == null)
                return typeToString();
            return classType;
        }

        public String getFullClassType() {
            String result = getClassType();
            if (packageName == null)
                return result;
            if (isBean() && node.isCreated())
                return packageName+"."+result;
            return result;
        }

        public void setClassType(String ct) {
            classType = ct;
        }

        public boolean isTypeSetExternally() {
            return typeSetExternally;
        }

        public void setTypeSetExternally(boolean value) {
            typeSetExternally = value;
        }
		
        public String toString() {
            return this.beanName +
                ((this.type == 
                  Common.TYPE_STRING)?" \t(String)":"\t(Bean)");  // NOI18N
        }

        public void setUsedTypes(Map usedTypes) {
            this.usedTypes = usedTypes;
        }

        public boolean isUsedType(String type) {
            return usedTypes.containsKey(type);
        }

        public boolean getCanBeEmpty() {
            return canBeEmpty;
        }

        public String getOutputFileName() {
            if (isBean())
                return getClassType();
            else
                return getName();
        }
    }

    class Finder {
        private String findExpr, byExpr;
        private boolean listFindExpr;
        
        public Finder(String findExpr, String byExpr, boolean listFindExpr) {
            this.findExpr = findExpr;
            this.byExpr = byExpr;
            this.listFindExpr = listFindExpr;
        }

        public String getFindExpr() {
            return findExpr;
        }

        public String getByExpr() {
            return byExpr;
        }

        public boolean isListFindExpr() {
            return listFindExpr;
        }

        public String toString() {
            if (listFindExpr)
                return "Finder list "+findExpr+" by "+byExpr;
            else
                return "Finder "+findExpr+" by "+byExpr;
        }
    }
    
    BeanBuilder(TreeParser parser, GenBeans.Config config, CodeGeneratorFactory cgf) {
        this.parser = parser;
        this.config = config;
        this.codeGenFactory = cgf;

        // Since java.lang is implicitly imported, we have to make sure to
        // not generate a class with that collides with java.lang.
        illegalClassNames.put("Object", null);
        illegalClassNames.put("Thread", null);
        illegalClassNames.put("Compiler", null);
        illegalClassNames.put("Class", null);
        illegalClassNames.put("ClassLoader", null);
        //illegalClassNames.put("Process", null);
        illegalClassNames.put("Package", null);
        illegalClassNames.put("String", null);
        illegalClassNames.put("Boolean", null);
        illegalClassNames.put("Integer", null);
        illegalClassNames.put("Long", null);
        illegalClassNames.put("Short", null);
        illegalClassNames.put("Double", null);
        illegalClassNames.put("Float", null);
        illegalClassNames.put("Byte", null);
        illegalClassNames.put("Character", null);
        illegalClassNames.put("int", null);
        illegalClassNames.put("char", null);
        illegalClassNames.put("byte", null);
        illegalClassNames.put("short", null);
        illegalClassNames.put("long", null);
        illegalClassNames.put("double", null);
        illegalClassNames.put("float", null);
        illegalClassNames.put("boolean", null);
        illegalClassNames.put("void", null);
    }
    
    
    /**
     *	Parse the attributes of the bean
     *
     * usedNames helps us to not generate multiple properties with the
     * same name.  The key is the name of the property and the entry
     * is a BeanElement (name = BeanElement.getName()).  Currently,
     * the storage of the BeanElement is not used, and null should be
     * valid for properties that are defined without a BeanElement.
     */
    private void buildProperties(GraphLink l, CodeGeneratorClass bc,
                                 int nestedLevel, int groupInstance,
                                 boolean ored,
                                 MetaElement e, MetaDD mdd, Map usedNames) {
        while (l != null) {
            if (config.isTraceGen())
                config.messageOut.println("buildProperties: l="+l+" l.name="+l.name+" l.element="+l.element+" l.getSibling()="+l.getSibling()+" groupInstance="+groupInstance);
            if (l.element != null) {
                BeanElement be = (BeanElement)l.element.getObject();
		
                if (be == null) {
                    // This can happen if there are no properties associated
                    // with this bean (like if the root element has no
                    // children elements).
                    config.messageOut.println("Warning: be was null");
                    continue;
                }

                //
                //  The group prop was set on the parent of the children.
                //  Set it on each property directly for building the class.
                //
                if (l.getParent() != null)
                    ored = ored || l.getParent().isSequenceOr();
                //System.out.println("ored="+ored);

                String name;
                String dtdName;
                String namespace;
                String constName;
                if (l.name != null) {
                    name = Common.convertName(l.name);
                    dtdName = l.getSchemaName();
                    namespace = l.getNamespace();
                } else {
                    name = be.getName();
                    dtdName = be.getDTDName();
                    namespace = be.getNamespace();
                }
                MetaElement propertyME = getMetaElement(mdd, dtdName);
                if (propertyME != null && propertyME.getBeanName() != null) {
                    name = propertyME.getBeanName();
                    if (config.isTraceGen())
                        config.messageOut.println("buildProperties: property in "+e.getBeanName()+" has been renamed to "+name);
                }
                constName = Common.constName(dtdName);
                if ("#PCDATA".equals(dtdName)) {
                    // text node
                    //config.messageOut.println("Hit #PCDATA");
                    name = "pcdata";
                    constName = "PCDATA";
                }
                if (usedNames.containsKey(name)) {
                    int uniqNum = 2;
                    String baseName = name;
                    while (usedNames.containsKey(name = baseName + uniqNum))
                        uniqNum++;
                    constName = constName + uniqNum;
                    if (l.name != null) {
                        //l.name = l.name + uniqNum;
                    } else {
                        be.setName(name);
                        MetaElement origE = getMetaElement(mdd, dtdName);
                        if (origE != null) {
                            MetaElement newE = new MetaElement(origE);
                            mdd.addMetaElement(newE);
                        }
                    }
                    config.messageOut.println(Common.getMessage("RenamedProperty_msg", baseName, name, e.getBeanName()));
                }
                usedNames.put(name, be);
                if (config.isTraceGen())
                    config.messageOut.println("buildProperties: name="+name+" constName="+constName+" dtdName="+dtdName+" graphlink.name="+l.name+" be.getClassType="+be.getClassType());
                AttrProp[] attrs = be.node.getAttributes();
                List extraData = new ArrayList(l.extraData);
                if (!be.node.getExtraData().isEmpty()) {
                    extraData.addAll(be.node.getExtraData());
                    //System.out.println("**** be.node="+be.node+" extraData="+extraData);
                }
                //System.out.println("extraData="+extraData);
                if (propertyME != null && propertyME.sizeKnownValue() > 0) {
                    for (int valNum = 0, size = propertyME.sizeKnownValue(); valNum < size; ++valNum) {
                        String knownValue = propertyME.getKnownValue(valNum);
                        extraData.add(new KnownValueEnumeration(knownValue));
                    }
                }
                constNameMap.put(constName, dtdName);
                int type = be.type;
                String classType = be.getClassType();
                //
                // Look to see if we need to make a primitive type into an
                // Object type, but don't do it, if the user has set the
                // type (like from mdd file).
                //
                if (!be.isTypeSetExternally() &&
                    (ored || l.isNillable())) {
                    if (JavaUtil.isPrimitiveType(classType)) {
                        classType = JavaUtil.toObjectType(classType);
                        type = Common.wrapperToType(classType);
                        if (type == Common.NONE)
                            type = Common.TYPE_STRING;
                        if (config.isTraceGen())
                            config.messageOut.println("Promoting primitive type to object type for "+name+" classType="+classType+" type="+type);
                    }
                }
                AbstractCodeGeneratorClass.Property prop = 
                    bc.addProperty(name, dtdName, namespace, l.element, l,
                                   classType, nestedLevel,
                                   l.getElementInstance(),
                                   groupInstance, type, ored,
                                   attrs, constName,
                                   l.getDefaultValue(), true, extraData);
                prop.setCanBeEmpty(be.getCanBeEmpty());
                prop.setNillable(l.isNillable());
                prop.setBeanElement(be);
                l.setObject(prop);
                if (e != null) {
                    // Need to check that name is not already in there.
                    MetaProperty[] metaProperties = e.getMetaProperty();
                    boolean found = false;
                    for (int i = 0; i < metaProperties.length; ++i) {
                        if (name.equals(metaProperties[i].getBeanName())) {
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        MetaProperty mp = new MetaProperty();
                        mp.setBeanName(name);
                        e.addMetaProperty(mp);
                    }
                }

                //
                // Take care of the case where a subnode is a leaf node
                // and it has attributes too.  In which case, that subnode's
                // attributes, become our own.
                //
                if (!Common.isBean(be.type) &&
                    config.isAttributesAsProperties()) {
                    addAttrProps(bc, attrs, name, usedNames,
                                 l.getElementInstance(), false);
                }
            }
	    
            //
            //	As we go one level deeper, the current link has
            //	the instance property of the group of children.
            //
            int childGroupInstance = Common.widestInstance(groupInstance,
                                                           l.getGroupInstance());
            buildProperties(l.getFirstChild(), bc, nestedLevel+1,
                            childGroupInstance, ored, e, mdd, usedNames);
	    
            l = l.getSibling();
        }
    }
    
    protected void addAttrProps(CodeGeneratorClass bc, AttrProp[] attrs,
                                String propertyName, Map usedNames,
                                int groupInstance,
                                boolean directChild) {
        if (attrs != null) {
            for (int i = 0; i < attrs.length; ++i) {
                addAttrProp(bc, attrs[i], propertyName, usedNames,
                            groupInstance, directChild);
            }
        }
    }
    
    protected void addAttrProp(CodeGeneratorClass bc, AttrProp attr,
                               String propertyName, Map usedNames,
                               int groupInstance,
                               boolean directChild) {
        String name;
        if (directChild)
            name = Common.convertName(attr.getName());
        else
            name = Common.convertName(propertyName+"_"+attr.getName());
        if (usedNames.containsKey(name)) {
            int uniqNum = 2;
            String baseName = name;
            while (usedNames.containsKey(name = baseName + uniqNum))
                uniqNum++;
            config.messageOut.println(Common.getMessage("RenamedProperty_msg", baseName, name, propertyName));
        }
        usedNames.put(name, attr);

        String javaType = attr.getJavaType();
        int type;
        if (javaType == null) {
            type = Common.TYPE_STRING;
            javaType = "java.lang.String";	// NOI18N
        } else {
            type = Common.wrapperToType(javaType);
            if (type == Common.NONE)
                type = Common.TYPE_STRING;
        }
        //System.out.println("addAttrProp: attr="+attr+" attr.javaType="+javaType);
        List extraData = attr.getExtraData();
        String namespace = attr.getNamespace();
        bc.addProperty(name, attr.getDtdName(), namespace, null, null,
                       javaType, 0,
                       attr.getInstance(),
                       groupInstance,
                       type,
                       false,
                       null,
                       Common.constName(name),
                       attr.getDefaultValue(), directChild,
                       extraData)
            .setAttrProp(attr);
    }

    protected void addCommentsProcessing(CodeGeneratorClass bc) {
        bc.addProperty("Comments", "comment", null, null, null,
                       "java.lang.String", 0,
                       Common.TYPE_0_N, 0, Common.TYPE_COMMENT,
                       false, null, "COMMENTS", null, true,
                       Collections.EMPTY_LIST);
    }

    protected static class KnownValueEnumeration implements DataEnumRestriction {
        private String knownValue;
        
        protected KnownValueEnumeration(String value) {
            knownValue = value;
        }

        public void genRestriction(Writer out, String type) throws IOException {
            out.write(JavaUtil.instanceFrom(type, knownValue));
        }
    }
    
    //	Called by GenBeans
    void process() throws IOException {
        Map generators = new LinkedHashMap();	// Map
        prepareBeans(generators);
        doGeneration(generators);
    }

    void prepareBeans(Map generators) throws IOException {
        GraphNode	    root = parser.getRoot();
        GraphNode[]	    list = parser.getNodes();
        String		    rootDir;
        BeanElement	    be;
        MetaDD			mdd = config.getMetaDD();
	
        if (root == null)
            throw new IllegalStateException(Common.getMessage("DTDObjectGraphIsNull_msg"));
        
        constNameMap = new LinkedHashMap();

        for (int i=0; i>
            // And generate the files
            for (Iterator it = generators.keySet().iterator(); it.hasNext(); ) {
                be = (BeanElement) it.next();
                CodeGeneratorClass bc = (CodeGeneratorClass) generators.get(be);
                String outputFileName = be.getOutputFileName();

                MetaElement metaElement = getMetaElement(mdd, be.getDTDName(), be.node.getNamespace());
                if (metaElement.isSkipGeneration()) {
                    config.messageOut.println("Skipping generation of class " + be.beanName
                                              + " (as specified in the mdd file)");	// NOI18N
                    continue;
                }

                //
                //	The bean class has now everything it needs to
                //	generate its content (name, package, attributes, ...)
                //
                try {
                    OutputStream out;
                    out = config.getOutputStreamProvider().getStream(genDir, 
                                                                     outputFileName, "java");	// NOI18N
                    bc.generate(out, mdd);
                    close(out);
                    out = null;  // Try to encourage the GC
                    Collection beansMethods = bc.getGeneratedMethods();
                    generatedMethods.add(beansMethods);

                    if (config.isGenerateDelegator()) {
                        GraphNode graphNode = be.getGraphNode();
                        MetaElement e = getMetaElement(mdd, be.getDTDName(),
                                                       graphNode.getNamespace());
                        String delegatorClassName;
                        if (e != null && e.getDelegatorName() != null)
                            delegatorClassName = e.getDelegatorName();
                        else {
                            delegatorClassName = outputFileName+"Delegator";
                            if (e != null)
                                e.setDelegatorName(delegatorClassName);
                        }
                        String delegatorPackageName = packageName;
                        String dir = genDir;
                        if (config.getDelegateDir() != null) {
                            dir = config.getDelegateDir().getAbsolutePath();
                            if (config.getDelegatePackage() == null) {
                                if (packagePath != null && !packagePath.equals(""))
                                    dir = dir + "/" + packagePath;	// NOI18N
                            } else {
                                delegatorPackageName = config.getDelegatePackage();
                                dir = dir + "/" + delegatorPackageName.replace('.', '/');	// NOI18N
                            }
                        }
                        out = config.getOutputStreamProvider().getStream(dir, 
                                                                         delegatorClassName, "java");	// NOI18N
                        bc.generateDelegator(out, mdd, delegatorClassName, delegatorPackageName);
                        close(out);
                        out = null;  // Try to encourage the GC
                    }
                    if (config.isGenerateInterfaces()) {
                        List beanInfoMethods = new ArrayList(beansMethods.size());	// List
                        for (Iterator mit = beansMethods.iterator(); mit.hasNext(); ) {
                            JavaWriter.Method method = (JavaWriter.Method) mit.next();
                            if (method.isStatic() || method.isConstructor() ||
                                !method.isPublic())
                                continue;
                            if (!method.isBeanInfo())
                                continue;
                            //System.out.println("\tFound bean info: "+method.getNameParameters());
                            beanInfoMethods.add(method);
                        }
                        String interfaceName = outputFileName+"Interface";	// NOI18N
                        GraphNode graphNode = be.getGraphNode();
                        MetaElement me = getMetaElement(mdd, be.getDTDName(),
                                                       graphNode.getNamespace());
                        generateInterface(genDir, packageName,
                                          interfaceName,
                                          beanInfoMethods,
                                          "This interface has all of the bean info accessor methods.",
                                          me.getBeanInterfaceExtends());
                    }
                } catch(IOException ioe) {
                    config.messageOut.println("Failed to generate bean class: "+outputFileName);	// NOI18N
                    TraceLogger.error(ioe);
                    throw ioe;
                } catch(IllegalStateException ise) {
                    config.messageOut.println("Failed to generate bean class "+outputFileName);	// NOI18N
                    TraceLogger.error(ise);
                    throw ise;
                }
            }

            if (config.getGenerateCommonInterface() != null
                && generatedMethods.size() > 0) {
                Map commonGeneratedMethods = new HashMap(); 	// Map
                Iterator it = generatedMethods.iterator();
                Collection methods = (Collection) it.next();
                // Put all of the methods into our map
                for (Iterator mit = methods.iterator(); mit.hasNext(); ) {
                    JavaWriter.Method method = (JavaWriter.Method) mit.next();
                    if (method.isStatic() || method.isConstructor() ||
                        !method.isPublic() || method.isUnsupported())
                        continue;
                    commonGeneratedMethods.put(method.getNameParameters(), method);
                }
                // Now go thru the other classes, and remove any methods that we do
                // not find.
                while (it.hasNext()) {
                    //System.out.println("---- Next bean");
                    methods = (Collection) it.next();
                    Map toKeep = new HashMap();	// Map
                    for (Iterator mit = methods.iterator(); mit.hasNext(); ) {
                        JavaWriter.Method method = (JavaWriter.Method) mit.next();
                        String nameParameters = method.getNameParameters();
                        if (commonGeneratedMethods.containsKey(nameParameters)) {
                            //System.out.println("Keeping "+nameParameters);
                            toKeep.put(nameParameters, commonGeneratedMethods.get(nameParameters));
                        }
                    }
                    commonGeneratedMethods = toKeep;
                }
                //System.out.println("Common Methods:");
                List sortedMethodNames = new ArrayList(commonGeneratedMethods.keySet());
                Collections.sort(sortedMethodNames);
                List sortedMethods = new ArrayList(sortedMethodNames.size());
                for (Iterator sortedMethodNamesIterator = sortedMethodNames.iterator();
                     sortedMethodNamesIterator.hasNext(); ) {
                    sortedMethods.add(commonGeneratedMethods.get(sortedMethodNamesIterator.next()));
                }
                generateInterface(genDir, packageName,
                                  config.getGenerateCommonInterface(),
                                  sortedMethods,
                                  "This interface is the intersection of all generated methods.",
                                  null);
            }
            if (config.getDumpBeanTree() != null) {
                Writer out = new FileWriter(config.getDumpBeanTree());
                CodeGeneratorClass bc = (CodeGeneratorClass) generators.get(rootElement);
                bc.dumpBeanTree(out, "", config.getIndent());
                close(out);
            }
            if (config.isGenerateTagsFile()) {
                String tagsClassName = "Tags";
                while (illegalClassNames.containsKey(tagsClassName)) {
                    tagsClassName = UNIQUE_PREFIX + tagsClassName;
                }
                OutputStream out = config.getOutputStreamProvider().getStream(genDir, 
                                                                              tagsClassName, "java");	// NOI18N
                generateTagsFile(out, packageName, tagsClassName);
                close(out);
            }
        }
        if (config.getGenerateDotGraph() != null) {
            Writer out = new FileWriter(config.getGenerateDotGraph());
            generateDotGraph(out, rootElement.getGraphNode());
            close(out);
        }

        if (!config.isQuiet())
            config.messageOut.println(Common.getMessage("MSG_GenerationSummary",
                                                        rootElement.getDTDName(),
                                                        rootElement.getClassType()));
    }

    protected void processFinders(GraphNode rootGraphNode) {
        for (int i = 0, size = config.sizeFinder(); i < size; ++i) {
            String finderExpr = config.getFinder(i);
            processFinder(rootGraphNode, finderExpr);
        }
        MetaDD mdd = config.getMetaDD();
        for (Iterator it = mdd.fetchFinderList().iterator();
             it.hasNext(); ) {
            String finderExpr = (String) it.next();
            processFinder(rootGraphNode, finderExpr);
        }
    }

    protected void processFinder(GraphNode rootGraphNode, String finderExpr) {
        String rootName = rootGraphNode.getName();
        //System.out.println("finderExpr="+finderExpr);
        //
        // Parse finder expression: on _ find _ by _"
        //
        String onExpr = null;
        String findExpr = null;
        boolean isListFindExpr = false;
        String byExpr = null;
        StringTokenizer st = new StringTokenizer(finderExpr);
        while (st.hasMoreTokens()) {
            String token = st.nextToken().intern();
            if (token == "on")
                onExpr = st.nextToken();
            else if (token == "find") {
                findExpr = st.nextToken();
                isListFindExpr = false;
            } else if (token == "findall") {
                findExpr = st.nextToken();
                isListFindExpr = true;
            } else if (token == "by")
                byExpr = st.nextToken();
            else
                throw new IllegalArgumentException(Common.getMessage("MSG_BadTokenInFinder", token));
        }
        if (onExpr == null)
            throw new IllegalArgumentException(Common.getMessage("MSG_MissingOnExpression", finderExpr));

        if (onExpr.startsWith("/"+rootName)) {
            onExpr = onExpr.substring(rootName.length()+1, onExpr.length());
            if (onExpr.startsWith("/"))
                onExpr = onExpr.substring(1, onExpr.length());
        }
        //System.out.println("onExpr="+onExpr);
        GraphNode onNode = null;
        if (onExpr.equals("")) {
            // It's on the root
            onNode = rootGraphNode;
        } else {
            GraphLink gl = null;
            for (Iterator it = rootGraphNode.getGraphLink().xPathIterator(onExpr);
                 it.hasNext(); ) {
                gl = (GraphLink) it.next();
                if (gl == null)
                    break;
            }
            if (gl == null)
                throw new IllegalArgumentException(Common.getMessage("MSG_UnableToFindExpressionFromFinder", finderExpr));
            onNode = gl.element;
        }
        //System.out.println("onNode="+onNode);
        onNode.addExtraDataIncludeAlias(new Finder(findExpr, byExpr,
                                                   isListFindExpr));
    }

    protected void setSchemaType(GraphNode[] list) {
        Map nodeMap = new HashMap(list.length*4);
        for (int i  = 0; i < list.length; ++i) {
            nodeMap.put(list[i].getNameWithNamespace(), list[i]);
        }
        GraphNode emptyGraphNode = null;
        for (Iterator it = config.readBeanGraphs(); it.hasNext(); ) {
            org.netbeans.modules.schema2beansdev.beangraph.BeanGraph bg = (org.netbeans.modules.schema2beansdev.beangraph.BeanGraph) it.next();
            for (int i = 0; i < bg.sizeSchemaTypeMapping(); ++i) {
                org.netbeans.modules.schema2beansdev.beangraph.SchemaTypeMappingType stm = bg.getSchemaTypeMapping(i);
                String key;
                if (stm.getSchemaTypeNamespace() == null)
                    key = stm.getSchemaTypeName();
                else
                    key = "{"+stm.getSchemaTypeNamespace()+"}"+stm.getSchemaTypeName();
                if (nodeMap.containsKey(key)) {
                    GraphNode node = (GraphNode) nodeMap.get(key);
                    //System.out.println("Found match from beangraph: node="+node);
                    node.setJavaType(stm.getJavaType());
                    node.setCreated(false);
                    if (stm.isCanBeEmpty()) {
                        node.setExtendedProperty("can-be-empty", Boolean.TRUE);
                    }
                }
            }
        }
    }

    protected void generateInterface(String genDir, String packageName,
                                     String name, List methods,
                                     String comments,
                                     String extendsStatement) throws IOException {
        JavaWriter jw = new JavaWriter();
        jw.bigComment(comments+"\n\n@"+Common.GENERATED_TAG);
        jw.cr();
        if (!(packageName == null || "".equals(packageName))) {
            jw.writePackage(packageName);
            jw.cr();
        }
        jw.writeAccess(jw.PUBLIC);
        jw.write(" interface ");
        jw.write(name);
        jw.write(" ");
        if (extendsStatement != null)
            jw.write("extends ", extendsStatement, " ");
        jw.begin();
        for (Iterator methodsIterator = methods.iterator(); methodsIterator.hasNext(); ) {
            JavaWriter.Method method = (JavaWriter.Method) methodsIterator.next();
            method.writeMethod(jw);
            jw.eol();
            jw.cr();
        }
        jw.end();
        try {
            OutputStream out;
            out = config.getOutputStreamProvider().getStream(genDir, 
                                                        name, "java");	// NOI18N
            jw.writeTo(out);
            close(out);
        } catch(IOException ioe) {
            config.messageOut.println("Failed to generate interface: "+name);	// NOI18N
            TraceLogger.error(ioe);
            throw ioe;
        }
    }

    protected BeanGraph generateBeanGraph(GraphNode[] list) {
        BeanGraph bg = new BeanGraph();
        for (int i = 0; i < list.length; ++i) {
            GraphNode node = list[i];
            BeanElement be = (BeanElement)node.getObject();
            SchemaTypeMappingType stm =
                new SchemaTypeMappingType(node.getName(),
                                          be.getFullClassType());
            stm.setRoot(be.isRoot());
            stm.setBean(be.isBean());
            stm.setCanBeEmpty(be.getCanBeEmpty());
            stm.setSchemaTypeNamespace(node.getNamespace());
            bg.addSchemaTypeMapping(stm);
        }
        return bg;
    }

    /**
     * Generate a .dot file for the dot or dotty program to run with.
     * This is primarily useful for debugging the graph that the schema parser
     * created for us.  See http://www.graphviz.org
     */
    protected void generateDotGraph(Writer out, GraphNode node) throws IOException {
        out.write("digraph \""+node.getName()+"\" {\n");
        out.write("\t\""+node.getName()+"\" [shape=box]\n");
        out.write("\t\""+node.getName()+"\" -> \""+node.getGraphLink()+"\";\n");
        generateDotGraph(out, node.getGraphLink(), new HashMap());
        out.write("}\n");
    }

    protected void generateDotGraph(Writer out, List children, Map doneLinks) throws IOException {
        for (Iterator it = children.iterator(); it.hasNext(); ) {
            GraphLink l = (GraphLink) it.next();
            generateDotGraph(out, l, doneLinks);
        }
    }
    
    protected void generateDotGraph(Writer out, GraphLink l, Map doneLinks) throws IOException {
        if (l == null)
            return;
        doneLinks.put(l, null);
        out.write("\t\""+l+"\" [label=\""+dotGraphLabel(l)+"\"];\n");
        GraphNode node = l.element;
        if (node != null) {
            BeanBuilder.BeanElement be =
                (BeanBuilder.BeanElement)node.getObject();
            if (be == null)
                return;

            String type = be.getClassType();
            out.write("\t\""+node+"\" [label=\""+dotGraphLabel(node)+"\", shape=box];\n");
            out.write("\t\""+l+"\" -> \""+node+"\" [label=\"type of property\", color=darkgreen];\n");
            if ("#PCDATA".equals(l.name) && "String".equals(type)) {
                return;
            }
            AttrProp[] attrs = node.getAttributes();
            for (int i = 0; i < attrs.length; ++i) {
                String attrName = node.getName()+" attribute "+attrs[i].getName();
                out.write("\t\""+attrName+"\" [label=\""+dotGraphLabel(attrs[i])+"\", shape=egg];\n");
                out.write("\t\""+node+"\" -> \""+attrName+"\" [label=\"attribute\", color=magenta];\n");
            }

            GraphLink hasAttr = node.getGraphLink();
            if (hasAttr != null) {
                if (node.getMarked() == false ) {
                    if ((config.isTraceDot() || hasData(hasAttr)) && !doneLinks.containsKey(hasAttr)) {
                        out.write("\t\""+node+"\" -> \""+hasAttr+"\" [label=\"has attr\", color=purple];\n");
                        node.setMarked(true);
                        generateDotGraph(out, hasAttr, doneLinks);
                        node.setMarked(false);
                    }
                }
            }
        }

        List children = l.getChildren();
        for (Iterator childIt = children.iterator(); childIt.hasNext(); ) {
            GraphLink child = (GraphLink) childIt.next();
            out.write("\t\""+l+"\" -> \""+child+"\" [label=child, color=blue];\n");
        }
        generateDotGraph(out, children, doneLinks);

        /*
          GraphLink sibling = l.getSibling();
          if (sibling != null) {
          while (!config.isTraceDot() && sibling.name == null &&
          sibling.getFirstChild() == null &&
          sibling.getSibling() != null)
          sibling = sibling.getSibling();
          out.write("\t\""+l+"\" -> \""+sibling+"\" [label=sibling, color=red];\n");
          }
        */
    }

    private String dotGraphLabel(GraphLink l) {
        if (config.isTraceDot()) {
            String elementInstance = TreeBuilder.instanceToString(l.getElementInstance(), true);
            String groupInstance = TreeBuilder.instanceToString(l.getGroupInstance(), true);
            String result = "GraphLink@"+Integer.toHexString(l.hashCode());
            if (l.name == null)
                result += " (grouping)";
            else
                result += ":"+l.name;
            result += "\\n";
            if (!"".equals(elementInstance))
                result += " element: "+elementInstance;
            if (!"".equals(groupInstance))
                result += " group: "+groupInstance;
            if (l.isSequenceAnd())
                result += " ,";
            if (l.isSequenceOr())
                result += " |";
            return result;
        } else if (l.name == null)
            return "GraphLink";
        else
            return "property: "+l.name;
    }

    private String dotGraphLabel(GraphNode node) {
        String result;
        if (config.isTraceDot())
            result = "GraphNode@"+Integer.toHexString(node.hashCode())+":"+node.toString();
        else
            result = node.getName();
        if (node.getJavaType() != null)
            result += ":" + node.getJavaType();
        return result;
    }

    private String dotGraphLabel(AttrProp attr) {
        return attr.toString();
    }

    private boolean hasData(GraphLink l) {
        for (; l != null; l = l.getSibling()) {
            if (l.name != null)
                return true;
            if (l.element != null) {
                return true;
            }
            if (l.getFirstChild() != null)
                if (hasData(l.getFirstChild()))
                    return true;
        }
        return false;
    }

    protected void generateTagsFile(OutputStream out,
                                    String packageName, String className) throws IOException {
        JavaWriter jw = new JavaWriter();
        jw.bigComment("This class has all element and attribute names as constants.\n\n@"+Common.GENERATED_TAG);
        jw.cr();
        jw.writePackage(packageName);
        jw.cr();

        jw.writeClassDecl(className, null, null, jw.PUBLIC);
        jw.select(jw.DECL_SECTION);

        for (Iterator it = constNameMap.keySet().iterator(); it.hasNext(); ) {
            String constName = (String) it.next();
            String dtdName = (String) constNameMap.get(constName);
            jw.write("public final static String ", constName, " = ");
            jw.writeEol("\"", dtdName, "\"");
        }
        jw.cr();

        jw.select(jw.CONSTRUCTOR_SECTION);
        jw.comment("This class is not to be instantiated.");
        jw.beginConstructor(className, "", null, jw.PRIVATE);
        jw.end();
        
        jw.writeTo(out);
    }

    /**
     * Search in the MetaDD @mdd for @dtdName
     */
    private MetaElement getMetaElement(MetaDD mdd, String dtdName) {
        return getMetaElement(mdd, dtdName, null);
    }

    private MetaElement getMetaElement(MetaDD mdd, String dtdName, String namespace) {
        if (mdd == null)
            return null;
        int size = mdd.sizeMetaElement();
        for (int i=0; i= 0) {
            String impl = implList.substring(0, pos);
            impl = impl.trim();
            if (impl.equals(interfce))
                return;
            implList = implList.substring(pos+1, implList.length());
            implList = implList.trim();
            pos = implList.indexOf(',');
        }
        if (implList.equals(interfce))
            return;

        //
        // It's a new interface, add it on in.
        //
        e.setImplements(e.getImplements()+", "+interfce);
    }

    protected void close(OutputStream out) throws java.io.IOException {
        out.close();
        if (!config.isQuiet() && config.isTraceGen() &&
            out instanceof org.netbeans.modules.schema2beansdev.gen.WriteIfDifferentOutputStream) {
            org.netbeans.modules.schema2beansdev.gen.WriteIfDifferentOutputStream widos = (org.netbeans.modules.schema2beansdev.gen.WriteIfDifferentOutputStream) out;
            if (!widos.isChanged())
                config.messageOut.println(Common.getMessage("MSG_DidNotChangeFile"));
        }
    }

    protected void close(Writer out) throws java.io.IOException {
        out.close();
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.