001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.xbean.spring.generator;
018
019import org.apache.tools.ant.BuildException;
020import org.apache.tools.ant.taskdefs.MatchingTask;
021import org.apache.tools.ant.types.Path;
022
023import java.io.File;
024import java.util.Iterator;
025import java.util.Set;
026import java.util.List;
027import java.util.LinkedList;
028import java.util.Arrays;
029import java.util.Collections;
030import java.util.StringTokenizer;
031import java.beans.PropertyEditorManager;
032
033/**
034 * An Ant task for executing generating mapping metadata.
035 *
036 * @version $Revision: 434369 $
037 */
038public class MappingGeneratorTask extends MatchingTask implements LogFacade {
039    private String namespace;
040    private Path srcDir;
041    private String excludedClasses = null;
042    private File destFile = new File("target/classes/schema.xsd");
043    private String metaInfDir = "target/classes/";
044    private String propertyEditorPaths = "org.apache.xbean.spring.context.impl";
045
046    public File getDestFile() {
047        return destFile;
048    }
049
050    public void setDestFile(File destFile) {
051        this.destFile = destFile;
052    }
053
054    public String getMetaInfDir() {
055        return metaInfDir;
056    }
057
058    public void setMetaInfDir(String metaInfDir) {
059        this.metaInfDir = metaInfDir;
060    }
061
062    public String getNamespace() {
063        return namespace;
064    }
065
066    public void setNamespace(String namespace) {
067        this.namespace = namespace;
068    }
069
070    public Path getSrcDir() {
071        return srcDir;
072    }
073
074    public void setSrcDir(Path srcDir) {
075        this.srcDir = srcDir;
076    }
077
078    public String getPropertyEditorPaths() {
079        return propertyEditorPaths;
080    }
081
082    public void setPropertyEditorPaths(String propertyEditorPaths) {
083        this.propertyEditorPaths = propertyEditorPaths;
084    }
085
086    public void execute() throws BuildException {
087        if (namespace == null) {
088            throw new BuildException("'namespace' must be specified");
089        }
090        if (srcDir == null) {
091            throw new BuildException("'srcDir' must be specified");
092        }
093        if (destFile == null) {
094            throw new BuildException("'destFile' must be specified");
095        }
096
097        if (propertyEditorPaths != null) {
098            List editorSearchPath = new LinkedList(Arrays.asList(PropertyEditorManager.getEditorSearchPath()));
099            StringTokenizer paths = new StringTokenizer(propertyEditorPaths, " ,");
100            editorSearchPath.addAll(Collections.list(paths));
101            PropertyEditorManager.setEditorSearchPath((String[]) editorSearchPath.toArray(new String[editorSearchPath.size()]));
102        }
103
104        ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
105        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
106        try {
107            String[] excludedClasses = null;
108            if (this.excludedClasses != null) {
109                excludedClasses = this.excludedClasses.split(" *, *");
110            }
111            MappingLoader mappingLoader = new QdoxMappingLoader(namespace, getFiles(srcDir), excludedClasses);
112
113            GeneratorPlugin[] plugins = new GeneratorPlugin[]{
114                new XmlMetadataGenerator(metaInfDir, destFile),
115                new DocumentationGenerator(destFile),
116                new XsdGenerator(destFile)
117            };
118
119            // load the mappings
120            Set namespaces = mappingLoader.loadNamespaces();
121            if (namespaces.isEmpty()) {
122                System.out.println("Warning: no namespaces found!");
123            }
124
125            // generate the files
126            for (Iterator iterator = namespaces.iterator(); iterator.hasNext();) {
127                NamespaceMapping namespaceMapping = (NamespaceMapping) iterator.next();
128                for (int i = 0; i < plugins.length; i++) {
129                    GeneratorPlugin plugin = plugins[i];
130                    plugin.setLog(this);
131                    plugin.generate(namespaceMapping);
132                }
133            }
134
135            log("...done.");
136        } catch (Exception e) {
137            throw new BuildException(e);
138        } finally {
139            Thread.currentThread().setContextClassLoader(oldCL);
140        }
141    }
142
143    private File[] getFiles(Path path) {
144        if (path == null) {
145            return null;
146        }
147        String[] paths = path.list();
148        File[] files = new File[paths.length];
149        for (int i = 0; i < files.length; i++) {
150            files[i] = new File(paths[i]).getAbsoluteFile();
151        }
152        return files;
153    }
154}