diff options
Diffstat (limited to 'test/src/itest-common/src/main/groovy/org/apache/bigtop/itest/JarContent.groovy')
-rw-r--r-- | test/src/itest-common/src/main/groovy/org/apache/bigtop/itest/JarContent.groovy | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/test/src/itest-common/src/main/groovy/org/apache/bigtop/itest/JarContent.groovy b/test/src/itest-common/src/main/groovy/org/apache/bigtop/itest/JarContent.groovy new file mode 100644 index 00000000..d3764822 --- /dev/null +++ b/test/src/itest-common/src/main/groovy/org/apache/bigtop/itest/JarContent.groovy @@ -0,0 +1,237 @@ +/** + * 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 + * <p/> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p/> + * 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.bigtop.itest + +import java.util.jar.JarEntry +import java.util.jar.JarFile +import java.util.zip.ZipInputStream +import java.util.zip.ZipException +import org.apache.commons.logging.LogFactory +import org.apache.commons.logging.Log + +public abstract class JarContent { + static private Log LOG = LogFactory.getLog(JarContent.class); + + static { + // Calling MOP hooks + bootstrapPlugins(); + } + + private static List<String> patterns = null; + private static List<String> content = null; + // Exclude META* and inner classes + def public static defaultExclPattern = ['.*META.*', '.*\\$.*.class'] + + /** + * Lists content of a given jar file excluding defaultExclPattern and any extra + * patterns set via {@link JarContent#setPatterns} call + * @param jarFileName file for a jar + * @return list of Strings representing jar's entries + * @throws IOException if file isn't found and anything else goes wrong + */ + def static List<String> listContent(String jarFileName) throws IOException { + content = new ArrayList<String>(); + if (jarFileName == null) { + throw new IOException("Specify a jar file name"); + } + JarFile jarFile; + try { + jarFile = new JarFile(jarFileName) + } catch (ZipException ze) { + throw new IOException("Could not open " + jarFileName + " file.", ze); + }; + + Enumeration<JarEntry> entries = jarFile.entries(); + while (entries.hasMoreElements()) { + def en = process(entries.nextElement()); + en != null ? content.add(en) : null; + } + setPatterns(defaultExclPattern); + + content = applyExcludeFilter(content, patterns); + return content; + } + + private static String process(JarEntry jarEntry) throws IOException { + JarEntry entry = jarEntry; + String name = entry.getName(); + if (!entry.isDirectory()) + return name; + return null; + } + + /** + * Set a list of new patterns to be applied in the processing of a jar file + * @param filterPatters list of pattern strings + * @return list of currently set patterns. Next call of this method will + * reset the content of patterns' list. + */ + def static List<String> setPatterns(List<String> filterPatters) { + patterns = new ArrayList<String>(); + filterPatters.each { + patterns.add(it); + } + return patterns; + } + + /** + * Filter out any entries which match given patterns + * @param list of entries + * @param filters list of patterns + * @return filtered-out list of entries + */ + def static List<String> applyExcludeFilter(final List<String> list, final List<String> filters) { + List<String> filtered = list.asList(); + ArrayList<String> toRemove = new ArrayList<String>(); + + filters.each { + def pattern = ~/${it}/ + for (l in list) { + if (pattern.matcher(l).matches()) + toRemove.add(l); + } + } + filtered.removeAll(toRemove); + return filtered; + } + + /** + * Finds JAR URL of an object's class belongs to + * @param ref Class reference of a class belongs to a jar file + * @return JAR URL or <code>null</code> if class doesn't belong + * to a JAR in the classpath + */ + public static URL getJarURL(Class ref) { + URL clsUrl = ref.getResource(ref.getSimpleName() + ".class"); + if (clsUrl != null) { + try { + URLConnection conn = clsUrl.openConnection(); + if (conn instanceof JarURLConnection) { + JarURLConnection connection = (JarURLConnection) conn; + return connection.getJarFileURL(); + } + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + return null; + } + + /** + * Finds JAR URL of an object's class belongs to + * @param className is full name of the class e.g. java.lang.String + * @return JAR URL or <code>null</code> if class doesn't belong + * to a JAR in the classpath + * @throws ClassNotFoundException if class specified by className wasn't found + */ + public static URL getJarURL(String className) throws ClassNotFoundException { + Class cl = Class.forName(className) + return getJarURL(cl) + } + + /** + * Returns full name of a jar file by a pattern + * @param baseDir to look for a jar under + * @param namePattern to look for a jar by + * @return name of the jar file if found; <code>null</code> otherwise + */ + public static String getJarName(String baseDir, String namePattern) { + try { + return new File(baseDir).list( + [accept: {d, f -> f ==~ /$namePattern/ }] as FilenameFilter + ).toList().get(0); + } catch (java.lang.IndexOutOfBoundsException ioob) { + LOG.error ("No $namePattern has been found under $baseDir. Check your installation."); + } catch (java.lang.NullPointerException npe) { + LOG.error("No $baseDir exists. Check your installation."); + } + return null; + } + + /** + * Finds and unpack a jar file by locating to what jar file a given class belongs + * and unpacking jar content to desalination according to given includes + * @param ref + * @param destination + * @param includes + * @throws IOException if can't find class' jar file in the classpath + */ + public static void unpackJarContainer (Class ref, + String destination, String includes) throws IOException { + URL connection = JarContent.getJarURL(ref); + if (connection == null) { + throw new IOException("Class " + ref.getSimpleName() + + " doesn't belong to any jar file in the classpath"); + } + ZipInputStream fis = + new ZipInputStream(connection.openConnection().getInputStream()); + fis.unzip (destination, includes); + + } + + public static unpackJarContainer (String className, + String destination, String includes) throws IOException { + Class cl = Class.forName(className) + unpackJarContainer (cl, destination, includes) + } + + private static void bootstrapPlugins() { + /** + * Adding an ability to unpack a content of an given ZipInputStream + * to specified destination with given pattern + * @param dest directory where the content will be unpacked + * @param includes regexps to include resources to be unpacked + */ + ZipInputStream.metaClass.unzip = { String dest, String includes -> + //in metaclass added methods, 'delegate' is the object on which + //the method is called. Here it's the file to unzip + if (includes == null) includes = ""; + def result = delegate + def destFile = new File(dest) + if (!destFile.exists()) { + destFile.mkdir(); + } + result.withStream { + def entry + while (entry = result.nextEntry) { + if (!entry.name.contains(includes)) { + continue + }; + if (!entry.isDirectory()) { + new File(dest + File.separator + entry.name).parentFile?.mkdirs() + def output = new FileOutputStream(dest + File.separator + + entry.name) + output.withStream { + int len; + byte[] buffer = new byte[4096] + while ((len = result.read(buffer)) > 0) { + output.write(buffer, 0, len); + } + } + } + else { + new File(dest + File.separator + entry.name).mkdir() + } + } + } + } + } +} + |