All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wisdom.maven.utils.WebJars Maven / Gradle / Ivy

There is a newer version: 0.10.0
Show newest version
/*
 * #%L
 * Wisdom-Framework
 * %%
 * Copyright (C) 2013 - 2014 Wisdom Framework
 * %%
 * Licensed 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.
 * #L%
 */
package org.wisdom.maven.utils;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
import org.slf4j.LoggerFactory;
import org.wisdom.maven.mojos.AbstractWisdomMojo;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import static org.ow2.chameleon.core.utils.BundleHelper.isBundle;

/**
 * Utility methods to handle webjars.
 */
public class WebJars {
    /**
     * A regex extracting the library name and version from Zip Entry names.
     */
    public static final Pattern WEBJAR_REGEX = Pattern.compile(".*META-INF/resources/webjars/([^/]+)/([^/]+)/.*");
    /**
     * The directory within jar file where webjar resources are located.
     */
    public static final String WEBJAR_LOCATION = "META-INF/resources/webjars/";

    /**
     * A regex to extract the different part of the path of a file from a library included in a webjar.
     */
    public static final Pattern WEBJAR_INTERNAL_PATH_REGEX = Pattern.compile("([^/]+)/([^/]+)/(.*)");

    /**
     * Manage webjars dependencies.
     * 

* This process is executed as follows: *

    *
  1. web jars that are also bundles are ignored
  2. *
  3. web jars libraries from a 'provided' dependency (in the 'provided' scope) are copied to the /assets/lib * directory.
  4. *
  5. web jars libraries from a 'compile' dependency (in the 'compile' scope) are copied to the application * directory.
  6. *
  7. Transitive are also analyzed if enabled (enabled by default).
  8. *
* * @param mojo the mojo * @param graph the dependency graph builder * @param transitive whether or not we include the transitive dependencies. * @param unpackWebJars whether or not webjars should be extracted to target/webjars * @throws java.io.IOException when a web jar cannot be handled correctly */ public static void manageWebJars(AbstractWisdomMojo mojo, DependencyGraphBuilder graph, boolean transitive, boolean unpackWebJars) throws IOException { File webjars = new File(mojo.getWisdomRootDirectory(), "assets/libs"); final File application = new File(mojo.getWisdomRootDirectory(), "application"); Set artifacts = DependencyCopy.getArtifactsToConsider(mojo, graph, transitive, null); for (Artifact artifact : artifacts) { if (DependencyCopy.SCOPE_COMPILE.equalsIgnoreCase(artifact.getScope()) || DependencyCopy.SCOPE_PROVIDED.equalsIgnoreCase(artifact.getScope())) { File file = artifact.getFile(); // Check it's a 'jar file' if (!file.getName().endsWith(".jar")) { mojo.getLog().debug("Dependency " + file.getName() + " is not a web jar, it's not even a jar file"); continue; } // Check that it's a web jar. if (!isWebJar(file)) { mojo.getLog().debug("Dependency " + file.getName() + " is not a web jar."); continue; } // Check that it's not a bundle. if (isBundle(file)) { mojo.getLog().debug("Dependency " + file.getName() + " is a web jar, but it's also a bundle, " + "to ignore it."); continue; } // It's a web jar. if (DependencyCopy.SCOPE_COMPILE.equalsIgnoreCase(artifact.getScope())) { mojo.getLog().info("Copying web jar library " + file.getName() + " to the application directory"); FileUtils.copyFileToDirectory(file, application); // Check whether or not it must be unpacked to target/webjars. if (unpackWebJars) { extract(mojo, file, new File(mojo.buildDirectory, "webjars"), true); } // NOTE: webjars from the 'provided' scope are not unpacked in target/webjars as they are in // target/wisdom/assets/libs. } else { mojo.getLog().info("Extracting web jar libraries from " + file.getName() + " to " + webjars .getAbsolutePath()); extract(mojo, file, webjars, false); } } } } /** * Checks whether the given file is a WebJar or not (http://www.webjars.org/documentation). * The check is based on the presence of {@literal META-INF/resources/webjars/} directory in the jar file. * * @param file the file. * @return {@literal true} if it's a bundle, {@literal false} otherwise. */ public static boolean isWebJar(File file) { Set found = new LinkedHashSet<>(); if (file.isFile() && file.getName().endsWith(".jar")) { JarFile jar = null; try { jar = new JarFile(file); // Fast return if the base structure is not there if (jar.getEntry(WEBJAR_LOCATION) == null) { return false; } Enumeration entries = jar.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); Matcher matcher = WEBJAR_REGEX.matcher(entry.getName()); if (matcher.matches()) { found.add(matcher.group(1) + "-" + matcher.group(2)); } } } catch (IOException e) { LoggerFactory.getLogger(DependencyCopy.class).error("Cannot check if the file {} is a webjar, " + "cannot open it", file.getName(), e); return false; } finally { final JarFile finalJar = jar; IOUtils.closeQuietly(new Closeable() { @Override public void close() throws IOException { if (finalJar != null) { finalJar.close(); } } }); } for (String lib : found) { LoggerFactory.getLogger(DependencyCopy.class).info("Web Library found in {} : {}", file.getName(), lib); } return !found.isEmpty(); } return false; } private static void extract(final AbstractWisdomMojo mojo, File in, File out, boolean stripVersion) throws IOException { ZipFile file = new ZipFile(in); try { Enumeration entries = file.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); if (entry.getName().startsWith(WEBJAR_LOCATION) && !entry.isDirectory()) { // Compute destination. File output = new File(out, entry.getName().substring(WEBJAR_LOCATION.length())); if (stripVersion) { String path = entry.getName().substring(WEBJAR_LOCATION.length()); Matcher matcher = WEBJAR_INTERNAL_PATH_REGEX.matcher(path); if (matcher.matches()) { output = new File(out, matcher.group(1) + "/" + matcher.group(3)); } else { mojo.getLog().warn(path + " does not match the regex - did not strip the version for this" + " file"); } } InputStream stream = null; try { stream = file.getInputStream(entry); output.getParentFile().mkdirs(); FileUtils.copyInputStreamToFile(stream, output); } catch (IOException e) { mojo.getLog().error("Cannot unpack " + entry.getName() + " from " + file.getName(), e); throw e; } finally { IOUtils.closeQuietly(stream); } } } } finally { IOUtils.closeQuietly(file); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy