All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.xmlbeans.impl.tool.XMLBean Maven / Gradle / Ivy

There is a newer version: 5.0.22
Show newest version
/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.xmlbeans.impl.tool;

import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.taskdefs.Jar;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.FileScanner;
import org.apache.tools.ant.Project;

import java.io.File;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.util.*;
import java.net.URI;

import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.impl.common.IOUtil;

/**
 * Modeled after Ant's javac and zip tasks.
 *
 * Schema files to process, or directories of schema files, are set with the 'schema'
 * attribute, and can be filtered with 'includes' and 'excludes'.
 * Alternatively, one or more nested <fileset> elements can specify the
 * files and directories to be used to generate this XMLBean.
 * The include set can also define .java files that should be built as well.
 * See the FileSet documentation at http://jakarta.apache.org/ant/manual/index.html
 * for instructions on FileSets if you are unfamiliar with their usage.
 */

public class XMLBean extends MatchingTask
{
    private ArrayList   schemas = new ArrayList();

    private Set         mdefnamespaces;

    private Path        classpath;

    private File        destfile,
                        schema,
                        srcgendir,
                        classgendir;

    private boolean     quiet,
                        verbose,
                        debug,
                        optimize,
                        download,
                        srconly,
                        noupa,
                        nopvr,
                        noann,
                        novdoc,
                        noext = false,
                        failonerror = true,
                        fork = true,
                        includeAntRuntime = true,
                        noSrcRegen,
                        includeJavaRuntime = false,
                        nowarn = false;

    private String      typesystemname,
                        forkedExecutable,
                        compiler,
                        debugLevel,
                        memoryInitialSize,
                        memoryMaximumSize,
                        catalog,
                        javasource;

    private List        extensions = new ArrayList();

    private HashMap     _extRouter = new HashMap(5);

    private static final String XSD = ".xsd",
                                WSDL = ".wsdl",
                                JAVA = ".java",
                                XSDCONFIG = ".xsdconfig";


    public void execute() throws BuildException
    {
        /* VALIDATION */
        //required
        if (schemas.size() == 0
            && schema == null
            && fileset.getDir(project) == null)
        {
            String msg = "The 'schema' or 'dir' attribute or a nested fileset is required.";
            if (failonerror)
                throw new BuildException(msg);
            else
            {
                log(msg, Project.MSG_ERR);
                return;
            }
        }

        _extRouter.put(XSD, new HashSet());
        _extRouter.put(WSDL, new HashSet());
        _extRouter.put(JAVA, new HashSet());
        _extRouter.put(XSDCONFIG, new HashSet());

        File theBasedir = schema;

        if (schema != null)
        {
            if (schema.isDirectory())
            {
                FileScanner scanner = getDirectoryScanner(schema);
                String[] paths = scanner.getIncludedFiles();
                processPaths(paths, scanner.getBasedir());
            }
            else
            {
                theBasedir = schema.getParentFile();
                processPaths(new String[] { schema.getName() }, theBasedir);
            }
        }

        if (fileset.getDir(project) != null)
            schemas.add(fileset);

        Iterator si = schemas.iterator();
        while (si.hasNext())
        {
            FileSet fs = (FileSet) si.next();
            FileScanner scanner = fs.getDirectoryScanner(project);
            File basedir = scanner.getBasedir();
            String[] paths = scanner.getIncludedFiles();

            processPaths(paths, basedir);
        }

        Set xsdList = (Set) _extRouter.get(XSD);
        Set wsdlList = (Set) _extRouter.get(WSDL);

        if (xsdList.size() + wsdlList.size() == 0)
        {
            log("Could not find any xsd or wsdl files to process.", Project.MSG_WARN);
            return;
        }

        //optional
        Set javaList = (Set) _extRouter.get(JAVA);
        Set xsdconfigList = (Set) _extRouter.get(XSDCONFIG);

        if (srcgendir == null && srconly)
            srcgendir = classgendir;

        if (destfile == null && classgendir == null && ! srconly)
            destfile = new File("xmltypes.jar");

        if (verbose)
            quiet = false;

        /* EXECUTION */

        File[] xsdArray = (File[]) xsdList.toArray(new File[xsdList.size()]);
        File[] wsdlArray = (File[]) wsdlList.toArray(new File[wsdlList.size()]);
        File[] javaArray = (File[]) javaList.toArray(new File[javaList.size()]);
        File[] xsdconfigArray = (File[]) xsdconfigList.toArray(new File[xsdconfigList.size()]);
        ErrorLogger err = new ErrorLogger(verbose);

        boolean success = false;

        try
        {
            // create a temp directory
            File tmpdir = null;
            if (srcgendir == null || classgendir == null)
            {
                tmpdir = SchemaCodeGenerator.createTempDir();
            }
            if (srcgendir == null)
                srcgendir = IOUtil.createDir(tmpdir, "src");
            if (classgendir == null)
                classgendir = IOUtil.createDir(tmpdir, "classes");

            // use the system classpath if user didn't provide any
            if (classpath == null)
            {
                classpath = new Path(project);
                classpath.concatSystemClasspath();
            }

            // prepend the output directory on the classpath
            Path.PathElement pathElement = classpath.createPathElement();
            pathElement.setLocation(classgendir);

            String[] paths = classpath.list();
            File[] cp = new File[paths.length];
            for (int i = 0; i < paths.length; i++)
                cp[i] = new File(paths[i]);

            // generate the source
            SchemaCompiler.Parameters params = new SchemaCompiler.Parameters();
            params.setBaseDir(theBasedir);
            params.setXsdFiles(xsdArray);
            params.setWsdlFiles(wsdlArray);
            params.setJavaFiles(javaArray);
            params.setConfigFiles(xsdconfigArray);
            params.setClasspath(cp);
            params.setName(typesystemname);
            params.setSrcDir(srcgendir);
            params.setClassesDir(classgendir);
            params.setNojavac(true); // always compile using javac task below
            params.setDebug(debug);
            params.setVerbose(verbose);
            params.setQuiet(quiet);
            params.setDownload(download);
            params.setExtensions(extensions);
            params.setErrorListener(err);
            params.setCatalogFile(catalog);
            params.setIncrementalSrcGen(noSrcRegen);
            params.setMdefNamespaces(mdefnamespaces);
            params.setNoUpa(noupa);
            params.setNoPvr(nopvr);
            params.setNoAnn(noann);
            params.setNoVDoc(novdoc);
            params.setNoExt(noext);
            params.setJavaSource(javasource);
            success = SchemaCompiler.compile(params);

            if (success && !srconly) {
                long start = System.currentTimeMillis();

                // compile the source
                Javac javac = new Javac();
                javac.setProject(project);
                javac.setTaskName(getTaskName());
                javac.setClasspath(classpath);
                if (compiler != null) javac.setCompiler(compiler);
                javac.setDebug(debug);
                if (debugLevel != null) javac.setDebugLevel(debugLevel);
                javac.setDestdir(classgendir);
                javac.setExecutable(forkedExecutable);
                javac.setFailonerror(failonerror);
                javac.setFork(fork);
                if (javasource != null)
                {
                    javac.setSource(javasource);
                    javac.setTarget(javasource);
                }
                else
                {
                    javac.setSource("1.4");
                    javac.setTarget("1.4");
                }
                javac.setIncludeantruntime(includeAntRuntime);
                javac.setIncludejavaruntime(includeJavaRuntime);
                javac.setNowarn(nowarn);
                javac.setSrcdir(new Path(project, srcgendir.getAbsolutePath()));
                if (memoryInitialSize != null) javac.setMemoryInitialSize(memoryInitialSize);
                if (memoryMaximumSize != null) javac.setMemoryMaximumSize(memoryMaximumSize);
                javac.setOptimize(optimize);
                javac.setVerbose(verbose);
                javac.execute();

                long finish = System.currentTimeMillis();
                if (!quiet)
                    log("Time to compile code: " + ((double)(finish - start) / 1000.0) + " seconds");

                if (destfile != null)
                {
                    // jar the compiled classes
                    Jar jar = new Jar();
                    jar.setProject(project);
                    jar.setTaskName(getTaskName());
                    jar.setBasedir(classgendir);
                    jar.setDestFile(destfile);
                    jar.execute();
                }
            }

            if (tmpdir != null) {
                SchemaCodeGenerator.tryHardToDelete(tmpdir);
            }
        }
        catch (BuildException e)
        {
            // re-throw anything thrown from javac or jar task
            throw e;
        }
        catch (Throwable e)
        {
            //interrupted means cancel
            if (e instanceof InterruptedException || failonerror)
                throw new BuildException(e);
            
            log("Exception while building schemas: " + e.getMessage(), Project.MSG_ERR);
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            log(sw.toString(), Project.MSG_VERBOSE);
        }

        if (!success && failonerror)
            throw new BuildException(); //stop the build
    }

