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     */
017    package org.apache.xbean.spring.generator;
018    
019    import org.apache.tools.ant.BuildException;
020    import org.apache.tools.ant.taskdefs.MatchingTask;
021    import org.apache.tools.ant.types.Path;
022    
023    import java.io.File;
024    import java.util.Iterator;
025    import java.util.Set;
026    import java.util.List;
027    import java.util.LinkedList;
028    import java.util.Arrays;
029    import java.util.Collections;
030    import java.util.StringTokenizer;
031    import java.beans.PropertyEditorManager;
032    
033    /**
034     * An Ant task for executing generating mapping metadata.
035     *
036     * @version $Revision: 434369 $
037     */
038    public 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    }