/* * JBoss, Home of Professional Open Source * Copyright 2009, Red Hat Middleware LLC, and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * 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 at.ac.tuwien.tiss.course.fe.test; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.jar.JarInputStream; import java.util.zip.ZipEntry; /** * Lots of neat little helpers to more easily create Archives * @author Mark Struberg */ public class ArchiveUtils { /** * Resolve all markerFiles from the current ClassPath and package the root nodes * into a JavaArchive. * @param classLoader to use * @param markerFile * @param includeIfPackageExists if not null, we will only create JavaArchives if the given package exists * @param excludeIfPackageExists if not null, we will not create JavaArchives if the given package exists. * This has a higher precedence than includeIfPackageExists. * @return */ public static JavaArchive[] getArchives(ClassLoader classLoader, String markerFile, String[] includeIfPackageExists, String[] excludeIfPackageExists) throws IOException { if (classLoader == null) { classLoader = ArchiveUtils.class.getClassLoader(); } Enumeration foundFiles = classLoader.getResources(markerFile); List archives = new ArrayList(); while (foundFiles.hasMoreElements()) { URL foundFile = foundFiles.nextElement(); JavaArchive archive = createArchive(foundFile, markerFile, includeIfPackageExists, excludeIfPackageExists); if (archive != null) { archives.add(archive); } } return archives.toArray(new JavaArchive[archives.size()]); } private static JavaArchive createArchive(URL foundFile, String markerFile, String[] includeIfPackageExists, String[] excludeIfPackageExists) throws IOException { String urlString = foundFile.toString(); int idx = urlString.lastIndexOf(markerFile); urlString = urlString.substring(0, idx); String jarUrlPath = isJarUrl(urlString); if (jarUrlPath != null) { return addJarArchive((new URL(ensureCorrectUrlFormat(jarUrlPath))).openStream(), includeIfPackageExists, excludeIfPackageExists); } else { File f = new File( (new URL(ensureCorrectUrlFormat(urlString))).getFile() ); if (!f.exists()) { // try a fallback if the URL contains %20 -> spaces if (jarUrlPath.contains("%20")) { jarUrlPath = jarUrlPath.replaceAll("%20", " "); f = new File( (new URL(ensureCorrectUrlFormat(jarUrlPath))).getFile() ); } } return addFileArchive(f, includeIfPackageExists, excludeIfPackageExists); } } private static JavaArchive addJarArchive(InputStream inputStream, String[] includeIfPackageExists, String[] excludeIfPackageExists) throws IOException { JavaArchive ret = null; JavaArchive javaArchive = ShrinkWrap.create(JavaArchive.class); if (includeIfPackageExists == null) { // no include rule, thus add it immediately ret = javaArchive; } JarInputStream jar = new JarInputStream(inputStream); try { for (ZipEntry jarEntry = jar.getNextEntry(); jarEntry != null; jarEntry = jar.getNextEntry()) { String entryName = jarEntry.getName(); if (jarEntry.isDirectory()) { // exclude rule if (excludeIfPackageExists(entryName, excludeIfPackageExists)) { return null; } if (ret == null && includeIfPackageExists(entryName, includeIfPackageExists)) { ret = javaArchive; } continue; } if (entryName.endsWith(".class")) { String className = entryName.substring(0, entryName.length()-(".class".length())).replace('/', '.'); javaArchive.addClass(className); } else { javaArchive.addAsResource(entryName); } } } finally { try { jar.close(); } catch (IOException ignored) { // all fine } } return ret; } private static JavaArchive addFileArchive(File archiveBasePath, String[] includeIfPackageExists, String[] excludeIfPackageExists) throws IOException { if (!archiveBasePath.exists()) { return null; } JavaArchive ret = null; JavaArchive javaArchive = ShrinkWrap.create(JavaArchive.class); if (includeIfPackageExists == null) { // no include rule, thus add it immediately ret = javaArchive; } int basePathLength = archiveBasePath.getAbsolutePath().length() + 1; for (File archiveEntry : collectArchiveEntries(archiveBasePath) ) { String entryName = archiveEntry.getAbsolutePath().substring(basePathLength); if (archiveEntry.isDirectory()) { // exclude rule if (excludeIfPackageExists(entryName, excludeIfPackageExists)) { return null; } if (ret == null && includeIfPackageExists(entryName, includeIfPackageExists)) { ret = javaArchive; } continue; } if (entryName.endsWith(".class")) { String className = entryName.substring(0, entryName.length()-(".class".length())).replace('/', '.'); javaArchive.addClass(className); } else { javaArchive.addAsResource(entryName); } } return ret; } private static List collectArchiveEntries(File archiveBasePath) { if (archiveBasePath.isDirectory()) { List archiveEntries = new ArrayList(); File[] files = archiveBasePath.listFiles(); for (File file : files) { if (file.isDirectory()) { archiveEntries.addAll(collectArchiveEntries(file)); } else { archiveEntries.add(file); } } return archiveEntries; } return Collections.EMPTY_LIST; } private static boolean excludeIfPackageExists(String jarEntryName, String[] excludeOnPackages) { if (excludeOnPackages != null) { String packageName = jarEntryName.replace('/' ,'.'); for (String excludeOnPackage : excludeOnPackages) { if (packageName.startsWith(excludeOnPackage)) { return true; } } } return false; } private static boolean includeIfPackageExists(String jarEntryName, String[] includeOnPackages) { if (includeOnPackages == null ) { return true; } String packageName = jarEntryName.replace('/' ,'.'); for (String includeOnPackage : includeOnPackages) { if (packageName.startsWith(includeOnPackage)) { return true; } } return false; } /** * check if the given url path is a Jar * @param urlPath * @return */ private static String isJarUrl(String urlPath) { // common prefixes of the url are: jar: (tomcat), zip: (weblogic) and wsjar: (websphere) final int jarColon = urlPath.indexOf(':'); if (urlPath.endsWith("!/") && jarColon > 0) { urlPath = urlPath.substring(jarColon + 1, urlPath.length() - 2); return urlPath; } return null; } private static String ensureCorrectUrlFormat(String url) { //fix for wls if(!url.startsWith("file:/")) { url = "file:/" + url; } return url; } }