    private void processPaths(String[] paths, File baseDir)
    {
        for (int i = 0; i < paths.length; i++)
        {
            int dot = paths[i].lastIndexOf('.');
            if (dot > -1)
            {
                String path = paths[i];
                String possExt = path.substring(dot).toLowerCase();
                Set set = (Set) _extRouter.get(possExt);

                if (set != null)
                    set.add(new File(baseDir, path));
            }
        }
    }

    public void addFileset(FileSet fileset)
    {
        schemas.add(fileset);
    }

    /////////////////////////////
    //Getter/Setters
    public File getSchema()
    {
        return schema;
    }

    /**
     * A file that points to either an individual schema file or a directory of files.
     * It is optional only if one or more <fileset> elements are nested in this
     * task.
     * @param schema Required, unless a fileset element is nested.
     */
    public void setSchema(File schema)
    {
        this.schema = schema;
    }

    /**
     * The classpath to use if schemas in the fileset import definitions that are
     * supplied by other compiled xml beans JAR files, or if .java files are in the
     * schema fileset.
     * @param classpath Optional.
     */
    public void setClasspath(Path classpath)
    {
        if (this.classpath != null)
            this.classpath.append(classpath);
        else
            this.classpath = classpath;
    }

    /**
     * Adds a path to the classpath.
     */
    public Path createClasspath() {
        if (classpath == null) {
            classpath = new Path(project);
        }
        return classpath.createPath();
    }

    /**
     * Adds a reference to a classpath defined elsewhere.
     * @param classpathref Optional.
     */
    public void setClasspathRef(Reference classpathref)
    {
        if (classpath == null)
            classpath = new Path(project);

        classpath.createPath().setRefid(classpathref);
    }

    public Path getClasspath()
    {
        return classpath;
    }

    public File getDestfile()
    {
        return destfile;
    }

    /**
     * Define the name of the jar file created.  For instance, "myXMLBean.jar"
     * will output the results of this task into a jar with the same name.
     * Optional, defaults to "xmltypes.jar".
     * @param destfile Optional.
     */
    public void setDestfile(File destfile)
    {
        this.destfile = destfile;
    }

    public File getSrcgendir()
    {
        return srcgendir;
    }

    /**
     * Set a location to generate .java files into.  Optional, defaults to
     * a temp dir.
     * @param srcgendir Optional.
     */
    public void setSrcgendir(File srcgendir)
    {
        this.srcgendir = srcgendir;
    }

    public File getClassgendir()
    {
        return classgendir;
    }

    /**
     * Set a location to generate .class files into.  Optional, defaults to
     * a temp dir.
     * @param classgendir Optional.
     */
    public void setClassgendir(File classgendir)
    {
        this.classgendir = classgendir;
    }

    /**
     * Choose the implementation for this particular task.
     *
     * @since Ant 1.5
     */
    public void setCompiler(String compiler)
    {
        this.compiler = compiler;
    }

    public boolean isDownload()
    {
        return download;
    }

    /**
     * Set to true to permit the compiler to download URLs for imports
     * and includes.  Defaults to false, meaning all imports and includes
     * must be copied locally.
     * @param download Optional.
     */
    public void setDownload(boolean download)
    {
        this.download = download;
    }

