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&eacute;r&ocirc;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&eacute;r&ocirc;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() + ")");
+        }
+      }
     }
 }


Reply via email to