001    /**
002     * Copyright 2004-2012 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.maven.common;
017    
018    import java.io.File;
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.HashMap;
022    import java.util.Hashtable;
023    import java.util.Iterator;
024    import java.util.List;
025    import java.util.Map;
026    import java.util.Properties;
027    import java.util.Set;
028    
029    import org.apache.maven.artifact.Artifact;
030    import org.apache.maven.artifact.DependencyResolutionRequiredException;
031    import org.apache.maven.artifact.repository.ArtifactRepository;
032    import org.apache.maven.plugin.logging.Log;
033    import org.apache.maven.project.MavenProject;
034    import org.apache.tools.ant.BuildLogger;
035    import org.apache.tools.ant.DefaultLogger;
036    import org.apache.tools.ant.Project;
037    import org.apache.tools.ant.types.Path;
038    import org.codehaus.plexus.util.StringUtils;
039    
040    public class AntMavenUtils {
041        public static final String MVN_COMPILE_CLASSPATH_KEY = "maven.compile.classpath";
042        public static final String MVN_RUNTIME_CLASSPATH_KEY = "maven.runtime.classpath";
043        public static final String MVN_TEST_CLASSPATH_KEY = "maven.test.classpath";
044        public static final String MVN_PLUGIN_CLASSPATH_KEY = "maven.plugin.classpath";
045    
046        /**
047         * Copy properties from the ant project to the maven project.
048         *
049         * @param antProject
050         *            not null
051         * @param mavenProject
052         *            not null
053         */
054        public void copyProperties(Project antProject, MavenProject mavenProject, Log log) {
055            log.debug("Propagated Ant properties to Maven properties");
056            Hashtable<?, ?> antProps = antProject.getProperties();
057    
058            Iterator<?> iter = antProps.keySet().iterator();
059            while (iter.hasNext()) {
060                String key = (String) iter.next();
061    
062                Properties mavenProperties = mavenProject.getProperties();
063                if (mavenProperties.getProperty(key) != null) {
064                    log.debug("Ant property '" + key + "=" + mavenProperties.getProperty(key)
065                            + "' clashes with an existing Maven property, SKIPPING this Ant property propagation.");
066                    continue;
067                }
068                mavenProperties.setProperty(key, antProps.get(key).toString());
069            }
070        }
071    
072        /**
073         * @param artifacts
074         * @param antProject
075         * @return a path
076         * @throws DependencyResolutionRequiredException
077         */
078        public Path getPathFromArtifacts(Collection<Artifact> artifacts, Project antProject)
079                throws DependencyResolutionRequiredException {
080            if (artifacts == null) {
081                return new Path(antProject);
082            }
083    
084            List<String> list = new ArrayList<String>(artifacts.size());
085            for (Iterator<?> i = artifacts.iterator(); i.hasNext();) {
086                Artifact a = (Artifact) i.next();
087                File file = a.getFile();
088                if (file == null) {
089                    throw new DependencyResolutionRequiredException(a);
090                }
091                list.add(file.getPath());
092            }
093    
094            Path p = new Path(antProject);
095            p.setPath(StringUtils.join(list.iterator(), File.pathSeparator));
096            return p;
097        }
098    
099        /**
100         * Copy properties from the maven project to the ant project.
101         *
102         * @param mavenProject
103         * @param antProject
104         */
105        public void copyProperties(MavenProject mavenProject, Project antProject, String prefix, Log log,
106                ArtifactRepository localRepo) {
107            Properties mavenProps = mavenProject.getProperties();
108            Iterator<?> iter = mavenProps.keySet().iterator();
109            while (iter.hasNext()) {
110                String key = (String) iter.next();
111                antProject.setProperty(key, mavenProps.getProperty(key));
112            }
113    
114            // Set the POM file as the ant.file for the tasks run directly in Maven.
115            antProject.setProperty("ant.file", mavenProject.getFile().getAbsolutePath());
116    
117            // Add some of the common maven properties
118            log.debug("Setting properties with prefix: " + prefix);
119            antProject.setProperty((prefix + "project.groupId"), mavenProject.getGroupId());
120            antProject.setProperty((prefix + "project.artifactId"), mavenProject.getArtifactId());
121            antProject.setProperty((prefix + "project.name"), mavenProject.getName());
122            if (mavenProject.getDescription() != null) {
123                antProject.setProperty((prefix + "project.description"), mavenProject.getDescription());
124            }
125            antProject.setProperty((prefix + "project.version"), mavenProject.getVersion());
126            antProject.setProperty((prefix + "project.packaging"), mavenProject.getPackaging());
127            antProject.setProperty((prefix + "project.build.directory"), mavenProject.getBuild().getDirectory());
128            antProject.setProperty((prefix + "project.basedir"), mavenProject.getBasedir().getAbsolutePath());
129            antProject
130                    .setProperty((prefix + "project.build.outputDirectory"), mavenProject.getBuild().getOutputDirectory());
131            antProject.setProperty((prefix + "project.build.testOutputDirectory"), mavenProject.getBuild()
132                    .getTestOutputDirectory());
133            antProject
134                    .setProperty((prefix + "project.build.sourceDirectory"), mavenProject.getBuild().getSourceDirectory());
135            antProject.setProperty((prefix + "project.build.testSourceDirectory"), mavenProject.getBuild()
136                    .getTestSourceDirectory());
137            antProject.setProperty((prefix + "localRepository"), localRepo.toString());
138            antProject.setProperty((prefix + "settings.localRepository"), localRepo.getBasedir());
139    
140            // Add properties for dependency artifacts
141            Set<?> depArtifacts = mavenProject.getArtifacts();
142            for (Iterator<?> it = depArtifacts.iterator(); it.hasNext();) {
143                Artifact artifact = (Artifact) it.next();
144    
145                String propName = artifact.getDependencyConflictId();
146    
147                antProject.setProperty(prefix + propName, artifact.getFile().getPath());
148            }
149    
150        }
151    
152        /**
153         * Setup an Ant BuildLogger
154         */
155        public BuildLogger getBuildLogger(Log logger) {
156            DefaultLogger antLogger = new DefaultLogger();
157            antLogger.setOutputPrintStream(System.out);
158            antLogger.setErrorPrintStream(System.err);
159    
160            if (logger.isDebugEnabled()) {
161                antLogger.setMessageOutputLevel(Project.MSG_DEBUG);
162            } else if (logger.isInfoEnabled()) {
163                antLogger.setMessageOutputLevel(Project.MSG_INFO);
164            } else if (logger.isWarnEnabled()) {
165                antLogger.setMessageOutputLevel(Project.MSG_WARN);
166            } else if (logger.isErrorEnabled()) {
167                antLogger.setMessageOutputLevel(Project.MSG_ERR);
168            } else {
169                antLogger.setMessageOutputLevel(Project.MSG_VERBOSE);
170            }
171            return antLogger;
172        }
173    
174        /**
175         * Create the Ant equivalent of the Maven classpath's for compile, runtime, test, and for the plugin
176         */
177        public Map<String, Path> getPathRefs(Project ant, MavenProject mvn, List<Artifact> pluginArtifacts)
178                throws DependencyResolutionRequiredException {
179    
180            Map<String, Path> pathRefs = new HashMap<String, Path>();
181    
182            // compile
183            Path mcp = new Path(ant);
184            mcp.setPath(StringUtils.join(mvn.getCompileClasspathElements().iterator(), File.pathSeparator));
185            pathRefs.put(MVN_COMPILE_CLASSPATH_KEY, mcp);
186    
187            // runtime
188            Path mrp = new Path(ant);
189            mrp.setPath(StringUtils.join(mvn.getRuntimeClasspathElements().iterator(), File.pathSeparator));
190            pathRefs.put(MVN_RUNTIME_CLASSPATH_KEY, mrp);
191    
192            // test
193            Path mtp = new Path(ant);
194            mtp.setPath(StringUtils.join(mvn.getTestClasspathElements().iterator(), File.pathSeparator));
195            pathRefs.put(MVN_TEST_CLASSPATH_KEY, mtp);
196    
197            // plugin
198            Path mpp = getPathFromArtifacts(pluginArtifacts, ant);
199            pathRefs.put(MVN_PLUGIN_CLASSPATH_KEY, mpp);
200            return pathRefs;
201        }
202    
203        /**
204         * Add this map of objects to the Ant projects as named references
205         */
206        public void addRefs(Project antProject, Map<String, ?> refs) {
207            for (Map.Entry<String, ?> pair : refs.entrySet()) {
208                antProject.addReference(pair.getKey(), pair.getValue());
209            }
210        }
211    
212        /**
213         * Set paths as properties on the Ant project
214         */
215        public void setPathProperties(Project antProject, Map<String, Path> paths) {
216            for (Map.Entry<String, ?> pair : paths.entrySet()) {
217                antProject.setProperty(pair.getKey(), pair.getValue().toString());
218            }
219        }
220    
221    }