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.schema2beansdev.gen.JavaUtil;
import org.netbeans.modules.schema2beansdev.gen.WriteIfDifferentOutputStream;
import org.netbeans.modules.schema2beans.Common;
import org.netbeans.modules.schema2beans.Schema2BeansException;
import org.netbeans.modules.schema2beans.Schema2BeansNestedException;
import org.netbeans.modules.schema2beans.DDLogFlags;
import org.netbeans.modules.schema2beans.Version;
import org.netbeans.modules.schema2beansdev.metadd.MetaDD;

//******************************************************************************
// BEGIN_NOI18N
//******************************************************************************

/**
 * This class provides the generation entry point.
 */
public class GenBeans {
    public static final String COMMON_BEAN = "CommonBean";
    /**
     * The OutputStreamProvider interface is a way of abstracting
     * how we get an OutputStream given a filename.  If GenBeans is being
     * run as part of the IDE, OutputStream's come from different places
     * than just opening up a regular File.  This is intended for the
     * writing of the generated files.
     * The caller of getStream will eventually run .close on the OutputStream
     */
    static public interface OutputStreamProvider {
        public OutputStream getStream(String dir, String name,
                                      String extension)
            throws java.io.IOException;

        /**
         * Returns true if the file in question is more older than the
         * given time.  @see java.io.File.lastModified
         */
        public boolean isOlderThan(String dir, String name, String extension,
                                   long time) throws java.io.IOException;
    }
    
    static public class DefaultOutputStreamProvider implements OutputStreamProvider {
        private Config config;
        private List generatedFiles;
        
        public DefaultOutputStreamProvider(Config config) {
            this.config = config;
            this.generatedFiles = new LinkedList();
        }

        private String getFilename(String dir, String name, String extension) {
            return dir + "/" + name + "." + extension;	// NOI18N
        }
        
        public OutputStream getStream(String dir, String name,
                                      String extension)
            throws java.io.IOException {
            String filename = getFilename(dir, name, extension);
            if (!config.isQuiet())
                config.messageOut.println(Common.getMessage("MSG_GeneratingClass", filename));	// NOI18N
            generatedFiles.add(filename);
            //return new FileOutputStream(filename);
            return new WriteIfDifferentOutputStream(filename);
        }

        public boolean isOlderThan(String dir, String name, String extension,
                                   long time) throws java.io.IOException {
            String filename = getFilename(dir, name, extension);
            File f = new File(filename);
            //System.out.println("filename="+filename+" lm="+f.lastModified());
            return f.lastModified() < time;
        }

        public List getGeneratedFiles() {
            return generatedFiles;
        }
    }

