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.pluto.maven;
018:
019: import java.io.File;
020: import java.util.ArrayList;
021: import java.util.Iterator;
022: import java.util.List;
023:
024: import org.apache.maven.plugin.MojoExecutionException;
025: import org.apache.maven.plugin.logging.Log;
026: import org.apache.pluto.util.UtilityException;
027: import org.apache.pluto.util.assemble.Assembler;
028: import org.apache.pluto.util.assemble.AssemblerConfig;
029: import org.apache.pluto.util.assemble.AssemblerFactory;
030:
031: /**
032: * The AssembleMojo is responsible for assembling a web application for deployment
033: * into the Pluto portlet container. Assembly, in this context, is the process of
034: * updating a web application's WEB-INF/web.xml with Pluto specific parameters for
035: * deployment in Pluto.
036: * <p>
037: * This Mojo is able to operate on individual descriptors by specifying
038: * <code>portletXml</code>, <code>webXml</code>, and <code>webXmlDestination</code>.
039: * If your project uses standard Maven 2 directory layouts, the defaults will
040: * provide proper values.
041: * <p/>
042: * Example Maven 2 <code>pom.xml</code> usage:
043: * <pre>
044: * <project>
045: * ...
046: * <build>
047: * <plugins>
048: * <plugin>
049: * <groupId>org.apache.pluto</groupId>
050: * <artifactId>maven-pluto-plugin</artifactId>
051: * </plugin>
052: * </plugins>
053: * </build>
054: * ...
055: * </project>
056: * </pre>
057: * <p>
058: * This Mojo can also operate on entire WAR or EAR archive files by specifying
059: * a list of archive path names in <code>archives</code>.
060: * <p/>
061: * Example Maven 2 <code>pom.xml</code> usage:
062: * <pre>
063: * <project>
064: * ...
065: * <build>
066: * <plugins>
067: * <plugin>
068: * <groupId>org.apache.pluto</groupId>
069: * <artifactId>maven-pluto-plugin</artifactId>
070: * <executions>
071: * <execution>
072: * <phase>package</phase>
073: * <goals>
074: * <goal>assemble</goal>
075: * </goals>
076: * <configuration>
077: * <assemblyOutputDirectory>${project.build.directory}/assembled-wars</assemblyOutputDirectory>
078: * <archives>
079: * <assembleArchive>
080: * ${project.build.directory}/wartoassemble.war
081: * </assembleArchive>
082: * <assembleArchive>
083: * ${project.build.directory}/anotherwartoassemble.war
084: * </assembleArchive>
085: * </archives>
086: * </configuration>
087: * </execution>
088: * </executions>
089: * </plugin>
090: * </plugins>
091: * </build>
092: * ...
093: * </project>
094: * </pre>
095: *
096: * @since Jul 30, 2005
097: * @see org.apache.pluto.util.assemble.Assembler
098: *
099: * @goal assemble
100: * @description prepares a web application as a portlet application
101: * @phase process-resources
102: */
103: public class AssembleMojo extends AbstractPortletMojo {
104:
105: // Private Member Variables ------------------------------------------------
106:
107: /**
108: * The portlet application descriptor (<code>WEB-INF/portlet.xml</code>).
109: * @parameter expression="${basedir}/src/main/webapp/WEB-INF/portlet.xml"
110: * @required
111: */
112: private File portletXml;
113:
114: /**
115: * The original webapp descriptor (<code>WEB-INF/web.xml</code>).
116: * @parameter expression="${basedir}/src/main/webapp/WEB-INF/web.xml"
117: * @required
118: */
119: private File webXml;
120:
121: /**
122: * The file to which the updated webapp descriptor is written.
123: * @parameter expression="${project.build.directory}/pluto-resources/web.xml"
124: */
125: private File webXmlDestination;
126:
127: /**
128: * The name of the dispatch servlet class to use
129: * @parameter
130: */
131: private String dispatchServletClass;
132:
133: /**
134: * A list of archive files to assemble. Only EAR and WAR file
135: * types are supported.
136: * <p/>
137: * Each value in the list is the absolute pathname to the
138: * archive being assembled.
139: * <p/>
140: * This parameter is mutually exclusive with portletXml, webXml,
141: * and webXmlDestination parameters.
142: *
143: * @parameter alias="warFiles"
144: */
145: private List archives;
146:
147: /**
148: * @deprecated see archives parameter
149: * @parameter
150: */
151: private List warFiles;
152:
153: /**
154: * Destination directory the assembled files are written out to.
155: * @parameter alias="warFilesDestination" expression="${project.build.directory}/pluto-assembled-wars"
156: */
157: private File assemblyOutputDirectory;
158:
159: /**
160: * Destination directory the assembled files are written out to.
161: * @parameter
162: * @deprecated see assemblyOutputDirectory parameter
163: */
164: private File warFilesDestination;
165:
166: // AbstractPlutoMojo Impl --------------------------------------------------
167:
168: protected void doExecute() throws MojoExecutionException {
169:
170: // Log parameter values.
171: Log log = getLog();
172: if (log.isInfoEnabled()) {
173: if (archives == null || archives.isEmpty()) {
174: log.info("Reading web.xml from :"
175: + webXml.getAbsolutePath());
176: log.info("Reading portlet.xml from: "
177: + portletXml.getAbsolutePath());
178: log.info("Writing web.xml to: "
179: + webXmlDestination.getAbsolutePath());
180: }
181: }
182:
183: try {
184: // Assemble portlet app by updating web.xml.
185: if (archives == null || archives.isEmpty()) {
186: AssemblerConfig config = createAssemblerConfig();
187: Assembler assembler = AssemblerFactory.getFactory()
188: .createAssembler(config);
189: assembler.assemble(config);
190: } else {
191: for (Iterator i = archives.iterator(); i.hasNext();) {
192: File archive = new File(i.next().toString());
193: if (log.isInfoEnabled()) {
194: log.info("Assembling archive file "
195: + archive.getAbsolutePath()
196: + " to directory "
197: + assemblyOutputDirectory
198: .getAbsolutePath());
199: }
200: AssemblerConfig config = createArchiveAssemblerConfig(
201: archive, assemblyOutputDirectory);
202: Assembler assembler = AssemblerFactory.getFactory()
203: .createAssembler(config);
204: assembler.assemble(config);
205: }
206: }
207: } catch (UtilityException e) {
208: log.error("Assembly failed: " + e.getMessage(), e);
209: }
210: }
211:
212: protected void doValidate() throws MojoExecutionException {
213: Log log = getLog();
214:
215: // Support for the old 'warFiles' mojo parameter. Apparently
216: // the alias for the 'archives' parameter doesn't work properly.
217: if (!(warFiles == null || warFiles.isEmpty())) {
218: log
219: .warn("'warFiles' parameter is deprecated. Use 'archives' parameter instead.");
220: if (archives == null) {
221: archives = new ArrayList();
222: }
223: archives.addAll(warFiles);
224: }
225:
226: // Warn if the old 'warFilesDestination' mojo parameter is used
227: if (warFilesDestination != null) {
228: log
229: .warn("'warFilesDestination' parameter is deprecated. Use 'assemblyOutputDirectory' instead.");
230: assemblyOutputDirectory = warFilesDestination;
231: }
232:
233: // If a list of war files are supplied:
234: // 1) webXml, portletXml, and webXmlDestination parameters are ignored
235: // 2) verify the files in the List exist.
236: // 3) verify the destination is a directory, or create it if it doesn't exist.
237:
238: // A list of files was supplied so we ignore other parameters.
239: if (archives != null && !archives.isEmpty()) {
240: if (webXml != null) {
241: log
242: .debug("archives parameter and webXml parameter are mutually exclusive. Ignoring webXml parameter.");
243: }
244: if (portletXml != null) {
245: log
246: .debug("archives parameter and portletXml parameter are mutually exclusive. Ignoring portletXml parameter.");
247: }
248: if (webXmlDestination != null) {
249: log
250: .debug("archives parameter and webXmlDestination parameter are mutually exclusive. Ignoring webXmlDestination parameter.");
251: }
252:
253: // verify each file can be found
254: for (Iterator i = archives.iterator(); i.hasNext();) {
255: File f = new File(i.next().toString());
256: if (!f.exists()) {
257: log.warn("File " + f.getAbsolutePath()
258: + " does not exist.");
259: i.remove();
260: continue;
261: }
262: if (!f.canRead()) {
263: log.warn("File " + f.getAbsolutePath()
264: + " exists but cannot be read.");
265: i.remove();
266: continue;
267: }
268: }
269:
270: // check to see if the warFiles list is now empty
271: if (archives.isEmpty()) {
272: throw new MojoExecutionException(
273: "No war files could be installed due errors.");
274: }
275:
276: // check to see if the dest dir exists or create it.
277: if (!assemblyOutputDirectory.exists()) {
278: if (log.isDebugEnabled()) {
279: log
280: .debug("Creating destination directory for assembled war files: "
281: + assemblyOutputDirectory
282: .getAbsolutePath());
283: }
284: try {
285: if (!assemblyOutputDirectory.mkdirs()) {
286: throw new MojoExecutionException(
287: "Unable to create destination directory for assembled war files: "
288: + assemblyOutputDirectory
289: .getAbsolutePath());
290: }
291: } catch (SecurityException e) {
292: throw new MojoExecutionException(
293: "Unable to create destination directory for assembled war files: "
294: + e.getMessage(), e);
295: }
296: } else {
297: if (!assemblyOutputDirectory.isDirectory()) {
298: throw new MojoExecutionException(
299: "Specified destination for assembled war files "
300: + assemblyOutputDirectory
301: .getAbsolutePath()
302: + " is not a directory!");
303: }
304: if (!assemblyOutputDirectory.canRead()
305: || !assemblyOutputDirectory.canWrite()) {
306: throw new MojoExecutionException(
307: "Unable to read or write to destination directory for assembed war files. "
308: + "Check permissions on the directory "
309: + assemblyOutputDirectory
310: .getAbsolutePath());
311: }
312: }
313:
314: // A list of archive files was not provided, so use the other parameters instead.
315:
316: } else {
317: if (webXml == null || !webXml.exists()) {
318: throw new MojoExecutionException(
319: "Web application descriptor must be a valid web.xml");
320: }
321: if (portletXml == null || !portletXml.exists()) {
322: throw new MojoExecutionException(
323: "Portlet descriptor must be a valid portlet.xml");
324: }
325: }
326: }
327:
328: // Private Methods ---------------------------------------------------------
329:
330: private AssemblerConfig createAssemblerConfig() {
331: AssemblerConfig config = new AssemblerConfig();
332: config.setPortletDescriptor(portletXml);
333: config.setWebappDescriptor(webXml);
334: config.setDestination(webXmlDestination);
335: config.setDispatchServletClass(dispatchServletClass);
336: return config;
337: }
338:
339: private AssemblerConfig createArchiveAssemblerConfig(
340: File archiveToAssemble, File destinationDirectory) {
341: AssemblerConfig config = new AssemblerConfig();
342: config.setDispatchServletClass(dispatchServletClass);
343: config.setSource(archiveToAssemble);
344: config.setDestination(destinationDirectory);
345: return config;
346: }
347:
348: }
|