/* * Copyright (C) 2012 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.crsh.lang.impl.java; import org.crsh.AbstractTestCase; import org.crsh.util.Utils; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import javax.tools.JavaFileObject; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; /** @author Julien Viet */ public class ClasspathResolverTestCase extends AbstractTestCase { final ClassLoader parent = new ClassLoader() { @Override public URL getResource(String name) { return null; } @Override public Enumeration<URL> getResources(String name) throws IOException { return Collections.enumeration(Collections.<URL>emptyList()); } }; /** . */ private JavaArchive archive; private static List<JavaFileObject> collect(List<JavaFileObject> files) { TreeMap<String, JavaFileObject> map = new TreeMap<String, JavaFileObject>(); for (JavaFileObject file : files) { String name = file.getName(); int index = name.lastIndexOf('/'); String key = name.substring(Math.max(0, index)); map.put(key, file); } return new ArrayList<JavaFileObject>(map.values()); } @Override protected void setUp() throws Exception { URL manifest = Thread.currentThread().getContextClassLoader().getResource("META-INF/MANIFEST.MF"); archive = ShrinkWrap.create(JavaArchive.class, "my.jar"); archive.addClass(HashMap.class); archive.addClass(Map.class); archive.addClass(ConcurrentHashMap.class); archive.setManifest(manifest); } public void testDir() throws Exception { File root = toExploded(archive, ""); ClassLoader cl = new URLClassLoader(new URL[]{root.toURI().toURL()}, parent); ClasspathResolver resolver = new ClasspathResolver(cl); // No recurse List<JavaFileObject> classes = collect(Utils.list(resolver.resolve("java.util", false))); assertEquals(2, classes.size()); assertEndsWith("/HashMap.class", classes.get(0).getName()); assertEndsWith("/Map.class", classes.get(1).getName()); // Recurse classes = collect(Utils.list(resolver.resolve("java.util", true))); assertEquals(3, classes.size()); assertEndsWith("/ConcurrentHashMap.class", classes.get(0).getName()); assertEndsWith("/HashMap.class", classes.get(1).getName()); assertEndsWith("/Map.class", classes.get(2).getName()); } public void testJar() throws Exception { File jar = toFile(this.archive, ".jar"); ClassLoader cl = new URLClassLoader(new URL[]{jar.toURI().toURL()}, parent); ClasspathResolver resolver = new ClasspathResolver(cl); // No recurse List<JavaFileObject> classes = collect(Utils.list(resolver.resolve("java.util", false))); assertEquals(2, classes.size()); assertEndsWith("/HashMap.class", classes.get(0).getName()); assertEndsWith("/Map.class", classes.get(1).getName()); // Recurse classes = collect(Utils.list(resolver.resolve("java.util", true))); assertEquals(3, classes.size()); assertEndsWith("/ConcurrentHashMap.class", classes.get(0).getName()); assertEndsWith("/HashMap.class", classes.get(1).getName()); assertEndsWith("/Map.class", classes.get(2).getName()); } public void testNestedJar() throws Exception { final File war = toFile(ShrinkWrap.create(WebArchive.class).addAsLibrary(archive), ".jar"); ClassLoader cl = new ClassLoader(parent) { @Override protected Enumeration<URL> findResources(String name) throws IOException { if ("META-INF/MANIFEST.MF".equals(name)) { URL u1 = new URL("jar:" + war.toURI().toURL() + "!/META-INF/MANIFEST.MF"); URL u2 = new URL("jar:" + ("jar:" + war.toURI().toURL() + "!/WEB-INF/lib/my.jar") + "!/META-INF/MANIFEST.MF"); return Collections.enumeration(Arrays.asList(u1, u2)); } else if ("java/util".equals(name)) { String u = "jar:" + ("jar:" + war.toURI().toURL() + "!/WEB-INF/lib/my.jar") + "!/java/util/"; return Collections.enumeration(Collections.singleton(new URL(u))); } else { return super.findResources(name); } } }; ClasspathResolver resolver = new ClasspathResolver(cl); // No recurse List<JavaFileObject> classes = collect(Utils.list(resolver.resolve("java.util", false))); assertEquals(2, classes.size()); assertEndsWith("/HashMap.class", classes.get(0).getName()); assertEndsWith("/Map.class", classes.get(1).getName()); // Attempt to get stream InputStream in = classes.get(0).openInputStream(); byte[] bytes = Utils.readAsBytes(in); assertTrue(bytes.length > 0); // Recurse classes = collect(Utils.list(resolver.resolve("java.util", true))); assertEquals(3, classes.size()); assertEndsWith("/ConcurrentHashMap.class", classes.get(0).getName()); assertEndsWith("/HashMap.class", classes.get(1).getName()); assertEndsWith("/Map.class", classes.get(2).getName()); } }