/* * Copyright 2013 Harald Wellmann * * 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. * */ package org.ops4j.pax.exam.spi.war; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.UUID; import org.ops4j.io.FileUtils; import org.ops4j.io.StreamUtils; import org.ops4j.pax.exam.TestContainerException; import org.ops4j.pax.exam.options.JarProbeOption; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Builds a JAR according to a {@link JarProbeOption}. * * @author Harald Wellmann * */ public class JarBuilder { private static final Logger LOG = LoggerFactory.getLogger(JarBuilder.class); /** * Temporary directory for assembling the JAR probe. */ private File tempDir; /** * Option used to configure the JAR. */ private JarProbeOption option; /** * Constructs a JAR builder for the given option. * * @param tempDir * temporary directory * @param option * JAR probe option */ public JarBuilder(File tempDir, JarProbeOption option) { this.option = option; this.tempDir = tempDir; } /** * Builds a JAR from the given option. * * @return file URI referencing the JAR in a temporary directory */ public URI buildJar() { if (option.getName() == null) { option.name(UUID.randomUUID().toString()); } try { File explodedJarDir = getExplodedJarDir(); File probeJar = new File(tempDir, option.getName() + ".jar"); ZipBuilder builder = new ZipBuilder(probeJar); builder.addDirectory(explodedJarDir, ""); builder.close(); URI warUri = probeJar.toURI(); LOG.info("JAR probe = {}", warUri); return warUri; } catch (IOException exc) { throw new TestContainerException(exc); } } private File getExplodedJarDir() throws IOException { File jarDir = new File(tempDir, "jar"); LOG.debug("building webapp in {}", jarDir); jarDir.mkdir(); File metaInfDir = new File(jarDir, "META-INF"); metaInfDir.mkdir(); for (String metaInfResource : option.getMetaInfResources()) { File source = new File(metaInfResource); if (source.isDirectory()) { copyDirectory(source, metaInfDir); } else { FileUtils.copyFile(source, new File(metaInfDir, source.getName()), null); } } File resourceDir = jarDir; resourceDir.mkdir(); for (Class<?> klass : option.getClasses()) { addClass(klass, resourceDir); } for (String resource : option.getResources()) { addResource(resource, resourceDir); } return jarDir; } private void addClass(Class<?> klass, File resourceDir) throws IOException { String resource = "/" + klass.getName().replaceAll("\\.", "/") + ".class"; addResource(resource, resourceDir); for (Class<?> innerClass : klass.getClasses()) { addClass(innerClass, resourceDir); } } private void addResource(String resource, File resourceDir) throws IOException { InputStream is = getClass().getResourceAsStream("/" + resource); File target = new File(resourceDir, resource); target.getParentFile().mkdirs(); FileOutputStream os = new FileOutputStream(target); StreamUtils.copyStream(is, os, true); } private void copyDirectory(File fromDir, File toDir) throws IOException { for (File file : fromDir.listFiles()) { if (file.isDirectory()) { File targetDir = new File(toDir, file.getName()); targetDir.mkdir(); copyDirectory(file, targetDir); } else { FileUtils.copyFile(file, new File(toDir, file.getName()), null); } } } }