File Source: pluginlocator.java

         /* 
    P/P   *  Method: int compare(Object, Object)
          * 
          *  Preconditions:
          *    Param_1 != null
          *    Param_2 != null
          *    Param_2.weight - Param_1.weight in -232+1..231
          * 
          *  Postconditions:
          *    return_value == -(Param_2.weight - Param_1.weight)
          *    init'ed(return_value)
          */
     1  /*
     2   * Copyright (c) 2003-2005, Simon Brown
     3   * All rights reserved.
     4   *
     5   * Redistribution and use in source and binary forms, with or without
     6   * modification, are permitted provided that the following conditions are met:
     7   *
     8   *   - Redistributions of source code must retain the above copyright
     9   *     notice, this list of conditions and the following disclaimer.
    10   *
    11   *   - Redistributions in binary form must reproduce the above copyright
    12   *     notice, this list of conditions and the following disclaimer in
    13   *     the documentation and/or other materials provided with the
    14   *     distribution.
    15   *
    16   *   - Neither the name of Pebble nor the names of its contributors may
    17   *     be used to endorse or promote products derived from this software
    18   *     without specific prior written permission.
    19   *
    20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    30   * POSSIBILITY OF SUCH DAMAGE.
    31   */
    32  package net.sourceforge.pebble.plugins;
    33  
    34  import net.sourceforge.pebble.domain.Blog;
    35  import org.apache.commons.logging.Log;
    36  import org.apache.commons.logging.LogFactory;
         /* 
    P/P   *  Method: void net.sourceforge.pebble.plugins.PluginLocator()
          */
    37  import org.jdom.Document;
    38  import org.jdom.Element;
    39  import org.jdom.JDOMException;
    40  import org.jdom.input.SAXBuilder;
    41  
    42  import java.io.IOException;
    43  import java.net.URL;
    44  import java.util.*;
    45  
    46  /**
    47   * Locates plugins
    48   *
    49   * @author James Roper
    50   */
    51  public class PluginLocator {
    52    private static final Log log = LogFactory.getLog(PluginLocator.class);
    53    private static final Map<String, PluginConfigType> PLUGIN_CONFIG_TYPES;
    54    static {
    55      PLUGIN_CONFIG_TYPES = new HashMap<String, PluginConfigType>();
    56      PLUGIN_CONFIG_TYPES.put("string", PlainTextPluginConfigType.INSTANCE);
    57      PLUGIN_CONFIG_TYPES.put("textarea", TextAreaPluginConfigType.INSTANCE);
    58      PLUGIN_CONFIG_TYPES.put("checkbox", CheckboxPluginConfigType.INSTANCE);
    59      PLUGIN_CONFIG_TYPES.put("password", PasswordPluginConfigType.INSTANCE);
    60    }
    61  
    62    private static AvailablePlugins availablePlugins;
    63  
    64    /**
    65     * Locates all the plugins installed in Pebble
    66     *
    67     * @return A map of plugin types to lists of plugin class names
    68     */
           /* 
    P/P     *  Method: AvailablePlugins locateAvailablePlugins()
            * 
            *  Preconditions:
            *    init'ed(availablePlugins)
            * 
            *  Presumptions:
            *    java.lang.Class:getClassLoader(...)@73 != null
            *    java.lang.ClassLoader:getResources(...)@73 != null
            *    java.util.Enumeration:nextElement(...)@75 != null
            *    java.util.Map:values(...)@82 != null
            *    org.apache.commons.logging.LogFactory:getLog(...)@52 != null
            * 
            *  Postconditions:
            *    availablePlugins == One-of{old availablePlugins, &new AvailablePlugins(locateAvailablePlugins#3)}
            *    availablePlugins != null
            *    return_value == availablePlugins
            *    new AvailablePlugins(locateAvailablePlugins#3) num objects <= 1
            *    new AvailablePlugins(locateAvailablePlugins#3).plugins == &new HashMap(locateAvailablePlugins#1)
            *    new HashMap(locateAvailablePlugins#1) num objects <= 1
            * 
            *  Test Vectors:
            *    availablePlugins: Inverse{null}, Addr_Set{null}
            *    java.util.Iterator:hasNext(...)@82: {1}, {0}
            */
    69    public static synchronized AvailablePlugins locateAvailablePlugins() {
    70      if (availablePlugins == null) {
    71        Map<String, List<Plugin>> plugins = new HashMap<String, List<Plugin>>();
    72        try {
    73          Enumeration<URL> resources = PluginLocator.class.getClassLoader().getResources("pebble-plugins.xml");
    74          while (resources.hasMoreElements()) {
    75            installPlugins(plugins, resources.nextElement());
    76          }
    77        }
    78        catch (IOException ioe) {
    79          log.error("Error occured while scanning context classloader for plugins", ioe);
    80        }
    81        // Sort the plugins
    82        for (List<Plugin> pluginsList : plugins.values())
    83        {
                 /* 
    P/P           *  Method: void net.sourceforge.pebble.plugins.PluginLocator$1()
                  */
    84          Collections.sort(pluginsList, new Comparator<Plugin>() {
    85            public int compare(Plugin o1, Plugin o2) {
                     /* 
    P/P               *  Method: int compare(Plugin, Plugin)
                      * 
                      *  Preconditions:
                      *    o1 != null
                      *    o2 != null
                      *    o2.weight - o1.weight in -232+1..231
                      * 
                      *  Postconditions:
                      *    return_value == -(o2.weight - o1.weight)
                      *    init'ed(return_value)
                      */
    86              return o1.getWeight() - o2.getWeight();
    87            }
    88          });
    89        }
    90        availablePlugins = new AvailablePlugins(plugins);
    91      }
    92      return availablePlugins;
    93    }
    94  
           /* 
    P/P     *  Method: AvailablePlugins getAvailablePluginsSortedForBlog(Blog)
            * 
            *  Preconditions:
            *    blog != null
            *    init'ed(availablePlugins)
            * 
            *  Presumptions:
            *    locateAvailablePlugins(...).plugins != null
            * 
            *  Postconditions:
            *    availablePlugins == One-of{old availablePlugins, &new AvailablePlugins(locateAvailablePlugins#3)}
            *    availablePlugins != null
            *    return_value == &new AvailablePlugins(getAvailablePluginsSortedForBlog#1)
            *    new AvailablePlugins(getAvailablePluginsSortedForBlog#1) num objects == 1
            *    new HashMap(copyMap#1) num objects == 1
            *    return_value.plugins == &new HashMap(copyMap#1)
            *    new AvailablePlugins(locateAvailablePlugins#3) num objects <= 1
            *    new HashMap(locateAvailablePlugins#1) num objects == new AvailablePlugins(locateAvailablePlugins#3) num objects
            *    new AvailablePlugins(locateAvailablePlugins#3).plugins == &new HashMap(locateAvailablePlugins#1)
            */
    95    public static AvailablePlugins getAvailablePluginsSortedForBlog(Blog blog) {
    96      Map<String, List<Plugin>> plugins = locateAvailablePlugins().copyMap();
    97      // Sort the decorators
    98      plugins.put(AvailablePlugins.CONTENT_DECORATOR, sortPlugins(plugins.get(AvailablePlugins.CONTENT_DECORATOR),
    99              blog.getContentDecorators()));
   100      return new AvailablePlugins(plugins);
   101    }
   102  
           /* 
    P/P     *  Method: List sortPlugins(List, List)
            * 
            *  Postconditions:
            *    return_value == One-of{null, plugins}
            *    init'ed(return_value)
            * 
            *  Test Vectors:
            *    plugins: Inverse{null}, Addr_Set{null}
            */
   103    private static List<Plugin> sortPlugins(List<Plugin> plugins, final List<String> installedPlugins) {
   104      if (plugins == null)
   105      {
   106        return null;
   107      }
   108      Collections.sort(plugins, new Comparator<Plugin>() {
   109        public int compare(Plugin plugin1, Plugin plugin2) {
   110          // This comparator ensures installed plugins are at the top, in the order specified by the user,
   111          // and that not installed plugins are sorted by their weight.
                 /* 
    P/P           *  Method: int compare(Plugin, Plugin)
                  * 
                  *  Preconditions:
                  *    plugin1 != null
                  *    plugin2 != null
                  *    this.val$installedPlugins != null
                  *    (soft) plugin2.weight - plugin1.weight in -232+1..231
                  * 
                  *  Presumptions:
                  *    java.util.List:indexOf(...)@113 - java.util.List:indexOf(...)@112 in {-6_442_450_943..231, 232..6_442_450_943}
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    java.util.List:indexOf(...)@112: {-231..-1}, {0..232-1}
                  *    java.util.List:indexOf(...)@113: {-231..-1}, {0..232-1}
                  *    java.util.List:indexOf(...)@113 - java.util.List:indexOf(...)@112: {1..231-1}, {-6_442_450_943..-1}
                  */
   112          int index1 = installedPlugins.indexOf(plugin1.getPluginClass());
   113          int index2 = installedPlugins.indexOf(plugin2.getPluginClass());
   114          if (index1 >= 0 && index2 >= 0)
   115          {
   116            return index1 - index2;
   117          }
   118          if (index1 < 0 && index2 < 0)
   119          {
   120            return plugin1.getWeight() - plugin2.getWeight();
   121          }
   122          if (index1 >= 0)
   123          {
   124            return -1;
   125          }
   126          return 1;
   127        }
   128      });
   129      return plugins;
   130    }
   131  
   132    /**
   133     * Install the plugins from the given resource
   134     * @param plugins The plugins to install
   135     * @param resource The resource to install them from
   136     */
   137    static void installPlugins(Map<String, List<Plugin>> plugins, URL resource) {
             /* 
    P/P       *  Method: void installPlugins(Map, URL)
              * 
              *  Preconditions:
              *    (soft) plugins != null
              *    (soft) resource != null
              * 
              *  Presumptions:
              *    java.lang.Iterable:iterator(...)@142 != null
              *    java.lang.Thread:currentThread(...)@165 != null
              *    java.lang.Thread:getContextClassLoader(...)@165 != null
              *    java.util.Iterator:next(...)@142 != null
              *    org.apache.commons.logging.LogFactory:getLog(...)@52 != null
              *    ...
              * 
              *  Test Vectors:
              *    java.util.Map:get(...)@168: Inverse{null}, Addr_Set{null}
              *    org.jdom.Element:getAttributeValue(...)@153: Addr_Set{null}, Inverse{null}
              *    org.jdom.Element:getChild(...)@146: Addr_Set{null}, Inverse{null}
              */
   138      SAXBuilder saxBuilder = new SAXBuilder();
   139      try {
   140        Document document = saxBuilder.build(resource.openStream());
   141        Element root = document.getRootElement();
   142        for (Element element : (Iterable<Element>) root.getChildren())
   143        {
   144          String type = element.getName();
   145          String name = element.getAttributeValue("name");
   146          Element descriptionElement = element.getChild("description");
   147          String description = null;
   148          if (descriptionElement != null)
   149          {
   150            description = descriptionElement.getText();
   151          }
   152          String className = element.getAttributeValue("class");
   153          String weightStr = element.getAttributeValue("weight");
   154          int weight = 100;
   155          if (weightStr != null)
   156          {
   157            try {
   158              weight = Integer.parseInt(weightStr);
   159            } catch (NumberFormatException e) {
   160              log.error("Invalid weight for plugin " + name + ": " + weightStr);
   161            }
   162          }
   163          // Try and load the class - for validation
   164          try {
   165            Thread.currentThread().getContextClassLoader().loadClass(className);
   166            // Successful, add it
   167            log.debug("Installing plugin '" + name + "' of type " + type + " with class " + className);
   168            List<Plugin> list = plugins.get(type);
   169            if (list == null)
   170            {
   171              list = new ArrayList<Plugin>();
   172              plugins.put(type, list);
   173            }
   174            Collection<PluginConfig> pluginConfig = parsePluginConfig(element);
   175            list.add(new Plugin(name, description, className, weight, pluginConfig));
   176          } catch (ClassNotFoundException e) {
   177            log.error("Plugin class " + className + " of type " + type + " from descriptor " + resource +
   178                    " could not be found.");
   179          }
   180        }
   181      } catch (JDOMException e) {
   182        log.error("Error parsing plugin descriptor at " + resource, e);
   183      } catch (IOException e) {
   184        log.error("Error reading plugin descriptor at " + resource, e);
   185      }
   186    }
   187  
   188    private static Collection<PluginConfig> parsePluginConfig(Element element)
   189    {
             /* 
    P/P       *  Method: Collection parsePluginConfig(Element)
              * 
              *  Preconditions:
              *    element != null
              * 
              *  Presumptions:
              *    java.lang.Iterable:iterator(...)@191 != null
              *    java.lang.Iterable:iterator(...)@208 != null
              *    java.util.Iterator:next(...)@191 != null
              *    java.util.Iterator:next(...)@208 != null
              *    org.jdom.Element:getChildren(...)@191 != null
              *    ...
              * 
              *  Postconditions:
              *    return_value == &new ArrayList(parsePluginConfig#1)
              *    new ArrayList(parsePluginConfig#1) num objects == 1
              * 
              *  Test Vectors:
              *    java.util.Iterator:hasNext(...)@191: {1}, {0}
              *    java.util.Iterator:hasNext(...)@208: {1}, {0}
              *    org.jdom.Element:getAttributeValue(...)@196: Inverse{null}, Addr_Set{null}
              */
   190      Collection<PluginConfig> results = new ArrayList<PluginConfig>();
   191      for (Element configElement : (Iterable<Element>) element.getChildren("config"))
   192      {
   193        String key = configElement.getAttributeValue("key");
   194        String name = configElement.getAttributeValue("name");
   195        boolean required = Boolean.parseBoolean(configElement.getAttributeValue("required"));
   196        String type = configElement.getAttributeValue("type");
   197        PluginConfigType pluginConfigType;
   198        if (type == null)
   199        {
   200          pluginConfigType = PlainTextPluginConfigType.INSTANCE;
   201        }
   202        else
   203        {
   204          pluginConfigType = PLUGIN_CONFIG_TYPES.get(type);
   205        }
   206        // todo custom class instantiation
   207        Properties properties = new Properties();
   208        for (Element property : (Iterable<Element>) configElement.getChildren())
   209        {
   210          properties.setProperty(property.getName(), property.getText());
   211        }
   212        results.add(new PluginConfig(key, name, pluginConfigType, required, properties));
   213      }
   214      return results;
   215    }
   216  }








SofCheck Inspector Build Version : 2.22510
pluginlocator.java 2010-Jun-25 19:40:32
pluginlocator.class 2010-Jul-19 20:23:38
pluginlocator$1.class 2010-Jul-19 20:23:38
pluginlocator$2.class 2010-Jul-19 20:23:38