source: josm/trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java@ 1623

Last change on this file since 1623 was 1623, checked in by stoecker, 15 years ago

closed #2596 - wrong texts in plugin information

  • Property svn:eol-style set to native
File size: 8.4 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.plugins;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.File;
7import java.io.FileInputStream;
8import java.io.IOException;
9import java.io.InputStream;
10import java.net.URL;
11import java.net.MalformedURLException;
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.LinkedList;
15import java.util.List;
16import java.util.Map;
17import java.util.TreeMap;
18import java.util.jar.Attributes;
19import java.util.jar.JarInputStream;
20import java.util.jar.Manifest;
21
22import org.openstreetmap.josm.Main;
23
24/**
25 * Encapsulate general information about a plugin. This information is available
26 * without the need of loading any class from the plugin jar file.
27 *
28 * @author imi
29 */
30public class PluginInformation {
31 public File file = null;
32 public String name = null;
33 public String mainversion = null;
34 public String className = null;
35 public String requires = null;
36 public String link = null;
37 public String description = null;
38 public boolean early = false;
39 public String author = null;
40 public int stage = 50;
41 public String version = null;
42 public String downloadlink = null;
43 public List<URL> libraries = new LinkedList<URL>();
44
45 public final Map<String, String> attr = new TreeMap<String, String>();
46
47 /**
48 * Used in the Plugin constructor to make the information of the plugin
49 * that is currently initializing available.
50 *
51 * If you think this is hacky, you are probably right. But it is
52 * convinient anyway ;-)
53 */
54 static PluginInformation currentPluginInitialization = null;
55
56 /**
57 * @param file the plugin jar file.
58 */
59 public PluginInformation(File file) {
60 this(file, file.getName().substring(0, file.getName().length()-4));
61 }
62
63 public PluginInformation(File file, String name) {
64 this.name = name;
65 this.file = file;
66 try {
67 JarInputStream jar = new JarInputStream(new FileInputStream(file));
68 Manifest manifest = jar.getManifest();
69 if (manifest == null)
70 throw new IOException(file+" contains no manifest.");
71 scanManifest(manifest);
72 libraries.add(0, fileToURL(file));
73 jar.close();
74 } catch (IOException e) {
75 throw new PluginException(null, name, e);
76 }
77 }
78
79 public PluginInformation(InputStream manifestStream, String name) {
80 this.name = name;
81 try {
82 Manifest manifest = new Manifest();
83 manifest.read(manifestStream);
84 scanManifest(manifest);
85 } catch (IOException e) {
86 throw new PluginException(null, name, e);
87 }
88 }
89
90 private void scanManifest(Manifest manifest)
91 {
92 String lang = Main.getLanguageCode()+"_";
93 Attributes attr = manifest.getMainAttributes();
94 className = attr.getValue("Plugin-Class");
95 String s = attr.getValue(lang+"Plugin-Link");
96 if(s == null)
97 s = attr.getValue("Plugin-Link");
98 link = s;
99 requires = attr.getValue("Plugin-Requires");
100 s = attr.getValue(lang+"Plugin-Description");
101 if(s == null)
102 {
103 s = attr.getValue("Plugin-Description");
104 if(s != null)
105 s = tr(s);
106 }
107 description = s;
108 early = Boolean.parseBoolean(attr.getValue("Plugin-Early"));
109 String stageStr = attr.getValue("Plugin-Stage");
110 stage = stageStr == null ? 50 : Integer.parseInt(stageStr);
111 version = attr.getValue("Plugin-Version");
112 mainversion = attr.getValue("Plugin-Mainversion");
113 author = attr.getValue("Author");
114
115 String classPath = attr.getValue(Attributes.Name.CLASS_PATH);
116 if (classPath != null) {
117 for (String entry : classPath.split(" ")) {
118 File entryFile;
119 if (new File(entry).isAbsolute())
120 entryFile = new File(entry);
121 else
122 entryFile = new File(file.getParent(), entry);
123
124 libraries.add(fileToURL(entryFile));
125 }
126 }
127 for (Object o : attr.keySet())
128 this.attr.put(o.toString(), attr.getValue(o.toString()));
129 }
130
131 public String getLinkDescription()
132 {
133 String d = description == null ? tr("no description available") : description;
134 if(link != null)
135 d += " <A HREF=\""+link+"\">"+tr("More details")+"</A>";
136 return d;
137 }
138
139 /**
140 * Load and instantiate the plugin
141 */
142 public PluginProxy load(Class<?> klass) {
143 try {
144 currentPluginInitialization = this;
145 return new PluginProxy(klass.newInstance(), this);
146 } catch (Exception e) {
147 throw new PluginException(null, name, e);
148 }
149 }
150
151 /**
152 * Load the class of the plugin
153 */
154 public Class<?> loadClass(ClassLoader classLoader) {
155 if (className == null)
156 return null;
157 try {
158 Class<?> realClass = Class.forName(className, true, classLoader);
159 return realClass;
160 } catch (Exception e) {
161 throw new PluginException(null, name, e);
162 }
163 }
164
165 public static URL fileToURL(File f) {
166 try {
167 return f.toURI().toURL();
168 } catch (MalformedURLException ex) {
169 return null;
170 }
171 }
172
173 /**
174 * Try to find a plugin after some criterias. Extract the plugin-information
175 * from the plugin and return it. The plugin is searched in the following way:
176 *
177 *<li>first look after an MANIFEST.MF in the package org.openstreetmap.josm.plugins.<plugin name>
178 * (After removing all fancy characters from the plugin name).
179 * If found, the plugin is loaded using the bootstrap classloader.
180 *<li>If not found, look for a jar file in the user specific plugin directory
181 * (~/.josm/plugins/<plugin name>.jar)
182 *<li>If not found and the environment variable JOSM_RESSOURCES + "/plugins/" exist, look there.
183 *<li>Try for the java property josm.ressources + "/plugins/" (set via java -Djosm.plugins.path=...)
184 *<li>If the environment variable ALLUSERSPROFILE and APPDATA exist, look in
185 * ALLUSERSPROFILE/<the last stuff from APPDATA>/JOSM/plugins.
186 * (*sic* There is no easy way under Windows to get the All User's application
187 * directory)
188 *<li>Finally, look in some typical unix paths:<ul>
189 * <li>/usr/local/share/josm/plugins/
190 * <li>/usr/local/lib/josm/plugins/
191 * <li>/usr/share/josm/plugins/
192 * <li>/usr/lib/josm/plugins/
193 *
194 * If a plugin class or jar file is found earlier in the list but seem not to
195 * be working, an PluginException is thrown rather than continuing the search.
196 * This is so JOSM can detect broken user-provided plugins and do not go silently
197 * ignore them.
198 *
199 * The plugin is not initialized. If the plugin is a .jar file, it is not loaded
200 * (only the manifest is extracted). In the classloader-case, the class is
201 * bootstraped (e.g. static {} - declarations will run. However, nothing else is done.
202 *
203 * @param pluginName The name of the plugin (in all lowercase). E.g. "lang-de"
204 * @return Information about the plugin or <code>null</code>, if the plugin
205 * was nowhere to be found.
206 * @throws PluginException In case of broken plugins.
207 */
208 public static PluginInformation findPlugin(String pluginName) throws PluginException {
209 String name = pluginName;
210 name = name.replaceAll("[-. ]", "");
211 InputStream manifestStream = PluginInformation.class.getResourceAsStream("/org/openstreetmap/josm/plugins/"+name+"/MANIFEST.MF");
212 if (manifestStream != null)
213 return new PluginInformation(manifestStream, pluginName);
214
215 Collection<String> locations = getPluginLocations();
216
217 for (String s : locations) {
218 File pluginFile = new File(s, pluginName + ".jar");
219 if (pluginFile.exists()) {
220 PluginInformation info = new PluginInformation(pluginFile);
221 return info;
222 }
223 }
224 return null;
225 }
226
227 public static Collection<String> getPluginLocations() {
228 Collection<String> locations = Main.pref.getAllPossiblePreferenceDirs();
229 Collection<String> all = new ArrayList<String>(locations.size());
230 for (String s : locations)
231 all.add(s+"plugins");
232 return all;
233 }
234}
235
Note: See TracBrowser for help on using the repository browser.