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