|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
PluginManager.java | 61.5% | 65.6% | 66.7% | 64.6% |
|
1 |
/*
|
|
2 |
* SimplyHTML, a word processor based on Java, HTML and CSS
|
|
3 |
* Copyright (C) 2002 Ulrich Hilger
|
|
4 |
*
|
|
5 |
* This program is free software; you can redistribute it and/or
|
|
6 |
* modify it under the terms of the GNU General Public License
|
|
7 |
* as published by the Free Software Foundation; either version 2
|
|
8 |
* of the License, or (at your option) any later version.
|
|
9 |
*
|
|
10 |
* This program is distributed in the hope that it will be useful,
|
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
* GNU General Public License for more details.
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License
|
|
16 |
* along with this program; if not, write to the Free Software
|
|
17 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
18 |
*/
|
|
19 |
|
|
20 |
import java.awt.Frame;
|
|
21 |
//import com.lightdev.app.shtm.Util;
|
|
22 |
import java.util.Vector;
|
|
23 |
import java.net.URLClassLoader;
|
|
24 |
import java.net.URL;
|
|
25 |
import java.util.Enumeration;
|
|
26 |
import java.util.jar.JarFile;
|
|
27 |
import java.util.jar.JarEntry;
|
|
28 |
import java.io.File;
|
|
29 |
import java.net.URI;
|
|
30 |
import java.util.Hashtable;
|
|
31 |
//import com.lightdev.app.shtm.FrmMain;
|
|
32 |
//import javax.help.*;
|
|
33 |
//import javax.help.event.*;
|
|
34 |
|
|
35 |
/**
|
|
36 |
* Finds and loads plug-ins of application SimplyHTML.
|
|
37 |
*
|
|
38 |
* @author Ulrich Hilger
|
|
39 |
* @author Light Development
|
|
40 |
* @author <a href="http://www.lightdev.com">http://www.lightdev.com</a>
|
|
41 |
* @author <a href="mailto:info@lightdev.com">info@lightdev.com</a>
|
|
42 |
* @author published under the terms and conditions of the
|
|
43 |
* GNU General Public License,
|
|
44 |
* for details see file gpl.txt in the distribution
|
|
45 |
* package of this software
|
|
46 |
*
|
|
47 |
* @version stage 11, April 27, 2003
|
|
48 |
*/
|
|
49 |
|
|
50 |
public class PluginManager { |
|
51 |
|
|
52 |
/** name of sub-package where plug-ins are stored */
|
|
53 |
private String PLUGIN_PACKAGE = "installed"; |
|
54 |
|
|
55 |
/** the class loader pointing to all plug-in locations (JARs) */
|
|
56 |
private URLClassLoader loader;
|
|
57 |
|
|
58 |
/** the class names of all loaded plug-ins */
|
|
59 |
private Vector pluginClassNames = new Vector(); |
|
60 |
|
|
61 |
/** the plug-in objects loaded by this <code>PluginManager</code> */
|
|
62 |
private Hashtable loadedPlugins = new Hashtable(); |
|
63 |
|
|
64 |
private Hashtable nameMap = new Hashtable(); |
|
65 |
|
|
66 |
/** the URLs pointing to the classes in pluginClassNames */
|
|
67 |
private Vector urls = new Vector(); |
|
68 |
|
|
69 |
private FrmMain owner;
|
|
70 |
|
|
71 |
/**
|
|
72 |
* construct a new <code>PluginManager</code> and load
|
|
73 |
* all available plug-ins.
|
|
74 |
*/
|
|
75 | 75 |
public PluginManager(Frame owner) {
|
76 | 75 |
this.owner = (FrmMain) owner;
|
77 |
} |
|
78 |
|
|
79 |
/**
|
|
80 |
* get all plug-ins loaded by this <code>PluginManager</code>
|
|
81 |
*/
|
|
82 | 75 |
public Enumeration plugins() {
|
83 | 75 |
return loadedPlugins.elements();
|
84 |
} |
|
85 |
|
|
86 | 0 |
public ClassLoader getPluginLoader() {
|
87 | 0 |
return loader;
|
88 |
} |
|
89 |
|
|
90 |
/**
|
|
91 |
* get a loaded plug-in by its GUI name.
|
|
92 |
*
|
|
93 |
* @param guiName the GUI name of this plaug-in
|
|
94 |
*
|
|
95 |
* @return the plug-in having the given GUI name, or null of no plug-in
|
|
96 |
* with that name is present
|
|
97 |
*/
|
|
98 | 0 |
public SHTMLPlugin pluginForName(String guiName) {
|
99 | 0 |
String intName = (String) nameMap.get(guiName); |
100 | 0 |
return (SHTMLPlugin) loadedPlugins.get(intName);
|
101 |
} |
|
102 |
|
|
103 | 0 |
public Object[] getPluginNames() {
|
104 | 0 |
return nameMap.keySet().toArray();
|
105 |
} |
|
106 |
|
|
107 |
/**
|
|
108 |
* load all plug-ins found in the plug-in path
|
|
109 |
*/
|
|
110 | 75 |
public void loadPlugins() { |
111 | 75 |
loadedPlugins.clear(); |
112 |
//String pluginPrefix = this.getClass().getPackage().getName() +
|
|
113 |
// Util.CLASS_SEPARATOR + PLUGIN_PACKAGE + Util.CLASS_SEPARATOR;
|
|
114 | 75 |
String pluginPrefix = this.getClass().getName() +
|
115 |
Util.CLASS_SEPARATOR + /*PLUGIN_PACKAGE +*/ Util.CLASS_SEPARATOR;
|
|
116 |
//System.out.println("pluginPrefix = "+ pluginPrefix);
|
|
117 | 75 |
findPlugins(pluginPrefix.replace(Util.CLASS_SEPARATOR_CHAR, |
118 |
Util.URL_SEPARATOR_CHAR)); |
|
119 | 75 |
Enumeration cNames = pluginClassNames.elements(); |
120 | 75 |
Class cl; |
121 | 75 |
Object o; |
122 | 75 |
SHTMLPlugin p; |
123 | 75 |
String intName; |
124 | 75 |
while(cNames.hasMoreElements()) {
|
125 | 0 |
try {
|
126 | 0 |
String nextClass = (String) cNames.nextElement(); |
127 |
//System.out.println("PluginManager loadPlugins loading " + pluginPrefix + nextClass /* pluginPrefix + (String) cNames.nextElement()*/);
|
|
128 | 0 |
cl = loader.loadClass(/*pluginPrefix +*/
|
129 |
/*(String) cNames.nextElement()*/ pluginPrefix + nextClass);
|
|
130 |
//System.out.println("PluginManager loadPlugins calling newInstance ");
|
|
131 | 0 |
o = cl.newInstance(); |
132 | 0 |
if(o instanceof SHTMLPlugin) { |
133 | 0 |
p = (SHTMLPlugin) o; |
134 | 0 |
p.initPlugin(owner, null, null, null); |
135 |
//p.setOwner(owner);
|
|
136 |
//p.initPluginActions();
|
|
137 | 0 |
intName = p.getInternalName(); |
138 | 0 |
loadedPlugins.put(intName, o); |
139 | 0 |
nameMap.put(p.getGUIName(), intName); |
140 |
} |
|
141 |
} |
|
142 |
catch(Exception e) {
|
|
143 | 0 |
Util.errMsg(null, this.getClass().getName() + ".loadPlugins: " + |
144 |
e.getMessage(), e); |
|
145 |
} |
|
146 |
} |
|
147 |
} |
|
148 |
|
|
149 |
/**
|
|
150 |
* get a class loader for a given set of URLs
|
|
151 |
* specifying one or more class paths
|
|
152 |
*
|
|
153 |
* @param urls set of URLs specifying the class path(s)
|
|
154 |
*
|
|
155 |
* @return the class loader
|
|
156 |
*/
|
|
157 | 75 |
private URLClassLoader createLoader(Vector urls) {
|
158 | 75 |
URL[] urlArray = new URL[urls.size()];
|
159 | 75 |
for(int i = 0; i < urls.size(); i++) { |
160 | 0 |
urlArray[i] = (URL) urls.elementAt(i); |
161 |
//System.out.println("urlArray[" + i + "]=" + urlArray[i]);
|
|
162 |
} |
|
163 | 75 |
return new URLClassLoader(urlArray, this.getClass().getClassLoader()); |
164 |
} |
|
165 |
|
|
166 |
/**
|
|
167 |
* find plug-ins by looking for JARs inside a
|
|
168 |
* given path and create a class loader for them.
|
|
169 |
*
|
|
170 |
* <p>JARs are searched in sub-package .plugin.installed
|
|
171 |
* of the package this class resides in.</p>
|
|
172 |
*
|
|
173 |
* <p>On return of this method fields <code>loader</code> and
|
|
174 |
* <code>pluginClassNames</code> are initialized and
|
|
175 |
* filled accordingly.</p>
|
|
176 |
*
|
|
177 |
* @param pluginPath the path to look for plug-in JAR files, e.g.
|
|
178 |
* com/lightdev/app/shtm/plugin/installed/
|
|
179 |
*/
|
|
180 | 75 |
private void findPlugins(String pluginPath) { |
181 | 75 |
String appPath = Util.getClassFilePath(this.getClass());
|
182 | 75 |
String filePath; |
183 | 75 |
if(appPath.indexOf(":") < 0) { |
184 | 0 |
filePath = "/" + appPath;
|
185 |
} |
|
186 |
else {
|
|
187 | 75 |
filePath = appPath; |
188 |
} |
|
189 |
//System.out.println("PluginManager.findPlugins appPath=" + appPath + ", filePath=" + filePath);
|
|
190 | 75 |
pluginClassNames.clear(); |
191 | 75 |
urls.clear(); |
192 | 75 |
String fName; |
193 | 75 |
try {
|
194 | 75 |
File plugindir = new File(filePath);//new URI(Util.FILE_PREFIX + Util.URL_SEPARATOR + appPath)); |
195 | 75 |
if(plugindir != null) { |
196 | 75 |
File[] content = plugindir.listFiles(); |
197 | 75 |
if(content != null) { |
198 | 75 |
for(int i = 0; i < content.length; i++) { |
199 | 22350 |
if(content[i].isFile()) {
|
200 | 21825 |
fName = content[i].getName(); |
201 |
//System.out.println("PluginManager.findPlugins fName=" + fName);
|
|
202 | 21825 |
if(fName.toLowerCase().endsWith("jhall.jar")) { |
203 |
/*System.out.println("PluginManager.findPlugins adding URL " + Util.FILE_PREFIX +
|
|
204 |
Util.URL_SEPARATOR + appPath + fName);*/
|
|
205 | 0 |
urls.addElement(new URL(Util.FILE_PREFIX +
|
206 |
Util.URL_SEPARATOR + appPath + fName)); |
|
207 |
} |
|
208 | 21825 |
if(fName.toLowerCase().endsWith("simplyhtml.jar")) { |
209 |
/*System.out.println("PluginManager.findPlugins adding URL " + Util.FILE_PREFIX +
|
|
210 |
Util.URL_SEPARATOR + appPath + fName);*/
|
|
211 | 0 |
urls.addElement(new URL(Util.FILE_PREFIX +
|
212 |
Util.URL_SEPARATOR + appPath + fName)); |
|
213 |
} |
|
214 | 21825 |
else if(fName.endsWith(Util.JAR_EXTENSION)) { |
215 | 750 |
readJar(appPath, pluginPath, content[i], fName); |
216 |
} |
|
217 |
} |
|
218 |
} |
|
219 |
} |
|
220 |
} |
|
221 | 75 |
loader = createLoader(urls); |
222 |
} |
|
223 |
catch(Exception e) {
|
|
224 | 0 |
Util.errMsg(null, this.getClass().getName() + ".findPlugins: " + |
225 |
e.getMessage(), e); |
|
226 |
} |
|
227 |
} |
|
228 |
|
|
229 |
/**
|
|
230 |
* read a Java archive (JAR) file and look for classes within
|
|
231 |
* a given package path inside the JAR file. Store class names and
|
|
232 |
* their URLS for later use.
|
|
233 |
*
|
|
234 |
* <p>Some of the parameters required below could be extracted from
|
|
235 |
* others passed to this method but as previous methods already determined
|
|
236 |
* respective paramaters, it is faster to pass the existing values as
|
|
237 |
* parameters than to re-build the values locally.</p>
|
|
238 |
*
|
|
239 |
* @param filePath the absolute path pointing to the JAR file, e.g.
|
|
240 |
* file:/C:/Programs/SimplyHTML/
|
|
241 |
* @param pluginPath the path inside filePath pointing to potential plug-ins
|
|
242 |
* @param jarFile the file object referring to the JAR file to read
|
|
243 |
* @param fileName the name of the JAR file
|
|
244 |
*/
|
|
245 | 750 |
private void readJar(String filePath, String pluginPath, File jarFile, |
246 |
String fileName) |
|
247 |
{ |
|
248 | 750 |
try {
|
249 | 750 |
Enumeration jarEntries = new JarFile(jarFile).entries();
|
250 | 675 |
JarEntry je; |
251 | 675 |
String jeName; |
252 | 675 |
while(jarEntries.hasMoreElements()) {
|
253 | 34050 |
je = (JarEntry) jarEntries.nextElement(); |
254 | 34050 |
jeName = je.getName(); |
255 | 34050 |
if(jeName.startsWith(pluginPath) &&
|
256 |
!je.isDirectory() && |
|
257 |
jeName.endsWith(Util.CLASS_EXT)) |
|
258 |
{ |
|
259 |
/*System.out.println("PluginManager.readJar adding URL " + Util.FILE_PREFIX +
|
|
260 |
Util.URL_SEPARATOR + filePath + fileName);*/
|
|
261 | 0 |
urls.addElement(new URL(Util.FILE_PREFIX +
|
262 |
Util.URL_SEPARATOR + filePath + fileName)); |
|
263 | 0 |
pluginClassNames.addElement(jeName.substring( |
264 |
pluginPath.length(), jeName.indexOf(Util.CLASS_SEPARATOR))); |
|
265 |
} |
|
266 |
} |
|
267 |
} |
|
268 |
catch(Exception e) {
|
|
269 |
/*Util.errMsg(null, this.getClass().getName() + ".readJar: " +
|
|
270 |
e.getMessage(), e);*/
|
|
271 |
} |
|
272 |
} |
|
273 |
} |
|