View Javadoc

1   /*
2    * Copyright 2004 Sun Microsystems, Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  package com.sun.syndication.io.impl;
18  
19  import java.util.*;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.net.URL;
23  
24  /***
25   * <p>
26   * @author Alejandro Abdelnur
27   *
28   */
29  public abstract class PluginManager {
30      private Map _pluginsMap;
31      private List _pluginsList;
32      private List _keys;
33  
34      /***
35       * Creates a PluginManager
36       * <p>
37       * @param propertyKey property key defining the plugins classes
38       *
39       */
40      protected PluginManager(String propertyKey) {
41          loadPlugins(propertyKey);
42          _pluginsMap = Collections.unmodifiableMap(_pluginsMap);
43          _pluginsList = Collections.unmodifiableList(_pluginsList);
44          _keys = Collections.unmodifiableList(new ArrayList(_pluginsMap.keySet()));
45      }
46  
47      protected abstract String getKey(Object obj);
48  
49  
50      protected List getKeys() {
51          return _keys;
52      }
53  
54      protected List getPlugins() {
55          return _pluginsList;
56      }
57  
58      protected Map getPluginMap() {
59          return _pluginsMap;
60      }
61  
62      protected Object getPlugin(String key) {
63          return _pluginsMap.get(key);
64      }
65  
66      // PRIVATE - LOADER PART
67  
68      private void loadPlugins(String key) {
69          List finalPluginsList = new ArrayList();
70          _pluginsList = new ArrayList();
71          _pluginsMap = new HashMap();
72          try {
73              Class[] classes = getClasses(key);
74              for (int i=0;i<classes.length;i++) {
75                  Object obj  = classes[i].newInstance();
76                  _pluginsMap.put(getKey(obj),obj);
77                  _pluginsList.add(obj); // to preserve the order of definition in the rome.properties files
78              }
79              Iterator i = _pluginsMap.values().iterator();
80              while (i.hasNext()) {
81                  finalPluginsList.add(i.next()); // to remove overriden plugin impls
82              }
83  
84              i = _pluginsList.iterator();
85              while (i.hasNext()) {
86                  Object plugin = i.next();
87                  if (!finalPluginsList.contains(plugin)) {
88                      i.remove();
89                  }
90              }
91          }
92          catch (Exception ex) {
93              throw new RuntimeException("could not instanciate plugin ",ex);
94          }
95      }
96  
97      private static final String MASTER_PLUGIN_FILE = "com/sun/syndication/rome.properties";
98      private static final String EXTRA_PLUGIN_FILE = "rome.properties";
99      private static final Properties[] PLUGINS_DEFS;
100 
101     static {
102         PLUGINS_DEFS = loadAllProperties();
103     }
104 
105     private static Properties[] loadAllProperties() {
106         ClassLoader classLoader = PluginManager.class.getClassLoader();
107         List allProps = new ArrayList();
108 
109         try {
110             // Rome own properties
111             InputStream is = classLoader.getResourceAsStream(MASTER_PLUGIN_FILE);
112             allProps.add(loadProperties(is));
113         }
114         catch (IOException ex) {
115             throw new RuntimeException("could not load Rome plugins file",ex);
116         }
117 
118         // Rome extensions properties, find them all
119         try {
120             Enumeration urls = classLoader.getResources(EXTRA_PLUGIN_FILE);
121             while (urls.hasMoreElements()) {
122                 URL url = (URL) urls.nextElement();
123                 try {
124                     InputStream is = url.openStream();
125                     allProps.add(loadProperties(is));
126                 }
127                 catch (IOException ex) {
128                     throw new RuntimeException("could not load Rome extensions plugins file ["+url.toString()+"] ",ex);
129                 }
130             }
131         }
132         catch (IOException ex) {
133             throw new RuntimeException("could not load fetch resources for Rome extensions plugins");
134         }
135 
136         Properties[] array = new Properties[allProps.size()];
137         allProps.toArray(array);
138         return array;
139     }
140 
141     private static Properties loadProperties(InputStream is) throws IOException {
142         Properties props = new Properties();
143         props.load(is);
144         return props;
145     }
146 
147     private static List parseAndLoadClasses(String classNames) throws ClassNotFoundException {
148         ClassLoader classLoader = PluginManager.class.getClassLoader();
149         List classes = new ArrayList();
150         StringTokenizer st = new StringTokenizer(classNames,", ");
151         while (st.hasMoreTokens()) {
152             String className = st.nextToken();
153             Class mClass = classLoader.loadClass(className);
154             classes.add(mClass);
155         }
156         return classes;
157     }
158 
159     /***
160      * Loads and returns the classes defined in the properties files.
161      * <p>
162      * @param pluginKey property key defining the plugin classes.
163      * @return array containing the classes defined in the properties files.
164      * @throws java.lang.ClassNotFoundException thrown if one of the classes defined in the properties file cannot be loaded
165      *         and hard failure is ON.
166      *
167      */
168     private static Class[] getClasses(String pluginKey) throws ClassNotFoundException {
169         List classes = new ArrayList();
170         for (int i=0;i<PLUGINS_DEFS.length;i++) {
171             String classNames = PLUGINS_DEFS[i].getProperty(pluginKey);
172             if (classNames!=null) {
173                 classes.addAll(parseAndLoadClasses(classNames));
174             }
175         }
176         Class[] array = new Class[classes.size()];
177         classes.toArray(array);
178         return array;
179     }
180 
181 
182 
183 }