blob: cfe538df31e07974494cefecaab0613c054ce406 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.myfaces.tobago.maven.plugin;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.MojoExecutionException;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.xml.XmlStreamReader;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Locale;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* @goal resources
* @phase process-resources
* @requiresDependencyResolution runtime
*/
public class UnPackThemeMojo extends AbstractThemeMojo {
/**
* To look up Archiver/UnArchiver implementations
*
* @parameter expression="${component.org.codehaus.plexus.archiver.manager.ArchiverManager}"
* @required
*/
private ArchiverManager archiverManager;
/**
* Directory to unpack JARs into if needed
*
* @parameter expression="${project.build.directory}/theme/work"
* @required
*/
private File workDirectory;
/**
* The directory where the webapp is built.
*
* @parameter expression="${project.build.directory}/${project.build.finalName}"
* @required
*/
private File webappDirectory;
/**
* Don't use the versioned information of the themes..
*
* @parameter
*/
private boolean ignoreVersioned;
private String getThemeDescriptor(final File jarFile) throws MojoExecutionException {
ZipFile zip = null;
try {
zip = new ZipFile(jarFile);
final Enumeration files = zip.entries();
while (files.hasMoreElements()) {
final ZipEntry nextEntry = (ZipEntry) files.nextElement();
if (nextEntry == null || nextEntry.isDirectory()) {
continue;
}
final String name = nextEntry.getName();
if (name.equals("META-INF/tobago-theme.xml") || name.equals("META-INF/tobago-config.xml")) {
XmlStreamReader xsr = null;
try {
final StringWriter stringWriter = new StringWriter();
xsr = ReaderFactory.newXmlReader(zip.getInputStream(nextEntry));
IOUtil.copy(xsr, stringWriter);
return stringWriter.toString();
} finally {
IOUtil.close(xsr);
}
}
}
} catch (final IOException e) {
throw new MojoExecutionException("Error find ThemeDescriptor in " + jarFile, e);
} finally {
if (zip != null) {
try {
zip.close();
} catch (final IOException e) {
// ignore
}
}
}
return null;
}
public void execute() throws MojoExecutionException {
try {
final Iterator artifacts = getProject().getRuntimeClasspathElements().iterator();
if (!workDirectory.exists()) {
workDirectory.mkdirs();
}
while (artifacts.hasNext()) {
final String artifact = (String) artifacts.next();
if (getLog().isDebugEnabled()) {
getLog().debug("Testing jar "+ artifact);
}
final File file = new File(artifact);
if (file.isFile() && artifact.endsWith(".jar")) {
final String descriptor = getThemeDescriptor(file);
if (descriptor != null) {
final String name = file.getName();
final File tempLocation = new File(workDirectory, name.substring(0, name.length() - 4));
boolean process = false;
if (!tempLocation.exists()) {
tempLocation.mkdirs();
process = true;
} else if (file.lastModified() > tempLocation.lastModified()) {
process = true;
}
if (process) {
try {
unpack(file, tempLocation);
String version = null;
String resourcePath = null;
try {
final Xpp3Dom xpp3Dom = Xpp3DomBuilder.build(new StringReader(descriptor));
final Xpp3Dom themeDefinitions = xpp3Dom.getChild("theme-definitions");
if (themeDefinitions != null && !ignoreVersioned) {
for (final Xpp3Dom themeDefinition : themeDefinitions.getChildren()) {
final Xpp3Dom versionedDom = themeDefinition.getChild("versioned");
if (versionedDom != null) {
final boolean versioned = Boolean.parseBoolean(versionedDom.getValue());
if (versioned) {
final Xpp3Dom resourcePathDom = themeDefinition.getChild("resource-path");
resourcePath = resourcePathDom.getValue();
final Properties properties = new Properties();
final String metaInf = tempLocation + "/META-INF/MANIFEST.MF";
properties.load(new ByteArrayInputStream(FileUtils.fileRead(metaInf).getBytes()));
version = properties.getProperty("Implementation-Version");
if (version == null) {
getLog().error("No Implementation-Version found in Manifest-File for theme: '"
+ name + "'.");
}
}
}
}
}
} catch (final IOException e) {
getLog().error(e);
} catch (final XmlPullParserException e) {
getLog().error(e);
}
if (getLog().isDebugEnabled()) {
getLog().debug("Expanding theme: "+ name);
getLog().debug("Version: " + version);
getLog().debug("ResourcePath: " + resourcePath);
}
final String[] fileNames = getThemeFiles(tempLocation);
for (final String fileName : fileNames) {
final File fromFile = new File(tempLocation, fileName);
String toFileName = fileName;
if (resourcePath != null && version != null && toFileName.startsWith(resourcePath)
&& !fileName.endsWith("blank.html")) {
toFileName = resourcePath + "/" + version + "/" + toFileName.substring(resourcePath.length() + 1);
}
if (getLog().isDebugEnabled()) {
getLog().debug("Copy file " + fromFile + " to: " + toFileName);
}
final File toFile = new File(webappDirectory, toFileName);
try {
FileUtils.copyFile(fromFile, toFile);
} catch (final IOException e) {
throw new MojoExecutionException("Error copy file: " + fromFile + " to: " + toFile, e);
}
}
} catch (final NoSuchArchiverException e) {
getLog().info("Skip unpacking dependency file with unknown extension: " + file.getPath());
}
}
}
}
}
} catch (final DependencyResolutionRequiredException drre) {
throw new MojoExecutionException(drre.getMessage(), drre);
}
}
private void unpack(final File file, final File location)
throws MojoExecutionException, NoSuchArchiverException {
final String archiveExt = FileUtils.getExtension(file.getAbsolutePath()).toLowerCase(Locale.ENGLISH);
try {
final UnArchiver unArchiver = archiverManager.getUnArchiver(archiveExt);
unArchiver.setSourceFile(file);
unArchiver.setDestDirectory(location);
unArchiver.extract();
} catch (final ArchiverException e) {
throw new MojoExecutionException("Error unpacking file: " + file + "to: " + location, e);
}
}
}