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: 1189729 $
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    private boolean strictXsdOrder = true;
046
047    public File getDestFile() {
048        return destFile;
049    }
050
051    public void setDestFile(File destFile) {
052        this.destFile = destFile;
053    }
054
055    public String getMetaInfDir() {
056        return metaInfDir;
057    }
058
059    public void setMetaInfDir(String metaInfDir) {
060        this.metaInfDir = metaInfDir;
061    }
062
063    public String getNamespace() {
064        return namespace;
065    }
066
067    public void setNamespace(String namespace) {
068        this.namespace = namespace;
069    }
070
071    public Path getSrcDir() {
072        return srcDir;
073    }
074
075    public void setSrcDir(Path srcDir) {
076        this.srcDir = srcDir;
077    }
078
079    public String getPropertyEditorPaths() {
080        return propertyEditorPaths;
081    }
082
083    public void setPropertyEditorPaths(String propertyEditorPaths) {
084        this.propertyEditorPaths = propertyEditorPaths;
085    }
086
087    public boolean isStrictXsdOrder() {
088        return strictXsdOrder;
089    }
090
091    public void setStrictXsdOrder(boolean strictXsdOrder) {
092        this.strictXsdOrder = strictXsdOrder;
093    }
094
095    public void execute() throws BuildException {
096        if (namespace == null) {
097            throw new BuildException("'namespace' must be specified");
098        }
099        if (srcDir == null) {
100            throw new BuildException("'srcDir' must be specified");
101        }
102        if (destFile == null) {
103            throw new BuildException("'destFile' must be specified");
104        }
105
106        if (propertyEditorPaths != null) {
107            List editorSearchPath = new LinkedList(Arrays.asList(PropertyEditorManager.getEditorSearchPath()));
108            StringTokenizer paths = new StringTokenizer(propertyEditorPaths, " ,");
109            editorSearchPath.addAll(Collections.list(paths));
110            PropertyEditorManager.setEditorSearchPath((String[]) editorSearchPath.toArray(new String[editorSearchPath.size()]));
111        }
112
113        ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
114        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
115        try {
116            String[] excludedClasses = null;
117            if (this.excludedClasses != null) {
118                excludedClasses = this.excludedClasses.split(" *, *");
119            }
120            MappingLoader mappingLoader = new QdoxMappingLoader(namespace, getFiles(srcDir), excludedClasses);
121
122            GeneratorPlugin[] plugins = new GeneratorPlugin[]{
123                new XmlMetadataGenerator(metaInfDir, destFile),
124                new DocumentationGenerator(destFile),
125                new XsdGenerator(destFile, strictXsdOrder)
126            };
127
128            // load the mappings
129            Set namespaces = mappingLoader.loadNamespaces();
130            if (namespaces.isEmpty()) {
131                System.out.println("Warning: no namespaces found!");
132            }
133
134            // generate the files
135            for (Iterator iterator = namespaces.iterator(); iterator.hasNext();) {
136                NamespaceMapping namespaceMapping = (NamespaceMapping) iterator.next();
137                for (int i = 0; i < plugins.length; i++) {
138                    GeneratorPlugin plugin = plugins[i];
139                    plugin.setLog(this);
140                    plugin.generate(namespaceMapping);
141                }
142            }
143
144            log("...done.");
145        } catch (Exception e) {
146            throw new BuildException(e);
147        } finally {
148            Thread.currentThread().setContextClassLoader(oldCL);
149        }
150    }
151
152    private File[] getFiles(Path path) {
153        if (path == null) {
154            return null;
155        }
156        String[] paths = path.list();
157        File[] files = new File[paths.length];
158        for (int i = 0; i < files.length; i++) {
159            files[i] = new File(paths[i]).getAbsoluteFile();
160        }
161        return files;
162    }
163}