/* * JBoss, Home of Professional Open Source * Copyright 2016, Red Hat, Inc., and individual contributors as indicated * by the @authors tag. * * 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.jboss.modules; import java.io.File; import java.io.IOException; import java.net.JarURLConnection; import java.net.URI; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.nio.file.attribute.BasicFileAttributes; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; /** * Test absolute and relative paths in resource-roots' path attribute (MODULES-218) * @author Martin Simka */ public class ResourceRootPathsTest extends AbstractModuleTestCase { @Rule public TemporaryFolder tmpDir = new TemporaryFolder(); private File repoRoot; private File testModuleRoot; private File fileResourceRoot; private static final String MODULE_XML_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<module xmlns=\"urn:jboss:module:1.5\" name=\"test.test\">\n" + " <resources>\n" + " <resource-root name=\"relativejar\" path=\"relative.jar\" />\n" + " <resource-root name=\"absolutejar\" path=\"@absolutejar@\" />\n" + " <resource-root name=\"relativedir\" path=\"relativedir\" />\n" + " <resource-root name=\"absolutedir\" path=\"@absolutedir@\" />\n" + " </resources>\n" + "</module>"; private ModuleLoader moduleLoader; @Before public void setupModuleLoader() throws Exception { repoRoot = tmpDir.newFolder("repo"); testModuleRoot = new File(repoRoot, "test/test/main/"); // Build a jar in module copyResource("org/jboss/modules/test/TestClass.class", "test/fileresourceloader", "org/jboss/modules/test"); fileResourceRoot = getResource("test/fileresourceloader"); final File jarInModule = new File(testModuleRoot, "relative.jar"); jarInModule.getParentFile().mkdirs(); JarResourceLoaderTest.buildJar(fileResourceRoot, jarInModule); // Build a jar outside of module final File jarOutsideModule = new File(repoRoot, "relative.jar"); JarResourceLoaderTest.buildJar(fileResourceRoot, jarOutsideModule); // copy resource dir to module copyDir(fileResourceRoot, new File(testModuleRoot, "relativedir")); //create module.xml final File moduleXml = new File(testModuleRoot, "module.xml"); String moduleXmlContent = MODULE_XML_TEMPLATE.replaceAll("@absolutejar@", jarOutsideModule.getCanonicalPath().replace(File.separatorChar, '/')); moduleXmlContent = moduleXmlContent.replaceAll("@absolutedir@", fileResourceRoot.getCanonicalPath().replace(File.separatorChar, '/')); Files.write(moduleXml.toPath(), moduleXmlContent.getBytes(), StandardOpenOption.CREATE_NEW); moduleLoader = new LocalModuleLoader(new File[] {repoRoot}); } @Test public void testPaths() throws Exception { ConcreteModuleSpec moduleSpec = (ConcreteModuleSpec) moduleLoader.findModule("test.test"); ResourceLoaderSpec[] resourceLoaders = moduleSpec.getResourceLoaders(); int checkCount = 0; for (ResourceLoaderSpec r : resourceLoaders) { ResourceLoader resourceLoader = r.getResourceLoader(); if (resourceLoader instanceof JarFileResourceLoader) { // validate jar with relative path if(resourceLoader.getRootName().equals("relativejar")) { checkCount++; final File relativeJar = getFileFromJarUri(resourceLoader.getLocation()); Assert.assertEquals(testModuleRoot, relativeJar.getParentFile()); continue; } // validate jar with absolute path if(resourceLoader.getRootName().equals("absolutejar")) { checkCount++; final File absoluteJar = getFileFromJarUri(resourceLoader.getLocation()); Assert.assertEquals(repoRoot, absoluteJar.getParentFile()); continue; } } else if (resourceLoader instanceof FileResourceLoader) { // validate dir with relative path if(resourceLoader.getRootName().equals("relativedir")) { checkCount++; final File relativeDir = new File(resourceLoader.getLocation()); Assert.assertEquals(testModuleRoot, relativeDir.getParentFile()); continue; } // validate dir with absolute path if(resourceLoader.getRootName().equals("absolutedir")) { checkCount++; final File absoluteDir = new File(resourceLoader.getLocation()); Assert.assertEquals(fileResourceRoot.getParentFile(), absoluteDir.getParentFile()); continue; } } } Assert.assertEquals("Test should have checked 4 ResourceLoaders", 4, checkCount); } private File getFileFromJarUri(URI uri) throws Exception { JarURLConnection connection = (JarURLConnection) uri.toURL().openConnection(); File file = new File(connection.getJarFileURL().toURI()); return file; } static void copyDir(File sourceDir, File targetDir) throws Exception { abstract class CopyFileVisitor implements FileVisitor<Path> { boolean isFirst = true; Path ptr; } CopyFileVisitor copyVisitor = new CopyFileVisitor() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { if (!isFirst) { Path target = ptr.resolve(dir.getName(dir.getNameCount() - 1)); ptr = target; } Files.copy(dir, ptr, StandardCopyOption.COPY_ATTRIBUTES); isFirst = false; return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Path target = ptr.resolve(file.getFileName()); Files.copy(file, target, StandardCopyOption.COPY_ATTRIBUTES); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { throw exc; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { Path target = ptr.getParent(); ptr = target; return FileVisitResult.CONTINUE; } }; copyVisitor.ptr = targetDir.toPath(); Files.walkFileTree(sourceDir.toPath(), copyVisitor); } }