001/*
002 * Copyright 2007 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 */
016package org.kualigan.maven.plugins.kfs;
017
018import org.kualigan.maven.plugins.api.PrototypeHelper;
019
020import org.apache.commons.cli.CommandLine;
021import org.apache.commons.cli.OptionBuilder;
022import org.apache.commons.cli.Options;
023import org.apache.commons.cli.PosixParser;
024
025import org.apache.maven.archetype.Archetype;
026import org.apache.maven.artifact.repository.ArtifactRepository;
027import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
028import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
029import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
030
031import org.apache.maven.shared.invoker.DefaultInvocationRequest;
032import org.apache.maven.shared.invoker.DefaultInvoker;
033import org.apache.maven.shared.invoker.InvocationOutputHandler;
034import org.apache.maven.shared.invoker.InvocationRequest;
035import org.apache.maven.shared.invoker.InvocationResult;
036import org.apache.maven.shared.invoker.Invoker;
037import org.apache.maven.shared.invoker.InvokerLogger;
038import org.apache.maven.shared.invoker.MavenInvocationException;
039
040import org.apache.maven.plugin.AbstractMojo;
041import org.apache.maven.plugin.MojoExecutionException;
042import org.apache.maven.plugins.annotations.Component;
043import org.apache.maven.plugins.annotations.Mojo;
044import org.apache.maven.plugins.annotations.Parameter;
045import org.apache.maven.project.MavenProject;
046
047import org.codehaus.plexus.archiver.Archiver;
048import org.codehaus.plexus.archiver.ArchiverException;
049import org.codehaus.plexus.archiver.UnArchiver;
050import org.codehaus.plexus.archiver.manager.ArchiverManager;
051import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
052import org.codehaus.plexus.archiver.util.DefaultFileSet;
053import org.codehaus.plexus.components.io.fileselectors.IncludeExcludeFileSelector;
054
055import org.codehaus.plexus.components.interactivity.Prompter;
056import org.codehaus.plexus.util.FileUtils;
057import org.codehaus.plexus.util.IOUtil;
058import org.codehaus.plexus.util.StringUtils;
059import org.codehaus.plexus.util.cli.CommandLineUtils;
060
061import java.io.DataInputStream;
062import java.io.File;
063import java.io.FileOutputStream;
064import java.io.FileWriter;
065import java.io.InputStream;
066import java.util.ArrayList;
067import java.util.HashMap;
068import java.util.List;
069import java.util.Map;
070import java.util.Properties;
071import java.util.StringTokenizer;
072
073/**
074 * Creates a prototype from the given KFS project resource. A KFS project resource can be either
075 * of the following:
076 * <ul>
077 *   <li>KFS war file</li>
078 *   <li>KFS project directory with source</li>
079 *   <li>KFS svn repo</li>
080 * </ul>
081 * 
082 */
083 @Mojo(
084     name="create-prototype",
085     requiresProject = false
086     )
087public class CreatePrototypeMojo extends AbstractMojo {
088    @Component
089    private PrototypeHelper helper;
090
091    /**
092     */
093    @Parameter(property="localRepository")
094    protected ArtifactRepository localRepository;
095    
096    /**
097     * Path for where the KFS instance is we want to migrate
098     * 
099     */
100    @Parameter(property="kfs.local.path")
101    protected String kfsPath;
102
103    /**
104     */
105    @Parameter(property="packageName",defaultValue="org.kuali.kfs")
106    protected String packageName;
107
108    /**
109     */
110    @Parameter(property="groupId",defaultValue="org.kuali.kfs")
111    protected String groupId;
112
113    /**
114     */
115    @Parameter(property="artifactId",defaultValue="kfs")
116    protected String artifactId;
117
118    /**
119     */
120    @Parameter(property="version",defaultValue="5.0")
121    protected String version;
122
123    /**
124     * WAR file to create a prototype from. Only used when creating a prototype from a war.
125     */
126    @Parameter(property="file")
127    protected File file;
128
129    /**
130     * Assembled sources file.
131     */
132    @Parameter(property="sources")
133    protected File sources;
134
135    /**
136     */
137    @Parameter(property="project")
138    protected MavenProject project;
139    
140    /**
141     */
142    @Parameter(property="repositoryId")
143    protected String repositoryId;
144
145    /**
146     * The {@code M2_HOME} parameter to use for forked Maven invocations.
147     *
148     */
149    @Parameter(defaultValue = "${maven.home}")
150    protected File mavenHome;
151    
152    /**
153     * <p>Create a prototype</p>
154     * 
155     * <p>The following are the steps for creating a prototype from a KFS instance</p>
156     * <p>
157     * When using a war file:
158     * <ol>
159     *   <li>Basically, use the install-file mojo and generate a POM from the archetype</li>
160     * </ol>
161     * </p>
162     * <p>When using an svn repo:
163     * <ol>
164     *   <li>Checkout the source.</li>
165     *   <li>Run migrate on it.</li>
166     * </ol>
167     * </p>
168     * <p>When using a local path:
169     * <ol>
170     *   <li>Delegate to migrate</li>
171     * </ol>
172     * </p>
173     * 
174     * The basic way to understand how this works is the kfs-archetype is used to create kfs
175     * maven projects, but it is dynamically generated. Then, source files are copied to it.
176     */ 
177    public void execute() throws MojoExecutionException {
178        final String basedir = System.getProperty("user.dir");
179        helper.setCaller(this);
180
181        final Map<String, String> map = new HashMap<String, String>();
182        map.put("basedir", basedir);
183        map.put("package", packageName);
184        map.put("packageName", packageName);
185        map.put("groupId", groupId);
186        map.put("artifactId", artifactId);
187        map.put("version", version);
188
189        try {
190
191            final List archetypeRemoteRepositories = new ArrayList();
192            
193            /* TODO: Allow remote repositories later 
194
195            if (remoteRepositories != null) {
196                getLog().info("We are using command line specified remote repositories: " + remoteRepositories);
197
198                archetypeRemoteRepositories = new ArrayList();
199
200                String[] s = StringUtils.split(remoteRepositories, ",");
201
202                for (int i = 0; i < s.length; i++) {
203                    archetypeRemoteRepositories.add(createRepository(s[i], "id" + i));
204                }
205            }*/
206            
207            final File prototypeJar = helper.repack(file, artifactId);
208            helper.extractTempPom();
209            helper.installArtifact(file, null, 
210                                   getMavenHome(), 
211                                   groupId, 
212                                   artifactId, 
213                                   version, 
214                                   repositoryId);
215            helper.installArtifact(prototypeJar, 
216                                   sources, 
217                                   getMavenHome(), 
218                                   groupId, 
219                                   artifactId, 
220                                   version, 
221                                   repositoryId);
222
223        } 
224        catch (Exception e) {
225            throw new MojoExecutionException("Failed to create a new KFS Prototype",e);
226        }
227    }
228    
229    
230    public void setMavenHome(final File mavenHome) {
231        this.mavenHome = mavenHome;
232    }
233    
234    public File getMavenHome() {
235        return this.mavenHome;
236    }
237        
238    public void setRepositoryId(final String repositoryId) {
239        this.repositoryId = repositoryId;
240    }
241    
242    public String getRepositoryId() {
243        return this.repositoryId;
244    }
245}