    static public class Config extends S2bConfig {
        // What kind of schema is it coming in
        public static final int XML_SCHEMA = 0;
        public static final int DTD = 1;
        /*
        int schemaType;

        private boolean		traceParse = false;
        private boolean		traceGen = false;
        private boolean		traceMisc = false;
        private boolean		traceDot = false;
	
        // filename is the name of the schema (eg, DTD) input file
        String 		filename = null;
        // fileIn is an InputStream version of filename (the source schema).
        // If fileIn is set, then filename is ignored.
        InputStream 	fileIn;
        String 		docroot;
        String 		rootDir = ".";
        String 		packagePath;
        String		indent = "\t";
        String 		mddFile;
        // If mddIn is set, then the mdd file is read from there and
        // we don't write our own.
        InputStream 	mddIn;
        private MetaDD mdd;
        boolean doGeneration = true;
        boolean		scalarException;
        boolean		dumpToString;
        boolean		vetoable;	// enable veto events
        boolean		standalone;
        // auto is set when it is assumed that there is no user sitting
        // in front of System.in
        boolean     	auto;
        // outputStreamProvider, be default, is null, which means that
        // we use standard java.io.* calls to get the OutputStream
        OutputStreamProvider outputStreamProvider;
        boolean     throwErrors;

        // Whether or not to generate classes that do XML I/O.
        boolean generateXMLIO;

        // Whether or not to generate code to do validation
        boolean generateValidate;

        // Whether or not to generate property events
        boolean generatePropertyEvents;

        // Whether or not to generate code to be able to store events
        boolean generateStoreEvents;

        boolean generateTransactions;

        boolean attributesAsProperties;

        //
        boolean generateDelegator = false;

        String generateCommonInterface = null;

        boolean defaultsAccessable = false;

        private boolean useInterfaces = false;

        // Generate an interface for the bean info accessors
        private boolean generateInterfaces = false;

        private boolean keepElementPositions = false;

        private boolean removeUnreferencedNodes = false;

        // If we're passed in a simple InputStream, then the inputURI will
        // help us find relative URI's if anything gets included for imported.
        private String inputURI;

        // This is the name of the class to use for indexed properties.
        // It must implement java.util.List
        // Use null to mean use arrays.
        private String indexedPropertyType;

        private boolean doCompile = false;

        private String dumpBeanTree = null;

        private String generateDotGraph = null;

        private boolean processComments = false;

        private boolean processDocType = false;

        private boolean checkUpToDate = false;

        private boolean generateParentRefs = false;

        private boolean generateHasChanged = false;

        // Of all our source files, newestSourceTime represents the most
        // recently modified one.
        private long newestSourceTime = 0;

        private String writeBeanGraphFilename;

        private List readBeanGraphFilenames = new ArrayList();
        private List readBeanGraphs = new ArrayList();

        private boolean minFeatures = false;

        private boolean forME = false;

        private boolean generateTagsFile = false;
        private CodeGeneratorFactory codeGeneratorFactory;
        */
        // What should we generate
        public static final int OUTPUT_TRADITIONAL_BASEBEAN = 0;
        public static final int OUTPUT_JAVABEANS = 1;
	
        PrintStream 	messageOut;

        public Config() {
            setOutputStreamProvider(new DefaultOutputStreamProvider(this));
            setSchemaTypeNum(DTD);
            setMessageOut(System.out);
            /*
            attributesAsProperties = false;
            indexedPropertyType = "java.util.ArrayList";
            inputURI = null;
            mddFile = null;
            scalarException = true;
            dumpToString = false;
            vetoable = false;
            standalone = false;
            auto = false;
            mddIn = null;*/
        }

        public Config(OutputStreamProvider out) {
            setOutputStreamProvider(out);
            setSchemaTypeNum(DTD);
            setMessageOut(System.out);
        }

        public void readConfigs() throws java.io.IOException {
            long newestSourceTime = getNewestSourceTime();
            File[] readConfigs = getReadConfig();
            for (int i = 0; i < readConfigs.length; ++i) {
                try {
                    File configFile = readConfigs[i];
                    org.xml.sax.InputSource in = new org.xml.sax.InputSource(new FileInputStream(configFile));
                    javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
                    javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
                    org.w3c.dom.Document doc = db.parse(in);
                    readNode(doc.getDocumentElement());
                } catch (javax.xml.parsers.ParserConfigurationException e) {
                    throw new RuntimeException(e);
                } catch (org.xml.sax.SAXException e) {
                    throw new RuntimeException(e);
                }
            }
            setNewestSourceTime(newestSourceTime);
        }

