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 |