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(role = org.kualigan.maven.plugins.api.PrototypeHelper.class,
089               hint = "default")
090    private PrototypeHelper helper;
091
092    /**
093     */
094    @Parameter(property="localRepository")
095    protected ArtifactRepository localRepository;
096    
097    /**
098     * Path for where the KFS instance is we want to migrate
099     * 
100     */
101    @Parameter(property="kfs.local.path")
102    protected String kfsPath;
103
104    /**
105     */
106    @Parameter(property="packageName",defaultValue="org.kuali.kfs")
107    protected String packageName;
108
109    /**
110     */
111    @Parameter(property="groupId",defaultValue="org.kuali.kfs")
112    protected String groupId;
113
114    /**
115     */
116    @Parameter(property="artifactId",defaultValue="kfs")
117    protected String artifactId;
118
119    /**
120     */
121    @Parameter(property="version",defaultValue="5.0")
122    protected String version;
123
124    /**
125     * WAR file to create a prototype from. Only used when creating a prototype from a war.
126     */
127    @Parameter(property="file")
128    protected File file;
129
130    /**
131     * Assembled sources file.
132     */
133    @Parameter(property="sources")
134    protected File sources;
135
136    /**
137     */
138    @Parameter(property="project")
139    protected MavenProject project;
140    
141    /**
142     */
143    @Parameter(property="repositoryId")
144    protected String repositoryId;
145
146    /**
147     * The {@code M2_HOME} parameter to use for forked Maven invocations.
148     *
149     */
150    @Parameter(defaultValue = "${maven.home}")
151    protected File mavenHome;
152    
153    /**
154     * <p>Create a prototype</p>
155     * 
156     * <p>The following are the steps for creating a prototype from a KFS instance</p>
157     * <p>
158     * When using a war file:
159     * <ol>
160     *   <li>Basically, use the install-file mojo and generate a POM from the archetype</li>
161     * </ol>
162     * </p>
163     * <p>When using an svn repo:
164     * <ol>
165     *   <li>Checkout the source.</li>
166     *   <li>Run migrate on it.</li>
167     * </ol>
168     * </p>
169     * <p>When using a local path:
170     * <ol>
171     *   <li>Delegate to migrate</li>
172     * </ol>
173     * </p>
174     * 
175     * The basic way to understand how this works is the kfs-archetype is used to create kfs
176     * maven projects, but it is dynamically generated. Then, source files are copied to it.
177     */ 
178    public void execute() throws MojoExecutionException {
179        final String basedir = System.getProperty("user.dir");
180        
181        try {
182            final Map<String, String> map = new HashMap<String, String>();
183            map.put("basedir", basedir);
184            map.put("package", packageName);
185            map.put("packageName", packageName);
186            map.put("groupId", groupId);
187            map.put("artifactId", artifactId);
188            map.put("version", version);
189
190            List archetypeRemoteRepositories = new ArrayList();
191            /* TODO: Allow remote repositories later 
192
193            if (remoteRepositories != null) {
194                getLog().info("We are using command line specified remote repositories: " + remoteRepositories);
195
196                archetypeRemoteRepositories = new ArrayList();
197
198                String[] s = StringUtils.split(remoteRepositories, ",");
199
200                for (int i = 0; i < s.length; i++) {
201                    archetypeRemoteRepositories.add(createRepository(s[i], "id" + i));
202                }
203            }*/
204            
205            final File prototypeJar = helper.repack(file, artifactId);
206            helper.extractTempPom();
207            helper.installArtifact(file, null, 
208                                   getMavenHome(), 
209                                   groupId, 
210                                   artifactId, 
211                                   version, 
212                                   repositoryId);
213            helper.installArtifact(prototypeJar, 
214                                   sources, 
215                                   getMavenHome(), 
216                                   groupId, 
217                                   artifactId, 
218                                   version, 
219                                   repositoryId);
220
221            /* TODO: Was this really necessary?
222            Properties props = new Properties();
223            props.load(getClass().getResourceAsStream("plugin.properties"));
224            */
225
226        } catch (Exception e) {
227            throw new MojoExecutionException("Failed to create a new Jenkins plugin",e);
228        }
229    }
230    
231    
232    public void setMavenHome(final File mavenHome) {
233        this.mavenHome = mavenHome;
234    }
235    
236    public File getMavenHome() {
237        return this.mavenHome;
238    }
239        
240    public void setRepositoryId(final String repositoryId) {
241        this.repositoryId = repositoryId;
242    }
243    
244    public String getRepositoryId() {
245        return this.repositoryId;
246    }
247}