    /**
     * If true, compiles with optimization enabled.
     */
    public void setOptimize(boolean optimize) {
        this.optimize = optimize;
    }

    /** Gets the optimize flag. */
    public boolean getOptimize() {
        return optimize;
    }

    public boolean isVerbose()
    {
        return verbose;
    }

    /**
     * Controls the amount of output.  Defaults to true.
     * @param verbose Optional.
     */
    public void setVerbose(boolean verbose)
    {
        this.verbose = verbose;
    }

    public boolean isQuiet()
    {
        return quiet;
    }

    /**
     * Controls the amount of output.  Defaults to false.
     * @param quiet Optional.
     */
    public void setQuiet(boolean quiet)
    {
        this.quiet = quiet;
    }

    public boolean isDebug()
    {
        return debug;
    }

    /**
     * Get the value of debugLevel.
     * @return value of debugLevel.
     */
    public String getDebugLevel() {
        return debugLevel;
    }

    /**
     * Keyword list to be appended to the -g command-line switch.
     *
     * This will be ignored by all implementations except modern
     * and classic(ver >= 1.2). Legal values are none or a
     * comma-separated list of the following keywords: lines, vars,
     * and source. If debuglevel is not specified, by default, :none
     * will be appended to -g. If debug is not turned on, this attribute
     * will be ignored.
     *
     * @param v  Value to assign to debugLevel.
     */
    public void setDebugLevel(String  v) {
        this.debugLevel = v;
    }

    /**
     * Generate debugging symbols.
     * @param debug Optional.
     */
    public void setDebug(boolean debug)
    {
        this.debug = debug;
    }

    /**
     * If true, forks the javac compiler.
     *
     * @param f "true|false|on|off|yes|no"
     */
    public void setFork(boolean f) {
        fork = f;
    }

    /**
     * Sets the the name of the javac executable.
     *
     * 

Ignored unless fork is true or extJavac has been specified * as the compiler.

*/ public void setExecutable(String forkExec) { forkedExecutable = forkExec; } public String getExecutable() { return forkedExecutable; } public boolean isSrconly() { return srconly; } /** * A value of true means that only source will be generated. Optional, * default is false. * @param srconly Optional. */ public void setSrconly(boolean srconly) { this.srconly = srconly; } public String getTypesystemname() { return typesystemname; } /** * One or more SchemaCompiler extensions can be passed in via the <extension> subelement. * Schema Compiler extensions must implement the interface com.xbean.too.SchemaCompilerExtension */ public Extension createExtension() { Extension e = new Extension(); extensions.add(e); return e; } /** * One or more namespaces in which duplicate definitions are to be ignored * can be passed in via the <ignoreDuplicatesInNamespaces> subelement. */ public void setIgnoreDuplicatesInNamespaces(String namespaces) { mdefnamespaces = new HashSet(); StringTokenizer st = new StringTokenizer(namespaces, ","); while (st.hasMoreTokens()) { String namespace = st.nextToken().trim(); mdefnamespaces.add(namespace); } } public String getIgnoreDuplicatesInNamespaces() { if (mdefnamespaces == null) { return null; } StringBuffer buf = new StringBuffer(); Iterator i = mdefnamespaces.iterator(); while (i.hasNext()) { buf.append((String)i.next()); if (i.hasNext()) { buf.append(","); } } return buf.toString(); } /** * The name of the package that the TypeSystemHolder class should be * generated in. Normally this should be left unspecified. None of * the xml beans are generated in this package. *

Use .xsdconfig files to modify xml bean package or class names. * @param typesystemname Optional. */ public void setTypesystemname(String typesystemname) { this.typesystemname = typesystemname; } public boolean isFailonerror() { return failonerror; } /** * Determines whether or not the ant target will continue if the XMLBean * creation encounters a build error. Defaults to true. Optional. * @param failonerror Optional. */ public void setFailonerror(boolean failonerror) { this.failonerror = failonerror; } public boolean isIncludeAntRuntime() { return includeAntRuntime; } public void setIncludeAntRuntime(boolean includeAntRuntime) { this.includeAntRuntime = includeAntRuntime; } public boolean isIncludeJavaRuntime() { return includeJavaRuntime; } public void setIncludeJavaRuntime(boolean includeJavaRuntime) { this.includeJavaRuntime = includeJavaRuntime; } public boolean isNowarn() { return nowarn; } public void setNowarn(boolean nowarn) { this.nowarn = nowarn; } public boolean isNoSrcRegen() { return noSrcRegen; } public void setNoSrcRegen(boolean noSrcRegen) { this.noSrcRegen = noSrcRegen; } /** * Set the initial memory size of the underlying javac process. */ public String getMemoryInitialSize() { return memoryInitialSize; } public void setMemoryInitialSize(String memoryInitialSize) { this.memoryInitialSize = memoryInitialSize; } /** * Set the maximum memory size of the underlying javac process. */ public String getMemoryMaximumSize() { return memoryMaximumSize; } public void setMemoryMaximumSize(String memoryMaximumSize) { this.memoryMaximumSize = memoryMaximumSize; } /** * Do not enforce the unique particle attribution rule. */ public void setNoUpa(boolean noupa) { this.noupa = noupa; } public boolean isNoUpa() { return noupa; } /** * Do not enforce the particle valid (restriction) rule. */ public void setNoPvr(boolean nopvr) { this.nopvr = nopvr; } public boolean isNoPvr() { return nopvr; } /** * Skip over schema <annotation%gt; elements. */ public void setNoAnnotations(boolean noann) { this.noann = noann; } public boolean isNoAnnotations() { return noann; } /** * Do not validate the contents of schema <documentation> elements. */ public void setNoValidateDoc(boolean novdoc) { this.novdoc = novdoc; } public boolean isNoValidateDoc() { return novdoc; } /** * Ignore extensions found in .xsdconfig files * @param novdoc */ public void setNoExt(boolean noext) { this.noext = noext; } public boolean isNoExt() { return noext; } /** * Generate java source compatible with the given version. Currently, * only "1.4" or "1.5" are supported and "1.4" is the default. */ public void setJavaSource(String javasource) { this.javasource = javasource; } public String getJavaSource() { return javasource; } //REVIEW this allows people to deal with the case where they drag in //more files for compilation than they should. not sure if this is //a good thing or not private String source = null; public void setSource(String s) { source = s; } /** * Gets the XML Catalog file for org.apache.xml.resolver.tools.CatalogResolver. (Note: needs resolver.jar from http://xml.apache.org/commons/components/resolver/index.html) */ public String getCatalog() { return catalog; } /** * Sets the XML Catalog file for org.apache.xml.resolver.tools.CatalogResolver. (Note: needs resolver.jar from http://xml.apache.org/commons/components/resolver/index.html) */ public void setCatalog(String catalog) { this.catalog = catalog; } private static URI uriFromFile(File f) { if (f == null) return null; try { return f.getCanonicalFile().toURI(); } catch(java.io.IOException e) { // Don't spit out an exception here because on Windows you'll get one // if the filename is "aux", "lpt1", etc. It's the caller's responsibility // to deal with those cases correctly, usually by calling FileSvc.invalidPathCheck() // MessageSvc.get().logException(e); return f.getAbsoluteFile().toURI(); } } public class ErrorLogger extends AbstractCollection { private boolean _noisy; private URI _baseURI; public ErrorLogger(boolean noisy) { _noisy = noisy; _baseURI = uriFromFile(project.getBaseDir()); } public boolean add(Object o) { if (o instanceof XmlError) { XmlError err = (XmlError)o; if (err.getSeverity() == XmlError.SEVERITY_ERROR) log(err.toString(_baseURI), Project.MSG_ERR); else if (err.getSeverity() == XmlError.SEVERITY_WARNING) log(err.toString(_baseURI), Project.MSG_WARN); else if (_noisy) log(err.toString(_baseURI), Project.MSG_INFO); } return false; } public Iterator iterator() { return Collections.EMPTY_LIST.iterator(); } public int size() { return 0; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy