You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nutch.apache.org by je...@apache.org on 2005/09/11 22:28:16 UTC
svn commit: r280176 - in /lucene/nutch/trunk: conf/
src/java/org/apache/nutch/plugin/
Author: jerome
Date: Sun Sep 11 13:28:07 2005
New Revision: 280176
URL: http://svn.apache.org/viewcvs?rev=280176&view=rev
Log:
Automatically loads active plugins dependencies (add a property, default is on)
Added:
lucene/nutch/trunk/src/java/org/apache/nutch/plugin/CircularDependencyException.java (with props)
lucene/nutch/trunk/src/java/org/apache/nutch/plugin/MissingDependencyException.java (with props)
Modified:
lucene/nutch/trunk/conf/nutch-default.xml
lucene/nutch/trunk/src/java/org/apache/nutch/plugin/PluginManifestParser.java
lucene/nutch/trunk/src/java/org/apache/nutch/plugin/PluginRepository.java
Modified: lucene/nutch/trunk/conf/nutch-default.xml
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/conf/nutch-default.xml?rev=280176&r1=280175&r2=280176&view=diff
==============================================================================
--- lucene/nutch/trunk/conf/nutch-default.xml (original)
+++ lucene/nutch/trunk/conf/nutch-default.xml Sun Sep 11 13:28:07 2005
@@ -586,8 +586,17 @@
</property>
<property>
+ <name>plugin.auto-activation</name>
+ <value>false</value>
+ <description>Defines if some plugins that are not activated regarding
+ the plugin.includes and plugin.excludes properties must be automaticaly
+ activated if they are needed by some actived plugins.
+ </description>
+</property>
+
+<property>
<name>plugin.includes</name>
- <value>nutch-extensionpoints|protocol-httpclient|urlfilter-regex|parse-(text|html|js)|index-basic|query-(basic|site|url)</value>
+ <value>protocol-httpclient|urlfilter-regex|parse-(text|html|js)|index-basic|query-(basic|site|url)</value>
<description>Regular expression naming plugin directory names to
include. Any plugin not matching this expression is excluded.
In any case you need at least include the nutch-extensionpoints plugin. By
Added: lucene/nutch/trunk/src/java/org/apache/nutch/plugin/CircularDependencyException.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/src/java/org/apache/nutch/plugin/CircularDependencyException.java?rev=280176&view=auto
==============================================================================
--- lucene/nutch/trunk/src/java/org/apache/nutch/plugin/CircularDependencyException.java (added)
+++ lucene/nutch/trunk/src/java/org/apache/nutch/plugin/CircularDependencyException.java Sun Sep 11 13:28:07 2005
@@ -0,0 +1,35 @@
+/*
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.nutch.plugin;
+
+
+/**
+ * <code>CircularDependencyException</code> will be thrown if a circular
+ * dependency is detected.
+ *
+ * @author Jérôme Charron
+ */
+public class CircularDependencyException extends Exception {
+
+ public CircularDependencyException(Throwable cause) {
+ super(cause);
+ }
+
+ public CircularDependencyException(String message) {
+ super(message);
+ }
+}
Propchange: lucene/nutch/trunk/src/java/org/apache/nutch/plugin/CircularDependencyException.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/nutch/trunk/src/java/org/apache/nutch/plugin/MissingDependencyException.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/src/java/org/apache/nutch/plugin/MissingDependencyException.java?rev=280176&view=auto
==============================================================================
--- lucene/nutch/trunk/src/java/org/apache/nutch/plugin/MissingDependencyException.java (added)
+++ lucene/nutch/trunk/src/java/org/apache/nutch/plugin/MissingDependencyException.java Sun Sep 11 13:28:07 2005
@@ -0,0 +1,35 @@
+/*
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.nutch.plugin;
+
+
+/**
+ * <code>MissingDependencyException</code> will be thrown if a plugin
+ * dependency cannot be found.
+ *
+ * @author Jérôme Charron
+ */
+public class MissingDependencyException extends Exception {
+
+ public MissingDependencyException(Throwable cause) {
+ super(cause);
+ }
+
+ public MissingDependencyException(String message) {
+ super(message);
+ }
+}
Propchange: lucene/nutch/trunk/src/java/org/apache/nutch/plugin/MissingDependencyException.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: lucene/nutch/trunk/src/java/org/apache/nutch/plugin/PluginManifestParser.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/src/java/org/apache/nutch/plugin/PluginManifestParser.java?rev=280176&r1=280175&r2=280176&view=diff
==============================================================================
--- lucene/nutch/trunk/src/java/org/apache/nutch/plugin/PluginManifestParser.java (original)
+++ lucene/nutch/trunk/src/java/org/apache/nutch/plugin/PluginManifestParser.java Sun Sep 11 13:28:07 2005
@@ -22,7 +22,9 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
-import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import java.util.logging.Logger;
import java.util.regex.Pattern;
@@ -51,20 +53,52 @@
.startsWith("Windows");
/**
+ * Filters a list of plugins.
+ * The list of plugins is filtered regarding the configuration
+ * properties <code>plugin.excludes</code> and <code>plugin.includes</code>.
+ */
+ public static Map filter(Map plugins) {
+ Map map = new HashMap();
+ Pattern excludes = Pattern.compile(NutchConf.get().get(
+ "plugin.excludes", ""));
+ Pattern includes = Pattern.compile(NutchConf.get().get(
+ "plugin.includes", ""));
+ if (plugins == null) { return map; }
+
+ Iterator iter = plugins.values().iterator();
+ while (iter.hasNext()) {
+ PluginDescriptor plugin = (PluginDescriptor) iter.next();
+ if (plugin == null) { continue; }
+ String id = plugin.getPluginId();
+ if (id == null) { continue; }
+
+ if (!includes.matcher(id).matches()) {
+ LOG.fine("not including: " + id);
+ continue;
+ }
+ if (excludes.matcher(id).matches()) {
+ LOG.fine("excluding: " + id);
+ continue;
+ }
+ map.put(plugin.getPluginId(), plugin);
+ }
+ return map;
+ }
+
+ /**
* Returns a list with plugin descriptors.
*
* @return ArrayList
*
*/
- public static ArrayList parsePluginFolder() {
- ArrayList list = new ArrayList();
+ public static Map parsePluginFolder() {
+ Map map = new HashMap();
String[] pluginFolders = NutchConf.get().getStrings("plugin.folders");
- Pattern excludes = Pattern.compile(NutchConf.get().get(
- "plugin.excludes", ""));
- Pattern includes = Pattern.compile(NutchConf.get().get(
- "plugin.includes", ""));
- if (pluginFolders == null)
+
+ if (pluginFolders == null) {
throw new IllegalArgumentException("plugin.folders is not defined");
+ }
+
for (int i = 0; i < pluginFolders.length; i++) {
String name = pluginFolders[i];
File directory = getPluginFolder(name);
@@ -77,35 +111,25 @@
for (int j = 0; j < files.length; j++) {
File oneSubFolder = files[j];
if (oneSubFolder.isDirectory()) {
-
- if (!includes.matcher(oneSubFolder.getName()).matches()) {
- LOG.info("not including: " + oneSubFolder);
- continue;
- }
-
- if (excludes.matcher(oneSubFolder.getName()).matches()) {
- LOG.info("excluding: " + oneSubFolder);
- continue;
- }
-
String manifestPath = oneSubFolder.getAbsolutePath()
+ File.separator + "plugin.xml";
try {
- LOG.info("parsing: " + manifestPath);
- list.add(parseManifestFile(manifestPath));
+ LOG.fine("parsing: " + manifestPath);
+ PluginDescriptor p = parseManifestFile(manifestPath);
+ map.put(p.getPluginId(), p);
} catch (MalformedURLException e) {
- LOG.info(e.toString());
+ LOG.warning(e.toString());
} catch (SAXException e) {
- LOG.info(e.toString());
+ LOG.warning(e.toString());
} catch (IOException e) {
- LOG.info(e.toString());
+ LOG.warning(e.toString());
} catch (ParserConfigurationException e) {
- LOG.info(e.toString());
+ LOG.warning(e.toString());
}
}
}
}
- return list;
+ return map;
}
/**
@@ -118,10 +142,10 @@
URL url = PluginManifestParser.class.getClassLoader().getResource(
name);
if (url == null) {
- LOG.info("Plugins: directory not found: " + name);
+ LOG.warning("Plugins: directory not found: " + name);
return null;
} else if (!"file".equals(url.getProtocol())) {
- LOG.info("Plugins: not a file: url. Can't load plugins from: "
+ LOG.warning("Plugins: not a file: url. Can't load plugins from: "
+ url);
return null;
}
@@ -184,7 +208,7 @@
}
PluginDescriptor pluginDescriptor = new PluginDescriptor(id, version,
name, providerName, pluginClazz, pPath);
- LOG.fine("plugin: id="+id+" name="+name+" version="+version
+ LOG.fine("plugin: id="+id+" name="+name+" version="+version
+" provider="+providerName+"class="+pluginClazz);
parseExtension(rootElement, pluginDescriptor);
parseExtensionPoints(rootElement, pluginDescriptor);
@@ -289,7 +313,7 @@
String id = oneImplementation.getAttribute("id");
String extensionClass = oneImplementation
.getAttribute("class");
- LOG.info("impl: point=" + pointId + " class="
+ LOG.fine("impl: point=" + pointId + " class="
+ extensionClass);
Extension extension = new Extension(pPluginDescriptor,
pointId, id, extensionClass);
Modified: lucene/nutch/trunk/src/java/org/apache/nutch/plugin/PluginRepository.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/src/java/org/apache/nutch/plugin/PluginRepository.java?rev=280176&r1=280175&r2=280176&view=diff
==============================================================================
--- lucene/nutch/trunk/src/java/org/apache/nutch/plugin/PluginRepository.java (original)
+++ lucene/nutch/trunk/src/java/org/apache/nutch/plugin/PluginRepository.java Sun Sep 11 13:28:07 2005
@@ -16,14 +16,20 @@
*/
package org.apache.nutch.plugin;
+// JDK imports
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import java.util.logging.Logger;
+// Nutch imports
import org.apache.nutch.util.LogFormatter;
+import org.apache.nutch.util.NutchConf;
+
/**
* The plugin repositority is a registry of all plugins.
@@ -38,14 +44,19 @@
* @author joa23
*/
public class PluginRepository {
+
+ private final static boolean AUTO =
+ NutchConf.get().getBoolean("plugin.auto-activation", true);
+
private static PluginRepository fInstance;
- private ArrayList fRegisteredPlugins;
+ private List fRegisteredPlugins;
private HashMap fExtensionPoints;
private HashMap fActivatedPlugins;
+
public static final Logger LOG = LogFormatter
.getLogger("org.apache.nutch.plugin.PluginRepository");
@@ -54,66 +65,115 @@
* @see java.lang.Object#Object()
*/
private PluginRepository() throws PluginRuntimeException{
- fActivatedPlugins = new HashMap();
- fExtensionPoints = new HashMap();
- fRegisteredPlugins = getDependencyCheckedPlugins(PluginManifestParser
- .parsePluginFolder());
- installExtensions(fRegisteredPlugins);
+ fActivatedPlugins = new HashMap();
+ fExtensionPoints = new HashMap();
+ Map allPlugins = PluginManifestParser.parsePluginFolder();
+ Map filteredPlugins = PluginManifestParser.filter(allPlugins);
+ fRegisteredPlugins = getDependencyCheckedPlugins(
+ filteredPlugins,
+ AUTO ? allPlugins : filteredPlugins);
+ installExtensionPoints(fRegisteredPlugins);
+ installExtensions(fRegisteredPlugins);
+ displayStatus();
}
+ private void installExtensionPoints(List plugins) {
+ if (plugins == null) { return; }
+
+ for (int i=0; i<plugins.size(); i++) {
+ PluginDescriptor plugin = (PluginDescriptor) plugins.get(i);
+ ExtensionPoint[] points = plugin.getExtenstionPoints();
+ for (int j=0; j<points.length; j++) {
+ ExtensionPoint point = points[j];
+ String xpId = point.getId();
+ LOG.fine("Adding extension point " + xpId);
+ fExtensionPoints.put(xpId, point);
+ }
+ }
+ }
+
/**
* @param pRegisteredPlugins
*/
- private void installExtensions(ArrayList pRegisteredPlugins)
- throws PluginRuntimeException {
- for (int i = 0; i < pRegisteredPlugins.size(); i++) {
- PluginDescriptor descriptor = (PluginDescriptor) pRegisteredPlugins
- .get(i);
- Extension[] extensions = descriptor.getExtensions();
- for (int j = 0; j < extensions.length; j++) {
- Extension extension = extensions[j];
- String xpId = extension.getTargetPoint();
- ExtensionPoint point = getExtensionPoint(xpId);
- if (point == null)
- throw new PluginRuntimeException("extension point: " + xpId
- + " does not exist.");
- point.addExtension(extension);
- }
+ private void installExtensions(List pRegisteredPlugins)
+ throws PluginRuntimeException {
+
+ for (int i = 0; i < pRegisteredPlugins.size(); i++) {
+ PluginDescriptor descriptor = (PluginDescriptor) pRegisteredPlugins.get(i);
+ Extension[] extensions = descriptor.getExtensions();
+ for (int j = 0; j < extensions.length; j++) {
+ Extension extension = extensions[j];
+ String xpId = extension.getTargetPoint();
+ ExtensionPoint point = getExtensionPoint(xpId);
+ if (point == null) {
+ throw new PluginRuntimeException(
+ "Plugin (" + descriptor.getPluginId() + "), " +
+ "extension point: " + xpId + " does not exist.");
+ }
+ point.addExtension(extension);
}
+ }
}
+ private void getPluginCheckedDependencies(PluginDescriptor plugin,
+ Map plugins, Map dependencies)
+ throws MissingDependencyException,
+ CircularDependencyException {
+
+ if (dependencies == null) { dependencies = new HashMap(); }
+
+ String[] ids = plugin.getDependencies();
+ for (int i=0; i<ids.length; i++) {
+ String id = ids[i];
+ PluginDescriptor dependency = (PluginDescriptor) plugins.get(id);
+ if (dependency == null) {
+ throw new MissingDependencyException(
+ "Missing dependency " + id +
+ " for plugin " + plugin.getPluginId());
+ }
+ if (dependencies.containsKey(id)) {
+ throw new CircularDependencyException(
+ "Circular dependency detected " + id +
+ " for plugin " + plugin.getPluginId());
+ }
+ dependencies.put(id, dependency);
+ getPluginCheckedDependencies((PluginDescriptor) plugins.get(id),
+ plugins, dependencies);
+ }
+ }
+
+ private Map getPluginCheckedDependencies(PluginDescriptor plugin,
+ Map plugins)
+ throws MissingDependencyException,
+ CircularDependencyException {
+ Map dependencies = new HashMap();
+ getPluginCheckedDependencies(plugin, plugins, dependencies);
+ return dependencies;
+ }
+
/**
- * @param pLoadedPlugins
- * @return ArrayList
- */
- private ArrayList getDependencyCheckedPlugins(ArrayList pLoadedPlugins) {
- ArrayList availablePlugins = new ArrayList();
- for (int i = 0; i < pLoadedPlugins.size(); i++) {
- PluginDescriptor descriptor = (PluginDescriptor) pLoadedPlugins
- .get(i);
- String[] dependencyIDs = descriptor.getDependencies();
- boolean available = true;
- for (int j = 0; j < dependencyIDs.length; j++) {
- String id = dependencyIDs[j];
- if (!dependencyIsAvailable(id, pLoadedPlugins)) {
- available = false;
- //LOG.fine("Skipping " + descriptor.getName());
- break;
- }
- }
- if (available) {
- //LOG.fine("Adding " + descriptor.getName());
- availablePlugins.add(descriptor);
- ExtensionPoint[] points = descriptor.getExtenstionPoints();
- for (int j = 0; j < points.length; j++) {
- ExtensionPoint point = points[j];
- String xpId = point.getId();
- //LOG.fine("Adding extension point " + xpId);
- fExtensionPoints.put(xpId, point);
- }
- }
+ * @param filtered is the list of plugin filtred
+ * @param all is the list of all plugins found.
+ * @return List
+ */
+ private List getDependencyCheckedPlugins(Map filtered, Map all) {
+ if (filtered == null) { return null; }
+ Map checked = new HashMap();
+ Iterator iter = filtered.values().iterator();
+ while (iter.hasNext()) {
+ PluginDescriptor plugin = (PluginDescriptor) iter.next();
+ try {
+ checked.putAll(getPluginCheckedDependencies(plugin, all));
+ checked.put(plugin.getPluginId(), plugin);
+ } catch (MissingDependencyException mde) {
+ // Simply ignore this plugin
+ LOG.warning(mde.getMessage());
+ } catch (CircularDependencyException cde) {
+ // Simply ignore this plugin
+ LOG.warning(cde.getMessage());
}
- return availablePlugins;
+ }
+ return new ArrayList(checked.values());
}
/**
@@ -121,7 +181,7 @@
* @param pLoadedPlugins
* @return boolean
*/
- private boolean dependencyIsAvailable(String id, ArrayList pLoadedPlugins) {
+ private boolean dependencyIsAvailable(String id, List pLoadedPlugins) {
if (pLoadedPlugins != null && id != null) {
for (int i = 0; i < pLoadedPlugins.size(); i++) {
PluginDescriptor descriptor = (PluginDescriptor) pLoadedPlugins
@@ -251,5 +311,31 @@
Plugin object = (Plugin) fActivatedPlugins.get(pluginId);
object.shutDown();
}
+ }
+
+ private void displayStatus() {
+
+ LOG.info("Plugin Auto-activation mode: [" + AUTO + "]");
+
+ LOG.info("Registered Plugins:");
+ if ((fRegisteredPlugins == null) || (fRegisteredPlugins.size() == 0)) {
+ LOG.info("\tNONE");
+ } else {
+ for (int i=0; i<fRegisteredPlugins.size(); i++) {
+ PluginDescriptor plugin = (PluginDescriptor) fRegisteredPlugins.get(i);
+ LOG.info("\t" + plugin.getName() + " (" + plugin.getPluginId() + ")");
+ }
+ }
+
+ LOG.info("Registered Extension-Points:");
+ if ((fExtensionPoints == null) || (fExtensionPoints.size() == 0)) {
+ LOG.info("\tNONE");
+ } else {
+ Iterator iter = fExtensionPoints.values().iterator();
+ while (iter.hasNext()) {
+ ExtensionPoint ep = (ExtensionPoint) iter.next();
+ LOG.info("\t" + ep.getName() + " (" + ep.getId() + ")");
+ }
+ }
}
}