        protected int unknownArgument(String[] args, String arg, int argNum) {
            if (arg == "-t") {
                arg = args[++argNum];
                if (arg.equalsIgnoreCase("parse"))
                    setTraceParse(true);
                else if (arg.equalsIgnoreCase("gen"))
                    setTraceGen(true);
                else if (arg.equalsIgnoreCase("dot"))
                    setTraceDot(true);
                else {
                    if (!arg.equalsIgnoreCase("all"))
                        --argNum;  // unknown value, trace all, and rethink that option
                    setTraceParse(true);
                    setTraceGen(true);
                    setTraceMisc(true);
                    setTraceDot(true);
                }
            } else if (arg == "-version") {
                messageOut.println("schema2beans - " + Version.getVersion());
                System.exit(0);
            } else if (arg == "-xmlschema")
                setSchemaTypeNum(XML_SCHEMA);
            else if (arg == "-dtd")
                setSchemaTypeNum(DTD);
            else if (arg == "-premium")
                buyPremium();
            else if (arg == "-strict")
                useStrict();
            else if (arg == "-basebean") {
                setOutputType(OUTPUT_TRADITIONAL_BASEBEAN);
            } else if (arg == "-javabeans")
                setOutputType(OUTPUT_JAVABEANS);
            else if (arg == "-commoninterface")
                setGenerateCommonInterface(COMMON_BEAN);
            else if (arg == "-nocommoninterface")
                setGenerateCommonInterface(null);
            else {
                messageOut.println("Unknown argument: "+arg);
                messageOut.println("Use -help.");
                System.exit(1);
            }
            return argNum;
        }

        public void showHelp(java.io.PrintStream out) {
            super.showHelp(out);
            out.println(" -version\tPrint version info");
            out.println(" -xmlschema\tXML Schema input mode");
            out.println(" -dtd\tDTD input mode (default)");
            out.println(" -javaBeans\tGenerate pure JavaBeans that do not need any runtime library support (no BaseBean).");
            out.println(" -baseBean\tForce use of BaseBean.  Runtime required.");
            out.println(" -commonInterface\tGenerate a common interface between all beans.");
            out.println(" -premium The \"Premium\" Package.  Turn on what ought to be the default switches (but can't be the default due to backwards compatibility).");
            out.println(" -strict The \"Strict\" Package.  For those who are more concerned with correctness than backwards compatibility.  Turn on what ought to be the default switches (but can't be the default due to backwards compatibility).  Very similar to -premium.");
            out.println(" -no*\tAny switch that does not take an argument has a -no variant that will turn it off.");
            out.println("\nThe bean classes are generated in the directory rootDir/packagePath, where packagePath is built using the package name specified. If the package name is not specified, the doc root element value is used as the default package name.  Use the empty string to get no (default) package.");
            out.println("\nexamples: java GenBeans -f ejb.dtd");
            out.println("          java GenBeans -f webapp.dtd -d webapp -p myproject.webapp -r /myPath/src");
            out.println("          java GenBeans -f webapp.xsd -xmlschema -r /myPath/src -premium");
            out.println("\nMost of the parameters are optional. Only the file name is mandatory.");
            out.println("With only the file name specified, the generator uses the current directory, and uses the schema docroot value as the package name.");
        }
        
        public void setMessageOut(PrintStream messageOut) {
            this.messageOut = messageOut;
            super.setMessageOut(messageOut);
        }
	
        public void setOutputType(int type) {
            if (type == OUTPUT_JAVABEANS) {
                setCodeGeneratorFactory(JavaBeansFactory.newInstance());
                setAttributesAsProperties(true);
            } else if (type == OUTPUT_TRADITIONAL_BASEBEAN) {
                if (false) {
                    // Force extendBaseBean option
                    setOutputType(OUTPUT_JAVABEANS);
                    setExtendBaseBean(true);
                } else {
                    setCodeGeneratorFactory(null);
                    setProcessComments(false);  // we already do it anyway
                }
            } else {
                throw new IllegalArgumentException("type != OUTPUT_JAVABEANS && type != OUTPUT_TRADITIONAL_BASEBEAN");	// NOI18N
            }
        }

        public CodeGeneratorFactory getCodeGeneratorFactory() {
            if (super.getCodeGeneratorFactory() == null)
                setCodeGeneratorFactory(BaseBeansFactory.newInstance());
            return super.getCodeGeneratorFactory();
        }

