From c6cec30c88b98034a97af49aa18e644a6e1b32ca Mon Sep 17 00:00:00 2001 From: Decebal Suiu Date: Wed, 25 Sep 2013 14:14:02 +0300 Subject: [PATCH] add support hidden filter for plugins directory (.svn, .cvs, ...) --- .../fortsoft/pf4j/DefaultPluginManager.java | 89 ++++++++++--------- .../java/ro/fortsoft/pf4j/PluginLoader.java | 33 ++++--- .../ro/fortsoft/pf4j/util/AndFileFilter.java | 76 ++++++++++++++++ ...ryFilter.java => DirectoryFileFilter.java} | 13 +-- ...onFilter.java => ExtensionFileFilter.java} | 17 ++-- .../ro/fortsoft/pf4j/util/HiddenFilter.java | 30 +++++++ .../{JarFilter.java => JarFileFilter.java} | 4 +- .../ro/fortsoft/pf4j/util/NotFileFilter.java | 36 ++++++++ .../{ZipFilter.java => ZipFileFilter.java} | 4 +- 9 files changed, 219 insertions(+), 83 deletions(-) create mode 100644 pf4j/src/main/java/ro/fortsoft/pf4j/util/AndFileFilter.java rename pf4j/src/main/java/ro/fortsoft/pf4j/util/{DirectoryFilter.java => DirectoryFileFilter.java} (73%) rename pf4j/src/main/java/ro/fortsoft/pf4j/util/{ExtensionFilter.java => ExtensionFileFilter.java} (74%) create mode 100644 pf4j/src/main/java/ro/fortsoft/pf4j/util/HiddenFilter.java rename pf4j/src/main/java/ro/fortsoft/pf4j/util/{JarFilter.java => JarFileFilter.java} (91%) create mode 100644 pf4j/src/main/java/ro/fortsoft/pf4j/util/NotFileFilter.java rename pf4j/src/main/java/ro/fortsoft/pf4j/util/{ZipFilter.java => ZipFileFilter.java} (91%) diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java index 186ead9..a6c9fad 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java @@ -13,7 +13,7 @@ package ro.fortsoft.pf4j; import java.io.File; -import java.io.FilenameFilter; +import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -24,11 +24,14 @@ import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ro.fortsoft.pf4j.util.AndFileFilter; import ro.fortsoft.pf4j.util.CompoundClassLoader; -import ro.fortsoft.pf4j.util.DirectoryFilter; +import ro.fortsoft.pf4j.util.DirectoryFileFilter; import ro.fortsoft.pf4j.util.FileUtils; +import ro.fortsoft.pf4j.util.HiddenFilter; +import ro.fortsoft.pf4j.util.NotFileFilter; import ro.fortsoft.pf4j.util.Unzip; -import ro.fortsoft.pf4j.util.ZipFilter; +import ro.fortsoft.pf4j.util.ZipFileFilter; /** * Default implementation of the PluginManager interface. @@ -200,9 +203,9 @@ public class DefaultPluginManager implements PluginManager { } // expand all plugin archives - FilenameFilter zipFilter = new ZipFilter(); - String[] zipFiles = pluginsDirectory.list(zipFilter); - for (String zipFile : zipFiles) { + FileFilter zipFilter = new ZipFileFilter(); + File[] zipFiles = pluginsDirectory.listFiles(zipFilter); + for (File zipFile : zipFiles) { try { expandPluginArchive(zipFile); } catch (IOException e) { @@ -211,15 +214,18 @@ public class DefaultPluginManager implements PluginManager { } // check for no plugins - FilenameFilter directoryFilter = new DirectoryFilter(); - String[] directories = pluginsDirectory.list(directoryFilter); + List filterList = new ArrayList(); + filterList.add(new DirectoryFileFilter()); + filterList.add(new NotFileFilter(createHiddenPluginFilter())); + FileFilter pluginsFilter = new AndFileFilter(filterList); + File[] directories = pluginsDirectory.listFiles(pluginsFilter); if (directories.length == 0) { log.info("No plugins"); return; } // load any plugin from plugins directory - for (String directory : directories) { + for (File directory : directories) { try { loadPlugin(directory); } catch (PluginException e) { @@ -268,15 +274,36 @@ public class DefaultPluginManager implements PluginManager { return null; } - private void loadPlugin(String fileName) throws PluginException { - // test for plugin directory - File pluginDirectory = new File(pluginsDirectory, fileName); - if (!pluginDirectory.isDirectory()) { - return; - } - + /** + * Add the possibility to override the PluginDescriptorFinder. + */ + protected PluginDescriptorFinder createPluginDescriptorFinder() { + return new DefaultPluginDescriptorFinder(); + } + + /** + * Add the possibility to override the ExtensionFinder. + */ + protected ExtensionFinder createExtensionFinder() { + return new DefaultExtensionFinder(compoundClassLoader); + } + + protected boolean isPluginDisabled(String pluginId) { + if (enabledPlugins.isEmpty()) { + return disabledPlugins.contains(pluginId); + } + + return !enabledPlugins.contains(pluginId); + } + + protected FileFilter createHiddenPluginFilter() { + return new HiddenFilter(); + } + + private void loadPlugin(File pluginDirectory) throws PluginException { // try to load the plugin - String pluginPath = "/".concat(fileName); + String pluginName = pluginDirectory.getName(); + String pluginPath = "/".concat(pluginName); // test for plugin duplication if (plugins.get(pathToIdMap.get(pluginPath)) != null) { @@ -318,37 +345,15 @@ public class DefaultPluginManager implements PluginManager { pluginClassLoaders.put(pluginId, pluginClassLoader); } - /** - * Add the possibility to override the PluginDescriptorFinder. - */ - protected PluginDescriptorFinder createPluginDescriptorFinder() { - return new DefaultPluginDescriptorFinder(); - } - - /** - * Add the possibility to override the ExtensionFinder. - */ - protected ExtensionFinder createExtensionFinder() { - return new DefaultExtensionFinder(compoundClassLoader); - } - - protected boolean isPluginDisabled(String pluginId) { - if (enabledPlugins.isEmpty()) { - return disabledPlugins.contains(pluginId); - } - - return !enabledPlugins.contains(pluginId); - } - - private void expandPluginArchive(String fileName) throws IOException { - File pluginArchiveFile = new File(pluginsDirectory, fileName); + private void expandPluginArchive(File pluginArchiveFile) throws IOException { + String fileName = pluginArchiveFile.getName(); long pluginArchiveDate = pluginArchiveFile.lastModified(); String pluginName = fileName.substring(0, fileName.length() - 4); File pluginDirectory = new File(pluginsDirectory, pluginName); // check if exists directory or the '.zip' file is "newer" than directory if (!pluginDirectory.exists() || (pluginArchiveDate > pluginDirectory.lastModified())) { log.debug("Expand plugin archive '{}' in '{}'", pluginArchiveFile, pluginDirectory); - // create directorie for plugin + // create directory for plugin pluginDirectory.mkdirs(); // expand '.zip' file diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginLoader.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginLoader.java index 1ad4245..d65b3f8 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginLoader.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginLoader.java @@ -13,15 +13,15 @@ package ro.fortsoft.pf4j; import java.io.File; -import java.io.FilenameFilter; +import java.io.FileFilter; import java.net.MalformedURLException; import java.util.Vector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import ro.fortsoft.pf4j.util.DirectoryFilter; -import ro.fortsoft.pf4j.util.JarFilter; +import ro.fortsoft.pf4j.util.DirectoryFileFilter; +import ro.fortsoft.pf4j.util.JarFileFilter; /** * Load all informations needed by a plugin. @@ -77,20 +77,20 @@ class PluginLoader { return loadClasses() && loadJars(); } - private void getJars(Vector v, File file) { - FilenameFilter jarFilter = new JarFilter(); - FilenameFilter directoryFilter = new DirectoryFilter(); + private void getJars(Vector bucket, File file) { + FileFilter jarFilter = new JarFileFilter(); + FileFilter directoryFilter = new DirectoryFileFilter(); if (file.exists() && file.isDirectory() && file.isAbsolute()) { - String[] jars = file.list(jarFilter); + File[] jars = file.listFiles(jarFilter); for (int i = 0; (jars != null) && (i < jars.length); ++i) { - v.addElement(jars[i]); + bucket.addElement(jars[i]); } - String[] directoryList = file.list(directoryFilter); - for (int i = 0; (directoryList != null) && (i < directoryList.length); ++i) { - File directory = new File(file, directoryList[i]); - getJars(v, directory); + File[] directories = file.listFiles(directoryFilter); + for (int i = 0; (directories != null) && (i < directories.length); ++i) { + File directory = directories[i]; + getJars(bucket, directory); } } } @@ -122,13 +122,12 @@ class PluginLoader { // make 'jarDirectory' absolute libDirectory = libDirectory.getAbsoluteFile(); - Vector jars = new Vector(); + Vector jars = new Vector(); getJars(jars, libDirectory); - for (String jar : jars) { - File jarFile = new File(libDirectory, jar); + for (File jar : jars) { try { - pluginClassLoader.addURL(jarFile.toURI().toURL()); - log.debug("Added '{}' to the class loader path", jarFile); + pluginClassLoader.addURL(jar.toURI().toURL()); + log.debug("Added '{}' to the class loader path", jar); } catch (MalformedURLException e) { e.printStackTrace(); log.error(e.getMessage(), e); diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/AndFileFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/AndFileFilter.java new file mode 100644 index 0000000..b50e852 --- /dev/null +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/util/AndFileFilter.java @@ -0,0 +1,76 @@ +/* + * Copyright 2013 Decebal Suiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with + * the License. You may obtain a copy of the License in the LICENSE file, or 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 ro.fortsoft.pf4j.util; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * This filter providing conditional AND logic across a list of + * file filters. This filter returns true if all filters in the + * list return true. Otherwise, it returns false. + * Checking of the file filter list stops when the first filter returns + * false. + * + * @author Decebal Suiu + */ +public class AndFileFilter implements FileFilter { + + /** The list of file filters. */ + private List fileFilters; + + public AndFileFilter() { + this.fileFilters = new ArrayList(); + } + + public AndFileFilter(List fileFilters) { + this.fileFilters = new ArrayList(fileFilters); + } + + public void addFileFilter(FileFilter fileFilter) { + fileFilters.add(fileFilter); + } + + public List getFileFilters() { + return Collections.unmodifiableList(fileFilters); + } + + public boolean removeFileFilter(FileFilter fileFilter) { + return fileFilters.remove(fileFilter); + } + + public void setFileFilters(List fileFilters) { + this.fileFilters = new ArrayList(fileFilters); + } + + @Override + public boolean accept(File file) { + if (this.fileFilters.size() == 0) { + return false; + } + + for (Iterator iter = this.fileFilters.iterator(); iter.hasNext();) { + FileFilter fileFilter = (FileFilter) iter.next(); + if (!fileFilter.accept(file)) { + return false; + } + } + + return true; + } + +} diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectoryFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectoryFileFilter.java similarity index 73% rename from pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectoryFilter.java rename to pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectoryFileFilter.java index 54e1a95..3877222 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectoryFilter.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectoryFileFilter.java @@ -14,22 +14,17 @@ package ro.fortsoft.pf4j.util; import java.io.File; import java.io.FileFilter; -import java.io.FilenameFilter; /** + * Filter accepts files that are directories. + * * @author Decebal Suiu */ -public class DirectoryFilter implements FileFilter, FilenameFilter { +public class DirectoryFileFilter implements FileFilter { - /** - * Accepts any file ending in .jar. The case of the filename is ignored. - */ + @Override public boolean accept(File file) { return file.isDirectory(); } - public boolean accept(File dir, String name) { - return accept(new File(dir, name)); - } - } diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/ExtensionFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/ExtensionFileFilter.java similarity index 74% rename from pf4j/src/main/java/ro/fortsoft/pf4j/util/ExtensionFilter.java rename to pf4j/src/main/java/ro/fortsoft/pf4j/util/ExtensionFileFilter.java index e5561b6..03ed0b7 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/util/ExtensionFilter.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/util/ExtensionFileFilter.java @@ -13,30 +13,25 @@ package ro.fortsoft.pf4j.util; import java.io.File; -import java.io.FilenameFilter; +import java.io.FileFilter; /** + * Filter accepts any file ending in extension. The case of the filename is ignored. + * * @author Decebal Suiu */ -public class ExtensionFilter implements FilenameFilter { +public class ExtensionFileFilter implements FileFilter { private String extension; - public ExtensionFilter(String extension) { + public ExtensionFileFilter(String extension) { this.extension = extension; } - /** - * Accepts any file ending in extension. The case of the filename is ignored. - */ + @Override public boolean accept(File file) { // perform a case insensitive check. return file.getName().toUpperCase().endsWith(extension.toUpperCase()); } - @Override - public boolean accept(File dir, String name) { - return accept(new File(dir, name)); - } - } diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/HiddenFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/HiddenFilter.java new file mode 100644 index 0000000..eed53f1 --- /dev/null +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/util/HiddenFilter.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013 Decebal Suiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with + * the License. You may obtain a copy of the License in the LICENSE file, or 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 ro.fortsoft.pf4j.util; + +import java.io.File; +import java.io.FileFilter; + +/** + * Filter that only accepts hidden files. + * + * @author decebal.suiu + */ +public class HiddenFilter implements FileFilter { + + @Override + public boolean accept(File file) { + return file.isHidden(); + } + +} diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/JarFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/JarFileFilter.java similarity index 91% rename from pf4j/src/main/java/ro/fortsoft/pf4j/util/JarFilter.java rename to pf4j/src/main/java/ro/fortsoft/pf4j/util/JarFileFilter.java index 60c8859..5c1f0ca 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/util/JarFilter.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/util/JarFileFilter.java @@ -18,14 +18,14 @@ package ro.fortsoft.pf4j.util; * * @author Decebal Suiu */ -public class JarFilter extends ExtensionFilter { +public class JarFileFilter extends ExtensionFileFilter { /** * The extension that this filter will search for. */ private static final String JAR_EXTENSION = ".JAR"; - public JarFilter() { + public JarFileFilter() { super(JAR_EXTENSION); } diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/NotFileFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/NotFileFilter.java new file mode 100644 index 0000000..68ff3e0 --- /dev/null +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/util/NotFileFilter.java @@ -0,0 +1,36 @@ +/* + * Copyright 2013 Decebal Suiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with + * the License. You may obtain a copy of the License in the LICENSE file, or 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 ro.fortsoft.pf4j.util; + +import java.io.File; +import java.io.FileFilter; + +/** + * This filter produces a logical NOT of the filters specified. + * + * @author Decebal Suiu + */ +public class NotFileFilter implements FileFilter { + + private FileFilter filter; + + public NotFileFilter(FileFilter filter) { + this.filter = filter; + } + + @Override + public boolean accept(File file) { + return !filter.accept(file); + } + +} diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/ZipFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/ZipFileFilter.java similarity index 91% rename from pf4j/src/main/java/ro/fortsoft/pf4j/util/ZipFilter.java rename to pf4j/src/main/java/ro/fortsoft/pf4j/util/ZipFileFilter.java index 4b10de3..9743fb6 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/util/ZipFilter.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/util/ZipFileFilter.java @@ -18,14 +18,14 @@ package ro.fortsoft.pf4j.util; * * @author Decebal Suiu */ -public class ZipFilter extends ExtensionFilter { +public class ZipFileFilter extends ExtensionFileFilter { /** * The extension that this filter will search for. */ private static final String ZIP_EXTENSION = ".ZIP"; - public ZipFilter() { + public ZipFileFilter() { super(ZIP_EXTENSION); } -- 2.39.5