Mercurial > hg > thermostat
changeset 2283:bc41e22fcd76
Also look in user plugins dir for plugin jars.
Reviewed-by: neugens
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-May/018696.html
PR2948
author | Severin Gehwolf <sgehwolf@redhat.com> |
---|---|
date | Tue, 03 May 2016 10:42:25 +0200 |
parents | 3b3a9e977dd1 |
children | 24356daad9c5 |
files | launcher/src/main/java/com/redhat/thermostat/launcher/PluginDirFileVisitor.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/BundleManagerImpl.java launcher/src/test/java/com/redhat/thermostat/launcher/PluginDirFileVisitorTest.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/BundleManagerImplTest.java |
diffstat | 4 files changed, 185 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/PluginDirFileVisitor.java Tue May 03 10:42:25 2016 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.launcher; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; + +/** + * A simple file visitor for plugin directories. I.e. directories where + * Thermostat plugins are located. + * + */ +public class PluginDirFileVisitor extends SimpleFileVisitor<Path> { + + private static final Path DONT_SCAN_DIR = Paths.get("plugin-libs"); + + // package-private for testing + FileVisitResult previsitDir(Path file) { + Path fileName = file.getFileName(); + if (fileName != null && fileName.equals(DONT_SCAN_DIR)) { + return FileVisitResult.SKIP_SUBTREE; + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path file, BasicFileAttributes attrs) throws IOException { + return previsitDir(file); + } +}
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/BundleManagerImpl.java Mon May 02 11:13:22 2016 +0200 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/BundleManagerImpl.java Tue May 03 10:42:25 2016 +0200 @@ -42,8 +42,6 @@ import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.HashMap; @@ -66,14 +64,13 @@ import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.launcher.BundleInformation; import com.redhat.thermostat.launcher.BundleManager; +import com.redhat.thermostat.launcher.PluginDirFileVisitor; import com.redhat.thermostat.shared.config.CommonPaths; public class BundleManagerImpl extends BundleManager { private static final Logger logger = LoggingUtils.getLogger(BundleManagerImpl.class); - private static final Path DONT_SCAN_DIR = Paths.get("plugin-libs"); - // Bundle Name and version -> path (with symlinks resolved) // Match FrameworkProvider which uses canonical/symlink-resolved paths. If // there is a mismatch, there are going to be clashes with trying to load @@ -82,7 +79,6 @@ // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1514 private final Map<BundleInformation, Path> known; private CommonPaths paths; - private boolean printOSGiInfo = false; private boolean ignoreBundleVersions = false; private BundleLoader loader; @@ -92,49 +88,53 @@ this.paths = paths; loader = new BundleLoader(); - scanForBundles(); + scanForBundles(paths, known); } - private void scanForBundles() { + private static void scanForBundles(CommonPaths paths, Map<BundleInformation, Path> known) { long t1 = System.nanoTime(); final FileInspector inspector = new FileInspector(known); try { // Don't scan libs folder recursively. We only do that for the - // plugins folder + // plugins folders for (File file: paths.getSystemLibRoot().listFiles()) { inspector.inspectFile(file); } - Files.walkFileTree(paths.getSystemPluginRoot().toPath(), new SimpleFileVisitor<Path>() { - - @Override - public FileVisitResult preVisitDirectory(Path file, BasicFileAttributes attrs) throws IOException { - // Don't visit directories with name "plugin-libs" - return previsitDir(file); - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - inspector.inspectFile(file.toFile()); - return FileVisitResult.CONTINUE; - } - - }); + Path[] pluginsFolders = getPluginRoots(paths); + for (Path p: pluginsFolders) { + Files.walkFileTree(p, new PluginDirFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + inspector.inspectFile(file.toFile()); + return FileVisitResult.CONTINUE; + } + + }); + } } catch (IOException e) { logger.log(Level.WARNING, "Error scanning bundles for metadata", e); } long t2 = System.nanoTime(); - if (printOSGiInfo) { - logger.fine("Found: " + known.size() + " bundles"); - logger.fine("Took " + (t2 -t1) + "ns"); - } + logger.fine("Found: " + known.size() + " bundles"); + logger.fine("Took " + (t2 -t1) + "ns"); for (Entry<BundleInformation, Path> bundles : known.entrySet()) { logger.finest(bundles.getKey().toString() + " is at " + bundles.getValue().toString()); } } + /** For TESTS only */ + static Path[] getPluginRoots(CommonPaths paths) { + Path[] pluginsFolders = new Path[] { + paths.getSystemPluginRoot().toPath(), + paths.getUserPluginRoot().toPath() + }; + return pluginsFolders; + } + /** For TESTS only: explicitly specify known bundles */ void setKnownBundles(Map<BundleInformation,Path> knownData) { known.clear(); @@ -142,19 +142,9 @@ known.put(entry.getKey(), entry.getValue()); } } - - // package-private for testing - FileVisitResult previsitDir(Path file) { - Path fileName = file.getFileName(); - if (fileName != null && fileName.equals(DONT_SCAN_DIR)) { - return FileVisitResult.SKIP_SUBTREE; - } - return FileVisitResult.CONTINUE; - } /* Used via reflection from launcher */ public void setPrintOSGiInfo(boolean printOSGiInfo) { - this.printOSGiInfo = printOSGiInfo; loader.setPrintOSGiInfo(printOSGiInfo); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/PluginDirFileVisitorTest.java Tue May 03 10:42:25 2016 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.launcher; + +import static org.junit.Assert.assertEquals; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.junit.Test; + +public class PluginDirFileVisitorTest { + + @Test + public void verifyDontScanDirIsNotVisited() throws FileNotFoundException, IOException { + PluginDirFileVisitor visitor = new PluginDirFileVisitor(); + Path skipMe = Paths.get("plugin-libs"); + FileVisitResult result = visitor.previsitDir(skipMe); + assertEquals(FileVisitResult.SKIP_SUBTREE, result); + } + + @Test + public void verifyRegularDirIsVisited() throws FileNotFoundException, IOException { + PluginDirFileVisitor visitor = new PluginDirFileVisitor(); + Path pathNotToSkip = Paths.get("/path/to/plugins/vm-byteman"); + FileVisitResult result = visitor.previsitDir(pathNotToSkip); + assertEquals(FileVisitResult.CONTINUE, result); + } +}
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BundleManagerImplTest.java Mon May 02 11:13:22 2016 +0200 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BundleManagerImplTest.java Tue May 03 10:42:25 2016 +0200 @@ -46,7 +46,6 @@ import static org.powermock.api.mockito.PowerMockito.whenNew; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.Method; import java.nio.file.FileVisitResult; @@ -58,8 +57,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.junit.After; import org.junit.Before; @@ -105,6 +106,7 @@ paths = mock(CommonPaths.class); when(paths.getSystemLibRoot()).thenReturn(jarRootDir.toFile()); when(paths.getSystemPluginRoot()).thenReturn(pluginRootDir.toFile()); + when(paths.getUserPluginRoot()).thenReturn(pluginRootDir.toFile()); theContext = mock(BundleContext.class); theFramework = mock(Framework.class); @@ -292,19 +294,27 @@ } @Test - public void verifyDontScanDirIsNotVisited() throws FileNotFoundException, IOException { - BundleManagerImpl manager = new BundleManagerImpl(paths); - Path skipMe = Paths.get("plugin-libs"); - FileVisitResult result = manager.previsitDir(skipMe); - assertEquals(FileVisitResult.SKIP_SUBTREE, result); - } - - @Test - public void verifyRegularDirIsVisited() throws FileNotFoundException, IOException { - BundleManagerImpl manager = new BundleManagerImpl(paths); - Path pathNotToSkip = Paths.get("/path/to/plugins/vm-byteman"); - FileVisitResult result = manager.previsitDir(pathNotToSkip); - assertEquals(FileVisitResult.CONTINUE, result); + public void verifyUserPluginsAreUsedForDepScanning() throws Exception { + CommonPaths customPaths = mock(CommonPaths.class); + File systemPluginsFile = mock(File.class); + Path systemPluginsPath = mock(Path.class); + when(systemPluginsFile.toPath()).thenReturn(systemPluginsPath); + File userPluginsFile = mock(File.class); + Path userPluginsPath = mock(Path.class); + when(userPluginsFile.toPath()).thenReturn(userPluginsPath); + when(customPaths.getSystemPluginRoot()).thenReturn(systemPluginsFile); + when(customPaths.getUserPluginRoot()).thenReturn(userPluginsFile); + + Path[] paths = BundleManagerImpl.getPluginRoots(customPaths); + assertEquals(2, paths.length); + + Set<Path> expected = new HashSet<>(); + expected.add(systemPluginsPath); + expected.add(userPluginsPath); + + Set<Path> actual = new HashSet<>(); + actual.addAll(Arrays.asList(paths)); + assertEquals(expected, actual); } }