        public void setPackagePath(String pkg) {
            if (pkg.equals("."))
                pkg = "";
            else
                pkg = pkg.replace('.', '/');
            super.setPackagePath(pkg);
        }

        public boolean isTrace() {
            return isTraceParse() || isTraceGen() || isTraceMisc();
        }

        public void setTraceGen(boolean value) {
            super.setTraceGen(value);
            DDLogFlags.debug = value;
        }

        void setIfNewerSourceTime(long t) {
            //System.out.println("setIfNewerSourceTime: newestSourceTime="+newestSourceTime+" t="+t);
            if (t > getNewestSourceTime())
                setNewestSourceTime(t);
        }
        /*
        public void setOutputStreamProvider(OutputStreamProvider outputStreamProvider) {
            this.outputStreamProvider = outputStreamProvider;
        }

        public void setWriteBeanGraph(String filename) {
            writeBeanGraphFilename = filename;
        }

        public String getWriteBeanGraph() {
            return writeBeanGraphFilename;
        }

        public void addReadBeanGraphFilename(String filename) {
            readBeanGraphFilenames.add(filename);
        }

        public Iterator readBeanGraphFilenames() {
            return readBeanGraphFilenames.iterator();
            }

        public void addReadBeanGraph(org.netbeans.modules.schema2beansdev.beangraph.BeanGraph bg) {
            readBeanGraphs.add(bg);
        }
        */

        public Iterator readBeanGraphs() {
            return fetchReadBeanGraphsList().iterator();
        }

        public Iterator readBeanGraphFiles() {
            return fetchReadBeanGraphFilesList().iterator();
        }

        public int getSchemaTypeNum() {
            if ("xmlschema".equalsIgnoreCase(getSchemaType()))
                return XML_SCHEMA;
            if ("dtd".equalsIgnoreCase(getSchemaType()))
                return DTD;
            throw new IllegalStateException(Common.getMessage("MSG_IllegalSchemaName", getSchemaType()));
        }

        public void setSchemaType(int type) {
            setSchemaTypeNum(type);
        }
        
        public void setSchemaTypeNum(int type) {
            if (type == XML_SCHEMA)
                setSchemaType("xmlschema");
            else if (type == DTD)
                setSchemaType("dtd");
            else
                throw new IllegalStateException("illegal schema type: "+type);
        }

        /**
         * @deprecated  use setMddIn instead
         */
        public void setMDDIn(java.io.InputStream value) {
            setMddIn(value);
        }

        /**
         * @deprecated  use setFileIn instead
         */
        public void setDTDIn(java.io.InputStream value) {
            setFileIn(value);
        }

        public void setRootDir(String dir) {
            setRootDir(new File(dir));
        }

        public void setIndexedPropertyType(String className) {
            if ("".equals(className))
                className = null;  // use arrays
            super.setIndexedPropertyType(className);
        }

        public void setForME(boolean value) {
            super.setForME(value);
            if (value) {
                setOutputType(OUTPUT_JAVABEANS);
                setGeneratePropertyEvents(false);
                setIndexedPropertyType(null);
            }
        }

        /**
         * Turn on a bunch of the great switches that arn't on by default.
         */
        public void buyPremium() {
            setSetDefaults(true);
            setStandalone(true);
            setDumpToString(true);
            setThrowErrors(true);
            setGenerateXMLIO(true);
            setGenerateValidate(true);
            setAttributesAsProperties(true);
            setGenerateInterfaces(true);
            setGenerateCommonInterface(COMMON_BEAN);
            setOutputType(OUTPUT_JAVABEANS);
        }

        /**
         * For those who are more concerned with correctness than
         * backwards compatibility.
         */
        public void useStrict() {
            setSetDefaults(true);
            setStandalone(true);
            setDumpToString(true);
            setThrowErrors(true);
            setGenerateXMLIO(true);
            setGenerateValidate(true);
            setAttributesAsProperties(true);
            setOutputType(OUTPUT_JAVABEANS);
        }

        public void setMinFeatures(boolean value) {
            super.setMinFeatures(value);
            if (value) {
                setOutputType(OUTPUT_JAVABEANS);
                setGenerateXMLIO(false);
                setGenerateValidate(false);
                setGenerateInterfaces(false);
                setGenerateCommonInterface(null);
                setGeneratePropertyEvents(false);
                setGenerateStoreEvents(false);
                setGenerateTransactions(false);
                setDefaultsAccessable(false);
                setKeepElementPositions(false);
                setRemoveUnreferencedNodes(true);
                setProcessComments(false);
                setProcessDocType(false);
                setGenerateParentRefs(false);
                setGenerateHasChanged(false);
            }
        }

        public void setExtendBaseBean(boolean value) {
            super.setExtendBaseBean(value);
            if (value) {
                setUseRuntime(true);
                setGenerateParentRefs(true);
                setGenerateValidate(true);
                setGeneratePropertyEvents(true);
                setProcessComments(true);
                setProcessDocType(true);
            }
        }
    }

    //	Entry point - print help and call the parser
    public static void main(String args[]) {
        GenBeans.Config config = new GenBeans.Config();
	
        if (config.parseArguments(args)) {
            config.showHelp(System.out);
            return;
        }
        /*
        if (config.getFilename() == null) {
            config.showHelp(System.out);
            return;
        }
          try {
          for (int i=0; i 0) {
            config.setIndent("");
            for(int i = 0; i < config.getIndentAmount(); i++)
                config.setIndent(config.getIndent()+" ");
        }
        if (config.isGenerateTransactions()) {
            config.setGeneratePropertyEvents(true);
            config.setGenerateStoreEvents(true);
        } else if (!config.isGeneratePropertyEvents() && config.isGenerateStoreEvents())
            config.setGenerateStoreEvents(false);
        if (config.isGenerateHasChanged())
            config.setGenerateParentRefs(true);

        config.readConfigs();
        if (config.getWriteConfig() != null) {
            config.write(new FileOutputStream(config.getWriteConfig()));
        }
    }

    private static void readBeanGraphs(Config config) throws IOException {
        try {
            for (Iterator it = config.readBeanGraphFiles(); it.hasNext(); ) {
                File filename = (File) it.next();
                InputStream in = new FileInputStream(filename);
                org.netbeans.modules.schema2beansdev.beangraph.BeanGraph bg = org.netbeans.modules.schema2beansdev.beangraph.BeanGraph.read(in);
                in.close();
                config.addReadBeanGraphs(bg);
            }
        } catch (javax.xml.parsers.ParserConfigurationException e) {
            throw new RuntimeException(e);
        } catch (org.xml.sax.SAXException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @return whether or not the MetaDD should be written out at the end.
     */
    private static boolean processMetaDD(Config config) throws IOException {
        boolean needToWriteMetaDD = false;
        MetaDD mdd;
        //
        //	Either creates the metaDD file or read the existing one
        //
        if (config.getMddFile() != null || config.getMddIn() != null) {
            File file = config.getMddFile();
	    
            if (config.getMddIn() == null && !file.exists()) {
                config.setDoGeneration(false);
                if (!config.isAuto()) {
                    if (!askYesOrNo(config.messageOut, "The mdd file " + config.getMddFile() +	// NOI18N
                                    " doesn't exist. Should we create it (y/n)? "))	{ // NOI18N
                        config.messageOut.println("Generation aborted."); // NOI18N
                        return false;
                    }
                }
                needToWriteMetaDD = true;
                mdd = new MetaDD();
            } else {
                try {
                    InputStream is = config.getMddIn();
                    if (config.getMddIn() == null) {
                        is = new FileInputStream(config.getMddFile());
                        config.messageOut.println(Common.getMessage("MSG_UsingMdd",
                                                                    config.getMddFile()));
                    }
                    mdd = MetaDD.read(is);
                    if (config.getMddIn() == null) {
                        is.close();
                    }
                } catch (IOException e) {
                    if (config.isTraceParse())
                        e.printStackTrace();
                    throw new IOException(Common.
                                          getMessage("CantCreateMetaDDFile_msg", e.getMessage()));
                } catch (javax.xml.parsers.ParserConfigurationException e) {
                    if (config.isTraceParse())
                        e.printStackTrace();
                    throw new IOException(Common.
                                          getMessage("CantCreateMetaDDFile_msg", e.getMessage()));
                } catch (org.xml.sax.SAXException e) {
                    if (config.isTraceParse())
                        e.printStackTrace();
                    throw new IOException(Common.
                                          getMessage("CantCreateMetaDDFile_msg", e.getMessage()));
                }
            }
        } else {
            // Create a MetaDD to look stuff up in later on, even though
            // it wasn't read in, and we're not going to write it out.
            mdd = new MetaDD();
        }
        config.setMetaDD(mdd);
        return needToWriteMetaDD;
    }

    private static boolean askYesOrNo(PrintStream out, String prompt) throws IOException {
        out.print(prompt);
        BufferedReader rd =
			new BufferedReader(new InputStreamReader(System.in));
		    
        String str;
        str = rd.readLine();
        
        return str.equalsIgnoreCase("y");	// NOI18N
    }

    private static void calculateNewestSourceTime(Config config) {
        if (config.getFilename() != null) {
            config.setIfNewerSourceTime(config.getFilename().lastModified());
        }
        if (config.getMddFile() != null) {
            config.setIfNewerSourceTime(config.getMddFile().lastModified());
        }
        for (Iterator it = config.readBeanGraphFiles(); it.hasNext(); ) {
            File f = (File) it.next();
            config.setIfNewerSourceTime(f.lastModified());
        }

        // Need to also check the times on schema2beans.jar & schema2beansdev.jar
        config.setIfNewerSourceTime(getLastModified(org.netbeans.modules.schema2beans.BaseBean.class));
        config.setIfNewerSourceTime(getLastModified(BeanClass.class));
        config.setIfNewerSourceTime(getLastModified(GenBeans.class));
        config.setIfNewerSourceTime(getLastModified(BeanBuilder.class));
        config.setIfNewerSourceTime(getLastModified(TreeBuilder.class));
        config.setIfNewerSourceTime(getLastModified(GraphLink.class));
        config.setIfNewerSourceTime(getLastModified(GraphNode.class));
        config.setIfNewerSourceTime(getLastModified(JavaBeanClass.class));
        //System.out.println("config.getNewestSourceTime="+config.getNewestSourceTime());
    }

    private static long getLastModified(Class cls) {
        try {
            String shortName = cls.getName().substring(1+cls.getName().lastIndexOf('.'));
            java.net.URL url = cls.getResource(shortName + ".class");
            String file = url.getFile();
            //System.out.println("url="+url);
            if ("file".equals(url.getProtocol())) {
                // example: file='/home/cliffwd/cvs/dublin/nb_all/schema2beans/rt/src/org/netbeans/modules/schema2beans/GenBeans.class'
                String result = file.substring(0, file.length() - cls.getName().length() - 6);
                return new File(file).lastModified();
            } else if ("jar".equals(url.getProtocol())) {
                // example: file = 'jar:/usr/local/j2sdkee1.3.1/lib/j2ee.jar!/org/w3c/dom/Node.class'
                String jarFile = file.substring(file.indexOf(':')+1);
                jarFile = jarFile.substring(0, jarFile.indexOf('!'));
                //System.out.println("jarFile="+jarFile);
                return new File(jarFile).lastModified();
            }
            return url.openConnection().getDate();
        } catch (java.io.IOException e) {
            return 0;
        }
    }
}

//******************************************************************************
// END_NOI18N
//******************************************************************************
... 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.