blob: 0874185fe46cd11158c799cfae8db1d8199f740b [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.ziplock.maven;
import org.apache.ziplock.IO;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ArchivePath;
import org.jboss.shrinkwrap.api.Filter;
import org.jboss.shrinkwrap.api.Filters;
import org.jboss.shrinkwrap.api.GenericArchive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.Asset;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.container.ClassContainer;
import org.jboss.shrinkwrap.api.container.LibraryContainer;
import org.jboss.shrinkwrap.api.container.WebContainer;
import org.jboss.shrinkwrap.api.importer.ExplodedImporter;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.ScopeType;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
public final class Mvn {
public static class Builder {
private File basedir;
private File resources;
private File webapp;
private File classes;
private String basePackage;
private String name = "test.war";
private Map<File, String> additionalResources = new HashMap<File, String>();
private ScopeType[] scopes = { ScopeType.COMPILE, ScopeType.RUNTIME };
private Filter<ArchivePath> filter = Filters.includeAll();
public Builder scopes(final ScopeType... scopes) {
this.scopes = scopes;
return this;
}
public Builder basedir(final File path) {
this.basedir = path;
return this;
}
public Builder resources(final File path) {
this.resources = path;
return this;
}
public Builder webapp(final File path) {
this.webapp = path;
return this;
}
public Builder classes(final File path) {
this.classes = path;
return this;
}
public Builder applicationPackage(final String base) {
this.basePackage = base;
return this;
}
public Builder name(final String name) {
this.name = name;
return this;
}
public Builder filter(final Filter<ArchivePath> filter) {
this.filter = filter;
return this;
}
public Builder additionalResource(final File folder, final String root) {
additionalResources.put(folder, root);
return this;
}
public Archive<?> build() {
return build(WebArchive.class);
}
public <T extends Archive<?>> T build(final Class<T> type) {
initDefaults();
final T webArchive = ShrinkWrap.create(type, name);
if (basePackage != null) {
if (ClassContainer.class.isInstance(webArchive)) {
final ClassContainer<?> container = ClassContainer.class.cast(webArchive);
if (filter != null) {
container.addPackages(true, filter, basePackage);
} else {
container.addPackages(true, basePackage);
}
}
}
final String root;
if (WebContainer.class.isInstance(webArchive)) {
root = "/WEB-INF/classes";
} else {
root = "/";
}
add(webArchive, classes, root)
.add(webArchive, resources, root)
.add(webArchive, webapp, "/");
for (final Map.Entry<File, String> additionalResource : additionalResources.entrySet()) {
add(webArchive, additionalResource.getKey(), additionalResource.getValue());
}
if (LibraryContainer.class.isInstance(webArchive)) {
try {
final File[] deps = Maven.configureResolver().workOffline().loadPomFromFile(new File(basedir, "pom.xml"))
.importDependencies(scopes).resolve().withTransitivity().asFile();
if (deps.length > 0) {
LibraryContainer.class.cast(webArchive).addAsLibraries(deps);
}
} catch (final Exception e) {
// no-op: no deps
}
}
return webArchive;
}
private File basedir() {
if (basedir != null) {
return basedir;
}
{
final File file = new File("pom.xml");
if (file.exists()) {
return new File(".");
}
}
{
final File file = new File("../pom.xml");
if (file.exists()) {
return new File("..");
}
}
throw new IllegalStateException("basedir not found");
}
private void initDefaults() {
final File basedir = basedir();
if (classes == null && basePackage == null) {
classes = new File(basedir, "target/classes");
}
if (resources == null && basePackage != null) {
resources = new File(basedir, "src/main/resources");
}
if (webapp == null) {
webapp = new File(basedir, "src/main/webapp");
}
}
private Builder add(final Archive<?> webArchive, final File dir, final String root) {
if (dir == null || !dir.exists()) {
return this;
}
final KnownResourcesFilter filter = new KnownResourcesFilter(dir, root, this.filter);
filter.update(
webArchive.merge(
ShrinkWrap.create(GenericArchive.class).as(ExplodedImporter.class)
.importDirectory(dir).as(GenericArchive.class), root, filter));
return this;
}
}
/**
* Client war.
*
* @return create a war with src/main/resources, src/main/webapp and all compile and runtime dependencies
*/
public static Archive<?> war() {
return new Builder().build();
}
/**
* Server war without tests clases.
*
* @return create a war with src/main/resources, src/main/webapp and all compile, runtime and test dependencies
*/
public static Archive<?> testWar() {
return new Builder().scopes(ScopeType.COMPILE, ScopeType.RUNTIME, ScopeType.TEST).build();
}
private Mvn() {
// no-op
}
public static class KnownResourcesFilter implements Filter<ArchivePath> {
private final File base;
private final String prefix;
private final Map<ArchivePath, Asset> paths = new HashMap<ArchivePath, Asset>();
private final Filter<ArchivePath> delegate;
public KnownResourcesFilter(final File base, final String prefix, final Filter<ArchivePath> filter) {
this.base = base;
this.delegate = filter;
if (prefix.startsWith("/")) {
this.prefix = prefix.substring(1);
} else {
this.prefix = prefix;
}
}
@Override
public boolean include(final ArchivePath archivePath) {
if (!delegate.include(archivePath)) {
return false;
}
if (archivePath.get().contains("shiro.ini")) {
paths.put(archivePath, addArquillianServletInUrls(archivePath));
return false;
}
return true;
}
private Asset addArquillianServletInUrls(final ArchivePath archivePath) {
final File f = new File(base, archivePath.get());
if (!f.exists()) {
throw new IllegalArgumentException("Can't find " + archivePath.get());
}
final String ln = System.getProperty("line.separator");
final StringWriter out = new StringWriter();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(f));
String line;
while ((line = reader.readLine()) != null) {
out.write(line + ln);
if ("[urls]".equals(line)) {
out.write("/ArquillianServletRunner = anon" + ln);
}
}
} catch (final IOException e) {
throw new IllegalArgumentException(e);
} finally {
try {
IO.close(reader);
} catch (final IOException e) {
// no-op
}
}
return new StringAsset(out.toString());
}
public void update(final Archive<?> archive) {
for (final Map.Entry<ArchivePath, Asset> r : paths.entrySet()) {
archive.add(r.getValue(), prefix + r.getKey().get());
}
}
}
}