Changeset 1169 in josm for trunk/src/org/openstreetmap/josm/plugins
- Timestamp:
- 2008-12-23T15:07:05+01:00 (17 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/plugins
- Files:
-
- 5 edited
-
Plugin.java (modified) (3 diffs)
-
PluginDownloader.java (modified) (2 diffs)
-
PluginException.java (modified) (1 diff)
-
PluginInformation.java (modified) (1 diff)
-
PluginProxy.java (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/plugins/Plugin.java
r873 r1169 24 24 * 25 25 * The actual implementation of this class is optional, as all functions will be called 26 * via reflection. This is to be able to change this interface without the need of 26 * via reflection. This is to be able to change this interface without the need of 27 27 * recompiling or even breaking the plugins. If your class does not provide a 28 28 * function here (or does provide a function with a mismatching signature), it will not … … 32 32 * are provided (you can register yourself to more callbacks in your plugin class 33 33 * constructor). 34 * 34 * 35 35 * Subclassing Plugin and overriding some functions makes it easy for you to keep sync 36 36 * with the correct actual plugin architecture of JOSM. … … 40 40 public abstract class Plugin { 41 41 42 /**43 * This is the info available for this plugin. You can access this from your44 * constructor.45 *46 * (The actual implementation to request the info from a static variable47 * is a bit hacky, but it works).48 */49 public final PluginInformation info = PluginInformation.currentPluginInitialization;42 /** 43 * This is the info available for this plugin. You can access this from your 44 * constructor. 45 * 46 * (The actual implementation to request the info from a static variable 47 * is a bit hacky, but it works). 48 */ 49 public final PluginInformation info = PluginInformation.currentPluginInitialization; 50 50 51 /**52 * @return The directory for the plugin to store all kind of stuff.53 */54 public final String getPluginDir() {55 return new File(Main.pref.getPluginsDirFile(), info.name).getPath();56 }51 /** 52 * @return The directory for the plugin to store all kind of stuff. 53 */ 54 public final String getPluginDir() { 55 return new File(Main.pref.getPluginsDirFile(), info.name).getPath(); 56 } 57 57 58 /**59 * Called after Main.mapFrame is initalized. (After the first data is loaded).60 * You can use this callback to tweak the newFrame to your needs, as example install61 * an alternative Painter.62 */63 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {}58 /** 59 * Called after Main.mapFrame is initalized. (After the first data is loaded). 60 * You can use this callback to tweak the newFrame to your needs, as example install 61 * an alternative Painter. 62 */ 63 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {} 64 64 65 /**66 * Called in the preferences dialog to create a preferences page for the plugin,67 * if any available.68 */69 public PreferenceSetting getPreferenceSetting() { return null; }70 71 /**72 * Called in the download dialog to give the plugin a chance to modify the list73 * of bounding box selectors.74 */75 public void addDownloadSelection(List<DownloadSelection> list) {}76 77 /**78 * Copies the ressource 'from' to the file in the plugin directory named 'to'.79 */80 public void copy(String from, String to) throws FileNotFoundException, IOException {81 String pluginDirName = Main.pref.getPreferencesDir()+"plugins/"+info.name+"/";65 /** 66 * Called in the preferences dialog to create a preferences page for the plugin, 67 * if any available. 68 */ 69 public PreferenceSetting getPreferenceSetting() { return null; } 70 71 /** 72 * Called in the download dialog to give the plugin a chance to modify the list 73 * of bounding box selectors. 74 */ 75 public void addDownloadSelection(List<DownloadSelection> list) {} 76 77 /** 78 * Copies the ressource 'from' to the file in the plugin directory named 'to'. 79 */ 80 public void copy(String from, String to) throws FileNotFoundException, IOException { 81 String pluginDirName = Main.pref.getPreferencesDir()+"plugins/"+info.name+"/"; 82 82 File pluginDir = new File(pluginDirName); 83 83 if (!pluginDir.exists()) 84 pluginDir.mkdirs();84 pluginDir.mkdirs(); 85 85 FileOutputStream out = new FileOutputStream(pluginDirName+to); 86 86 InputStream in = getClass().getResourceAsStream(from); 87 87 byte[] buffer = new byte[8192]; 88 88 for(int len = in.read(buffer); len > 0; len = in.read(buffer)) 89 out.write(buffer, 0, len);89 out.write(buffer, 0, len); 90 90 in.close(); 91 91 out.close(); -
trunk/src/org/openstreetmap/josm/plugins/PluginDownloader.java
r1073 r1169 1 1 //License: GPL. Copyright 2007 by Immanuel Scholz and others 2 2 /** 3 * 3 * 4 4 */ 5 5 package org.openstreetmap.josm.plugins; … … 34 34 public class PluginDownloader { 35 35 36 private static final class UpdateTask extends PleaseWaitRunnable {37 private final Collection<PluginDescription> toUpdate;38 private String errors = "";39 private int count = 0;36 private static final class UpdateTask extends PleaseWaitRunnable { 37 private final Collection<PluginDescription> toUpdate; 38 private String errors = ""; 39 private int count = 0; 40 40 41 private UpdateTask(Collection<PluginDescription> toUpdate) {42 super(tr("Update Plugins"));43 this.toUpdate = toUpdate;44 }41 private UpdateTask(Collection<PluginDescription> toUpdate) { 42 super(tr("Update Plugins")); 43 this.toUpdate = toUpdate; 44 } 45 45 46 @Override protected void cancel() {47 finish();48 }46 @Override protected void cancel() { 47 finish(); 48 } 49 49 50 @Override protected void finish() {51 if (errors.length() > 0)52 JOptionPane.showMessageDialog(Main.parent, tr("There were problems with the following plugins:\n\n {0}",errors));53 else54 JOptionPane.showMessageDialog(Main.parent, trn("{0} Plugin successfully updated. Please restart JOSM.", "{0} Plugins successfully updated. Please restart JOSM.", count, count));55 }50 @Override protected void finish() { 51 if (errors.length() > 0) 52 JOptionPane.showMessageDialog(Main.parent, tr("There were problems with the following plugins:\n\n {0}",errors)); 53 else 54 JOptionPane.showMessageDialog(Main.parent, trn("{0} Plugin successfully updated. Please restart JOSM.", "{0} Plugins successfully updated. Please restart JOSM.", count, count)); 55 } 56 56 57 @Override protected void realRun() throws SAXException, IOException {58 File pluginDir = Main.pref.getPluginsDirFile();59 if (!pluginDir.exists())60 pluginDir.mkdirs();61 for (PluginDescription d : toUpdate) {62 File pluginFile = new File(pluginDir, d.name + ".jar.new");63 if (download(d.resource, pluginFile))64 count++;65 else66 errors += d.name + "\n";67 }68 PluginDownloader.moveUpdatedPlugins();69 }70 }57 @Override protected void realRun() throws SAXException, IOException { 58 File pluginDir = Main.pref.getPluginsDirFile(); 59 if (!pluginDir.exists()) 60 pluginDir.mkdirs(); 61 for (PluginDescription d : toUpdate) { 62 File pluginFile = new File(pluginDir, d.name + ".jar.new"); 63 if (download(d.resource, pluginFile)) 64 count++; 65 else 66 errors += d.name + "\n"; 67 } 68 PluginDownloader.moveUpdatedPlugins(); 69 } 70 } 71 71 72 private static final Pattern wiki = Pattern.compile("^</td></tr><tr><td><a class=\"ext-link\" href=\"([^\"]*)\"><span class=\"icon\">([^<]*)</span></a></td><td>([^<]*)</td><td>([^<].*)</td><td>(.*)");72 private static final Pattern wiki = Pattern.compile("^</td></tr><tr><td><a class=\"ext-link\" href=\"([^\"]*)\"><span class=\"icon\">([^<]*)</span></a></td><td>([^<]*)</td><td>([^<].*)</td><td>(.*)"); 73 73 74 private final static String[] pluginSites = {"http://josm.openstreetmap.de/wiki/Plugins"};74 private final static String[] pluginSites = {"http://josm.openstreetmap.de/wiki/Plugins"}; 75 75 76 public static Collection<String> getSites() {77 return Main.pref.getCollection("pluginmanager.sites", Arrays.asList(pluginSites));78 }76 public static Collection<String> getSites() { 77 return Main.pref.getCollection("pluginmanager.sites", Arrays.asList(pluginSites)); 78 } 79 79 80 public static int downloadDescription() {81 int count = 0;82 for (String site : getSites()) {83 try {84 BufferedReader r = new BufferedReader(new InputStreamReader(new URL(site).openStream()));85 CharSequence txt;86 if (site.toLowerCase().endsWith(".xml"))87 txt = readXml(r);88 else89 txt = readWiki(r);90 r.close();91 new File(Main.pref.getPreferencesDir()+"plugins").mkdir();92 FileWriter out = new FileWriter(new File(Main.pref93 .getPluginsDirFile(), count + "-site-"94 + site.replaceAll("[/:\\\\ <>|]", "_") + ".xml"));95 out.append(txt);96 out.close();97 count++;98 } catch (IOException x) {99 }100 }101 return count;102 }80 public static int downloadDescription() { 81 int count = 0; 82 for (String site : getSites()) { 83 try { 84 BufferedReader r = new BufferedReader(new InputStreamReader(new URL(site).openStream())); 85 CharSequence txt; 86 if (site.toLowerCase().endsWith(".xml")) 87 txt = readXml(r); 88 else 89 txt = readWiki(r); 90 r.close(); 91 new File(Main.pref.getPreferencesDir()+"plugins").mkdir(); 92 FileWriter out = new FileWriter(new File(Main.pref 93 .getPluginsDirFile(), count + "-site-" 94 + site.replaceAll("[/:\\\\ <>|]", "_") + ".xml")); 95 out.append(txt); 96 out.close(); 97 count++; 98 } catch (IOException x) { 99 } 100 } 101 return count; 102 } 103 103 104 private static CharSequence readXml(BufferedReader r) throws IOException {105 StringBuilder b = new StringBuilder();106 for (String line = r.readLine(); line != null; line = r.readLine())107 b.append(line+"\n");108 return b;109 }104 private static CharSequence readXml(BufferedReader r) throws IOException { 105 StringBuilder b = new StringBuilder(); 106 for (String line = r.readLine(); line != null; line = r.readLine()) 107 b.append(line+"\n"); 108 return b; 109 } 110 110 111 private static CharSequence readWiki(BufferedReader r) throws IOException {112 StringBuilder b = new StringBuilder("<plugins>\n");113 for (String line = r.readLine(); line != null; line = r.readLine()) {114 Matcher m = wiki.matcher(line);115 if (!m.matches())116 continue;117 b.append(" <plugin>\n");118 b.append(" <name>"+escape(m.group(2))+"</name>\n");119 b.append(" <resource>"+escape(m.group(1))+"</resource>\n");120 b.append(" <author>"+escape(m.group(3))+"</author>\n");121 b.append(" <description>"+escape(m.group(4))+"</description>\n");122 b.append(" <version>"+escape(m.group(5))+"</version>\n");123 b.append(" </plugin>\n");124 }125 b.append("</plugins>\n");126 return b;127 }111 private static CharSequence readWiki(BufferedReader r) throws IOException { 112 StringBuilder b = new StringBuilder("<plugins>\n"); 113 for (String line = r.readLine(); line != null; line = r.readLine()) { 114 Matcher m = wiki.matcher(line); 115 if (!m.matches()) 116 continue; 117 b.append(" <plugin>\n"); 118 b.append(" <name>"+escape(m.group(2))+"</name>\n"); 119 b.append(" <resource>"+escape(m.group(1))+"</resource>\n"); 120 b.append(" <author>"+escape(m.group(3))+"</author>\n"); 121 b.append(" <description>"+escape(m.group(4))+"</description>\n"); 122 b.append(" <version>"+escape(m.group(5))+"</version>\n"); 123 b.append(" </plugin>\n"); 124 } 125 b.append("</plugins>\n"); 126 return b; 127 } 128 128 129 private static String escape(String s) {130 return s.replaceAll("<", "<").replaceAll(">", ">");131 }129 private static String escape(String s) { 130 return s.replaceAll("<", "<").replaceAll(">", ">"); 131 } 132 132 133 public static boolean downloadPlugin(PluginDescription pd) {134 File file = new File(Main.pref.getPluginsDirFile(), pd.name + ".jar");135 if (!download(pd.resource, file)) {136 JOptionPane.showMessageDialog(Main.parent, tr("Could not download plugin: {0} from {1}", pd.name, pd.resource));137 } else {138 try {139 PluginInformation.findPlugin(pd.name);140 return true;141 } catch (Exception e) {142 e.printStackTrace();143 JOptionPane.showMessageDialog(Main.parent, tr("The plugin {0} seem to be broken or could not be downloaded automatically.", pd.name));144 }145 }146 if (file.exists())147 file.delete();148 return false;149 }133 public static boolean downloadPlugin(PluginDescription pd) { 134 File file = new File(Main.pref.getPluginsDirFile(), pd.name + ".jar"); 135 if (!download(pd.resource, file)) { 136 JOptionPane.showMessageDialog(Main.parent, tr("Could not download plugin: {0} from {1}", pd.name, pd.resource)); 137 } else { 138 try { 139 PluginInformation.findPlugin(pd.name); 140 return true; 141 } catch (Exception e) { 142 e.printStackTrace(); 143 JOptionPane.showMessageDialog(Main.parent, tr("The plugin {0} seem to be broken or could not be downloaded automatically.", pd.name)); 144 } 145 } 146 if (file.exists()) 147 file.delete(); 148 return false; 149 } 150 150 151 private static boolean download(String url, File file) {152 try {153 InputStream in = new URL(url).openStream();154 OutputStream out = new FileOutputStream(file);155 byte[] buffer = new byte[8192];156 for (int read = in.read(buffer); read != -1; read = in.read(buffer))157 out.write(buffer, 0, read);158 out.close();159 in.close();160 return true;161 } catch (MalformedURLException e) {162 e.printStackTrace();163 } catch (FileNotFoundException e) {164 e.printStackTrace();165 } catch (IOException e) {166 e.printStackTrace();167 }168 return false;169 }151 private static boolean download(String url, File file) { 152 try { 153 InputStream in = new URL(url).openStream(); 154 OutputStream out = new FileOutputStream(file); 155 byte[] buffer = new byte[8192]; 156 for (int read = in.read(buffer); read != -1; read = in.read(buffer)) 157 out.write(buffer, 0, read); 158 out.close(); 159 in.close(); 160 return true; 161 } catch (MalformedURLException e) { 162 e.printStackTrace(); 163 } catch (FileNotFoundException e) { 164 e.printStackTrace(); 165 } catch (IOException e) { 166 e.printStackTrace(); 167 } 168 return false; 169 } 170 170 171 public static void update(Collection<PluginDescription> update) {172 Main.worker.execute(new UpdateTask(update));173 }174 175 public static boolean moveUpdatedPlugins() {176 File pluginDir = Main.pref.getPluginsDirFile();177 boolean ok = true;178 if (pluginDir.exists() && pluginDir.isDirectory() && pluginDir.canWrite()) {179 final File[] files = pluginDir.listFiles(new FilenameFilter() {180 public boolean accept(File dir, String name) {181 return name.endsWith(".new");171 public static void update(Collection<PluginDescription> update) { 172 Main.worker.execute(new UpdateTask(update)); 173 } 174 175 public static boolean moveUpdatedPlugins() { 176 File pluginDir = Main.pref.getPluginsDirFile(); 177 boolean ok = true; 178 if (pluginDir.exists() && pluginDir.isDirectory() && pluginDir.canWrite()) { 179 final File[] files = pluginDir.listFiles(new FilenameFilter() { 180 public boolean accept(File dir, String name) { 181 return name.endsWith(".new"); 182 182 }}); 183 for (File updatedPlugin : files) {184 final String filePath = updatedPlugin.getPath();185 File plugin = new File(filePath.substring(0, filePath.length() - 4));186 ok = (plugin.delete() || !plugin.exists()) && updatedPlugin.renameTo(plugin) && ok;187 }188 }189 return ok;190 }183 for (File updatedPlugin : files) { 184 final String filePath = updatedPlugin.getPath(); 185 File plugin = new File(filePath.substring(0, filePath.length() - 4)); 186 ok = (plugin.delete() || !plugin.exists()) && updatedPlugin.renameTo(plugin) && ok; 187 } 188 } 189 return ok; 190 } 191 191 } -
trunk/src/org/openstreetmap/josm/plugins/PluginException.java
r1116 r1169 8 8 * and there is no particular reason to use this within the plugin itself (although there 9 9 * is also no reason against this.. ;) 10 * 10 * 11 11 * @author Immanuel.Scholz 12 12 */ 13 13 public class PluginException extends RuntimeException { 14 public final PluginProxy plugin;15 public final String name;14 public final PluginProxy plugin; 15 public final String name; 16 16 17 public PluginException(PluginProxy plugin, String name, Throwable cause) {18 super(tr("An error occured in plugin {0}", name), cause);19 this.plugin = plugin;20 this.name = name;17 public PluginException(PluginProxy plugin, String name, Throwable cause) { 18 super(tr("An error occured in plugin {0}", name), cause); 19 this.plugin = plugin; 20 this.name = name; 21 21 } 22 22 } -
trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java
r1073 r1169 29 29 */ 30 30 public class PluginInformation { 31 32 public final File file;33 public final String name;34 public final String mainversion;35 public final String className;36 public final String description;37 public final boolean early;38 public final String author;39 public final int stage;40 public final String version;41 public final List<URL> libraries = new LinkedList<URL>();42 43 public final Map<String, String> attr = new TreeMap<String, String>();44 45 /**46 * Used in the Plugin constructor to make the information of the plugin47 * that is currently initializing available.48 * 49 * If you think this is hacky, you are probably right. But it is50 * convinient anyway ;-)51 */52 static PluginInformation currentPluginInitialization = null;53 54 /**55 * @param file the plugin jar file.56 */57 public PluginInformation(File file) {58 this(file, file.getName().substring(0, file.getName().length()-4), null);59 }60 61 public PluginInformation(File file, String name, InputStream manifestStream) {62 this.name = name;63 this.file = file;64 try {65 Manifest manifest;66 JarInputStream jar = null;67 if (file != null) {68 jar = new JarInputStream(new FileInputStream(file));69 manifest = jar.getManifest();70 if (manifest == null)71 throw new IOException(file+" contains no manifest.");72 } else {73 manifest = new Manifest();74 manifest.read(manifestStream);75 }76 if (manifest != null) {77 Attributes attr = manifest.getMainAttributes();78 className = attr.getValue("Plugin-Class");79 description = attr.getValue("Plugin-Description");80 early = Boolean.parseBoolean(attr.getValue("Plugin-Early"));81 String stageStr = attr.getValue("Plugin-Stage");82 stage = stageStr == null ? 50 : Integer.parseInt(stageStr);83 version = attr.getValue("Plugin-Version");84 mainversion = attr.getValue("Plugin-Mainversion");85 author = attr.getValue("Author");86 87 String classPath = attr.getValue(Attributes.Name.CLASS_PATH);88 if (classPath != null) {89 for (String entry : classPath.split(" ")) {90 File entryFile;91 if (new File(entry).isAbsolute()) {92 entryFile = new File(entry);93 } else {94 entryFile = new File(file.getParent(), entry);95 }96 97 libraries.add(fileToURL(entryFile));98 }99 }100 for (Object o : attr.keySet())101 this.attr.put(o.toString(), attr.getValue(o.toString()));102 } else {103 // resource-only plugin104 className = null;105 mainversion = null;106 description = tr("unknown");107 early = false;108 stage = 50;109 version = null;110 author = null;111 }112 if (file != null)113 libraries.add(0, fileToURL(file));114 115 if (jar != null)116 jar.close();117 } catch (IOException e) {118 throw new PluginException(null, name, e);119 }120 }121 122 /**123 * Load and instantiate the plugin124 */125 public PluginProxy load(Class<?> klass) {126 try {127 currentPluginInitialization = this;128 return new PluginProxy(klass.newInstance(), this);129 } catch (Exception e) {130 throw new PluginException(null, name, e);131 }132 }133 134 /**135 * Load the class of the plugin136 */137 public Class<?> loadClass(ClassLoader classLoader) {138 if (className == null)139 return null;140 try {141 Class<?> realClass = Class.forName(className, true, classLoader);142 return realClass;143 } catch (Exception e) {144 throw new PluginException(null, name, e);145 }146 }147 148 public static URL fileToURL(File f) {149 try {150 return f.toURI().toURL();151 } catch (MalformedURLException ex) {152 return null;153 }154 }155 156 /**157 * Try to find a plugin after some criterias. Extract the plugin-information158 * from the plugin and return it. The plugin is searched in the following way:159 * 160 *<li>first look after an MANIFEST.MF in the package org.openstreetmap.josm.plugins.<plugin name>161 * (After removing all fancy characters from the plugin name).162 * If found, the plugin is loaded using the bootstrap classloader.163 *<li>If not found, look for a jar file in the user specific plugin directory164 * (~/.josm/plugins/<plugin name>.jar)165 *<li>If not found and the environment variable JOSM_RESSOURCES + "/plugins/" exist, look there.166 *<li>Try for the java property josm.ressources + "/plugins/" (set via java -Djosm.plugins.path=...)167 *<li>If the environment variable ALLUSERSPROFILE and APPDATA exist, look in168 * ALLUSERSPROFILE/<the last stuff from APPDATA>/JOSM/plugins.169 * (*sic* There is no easy way under Windows to get the All User's application170 * directory)171 *<li>Finally, look in some typical unix paths:<ul>172 * <li>/usr/local/share/josm/plugins/173 * <li>/usr/local/lib/josm/plugins/174 * <li>/usr/share/josm/plugins/175 * <li>/usr/lib/josm/plugins/176 * 177 * If a plugin class or jar file is found earlier in the list but seem not to178 * be working, an PluginException is thrown rather than continuing the search.179 * This is so JOSM can detect broken user-provided plugins and do not go silently180 * ignore them.181 * 182 * The plugin is not initialized. If the plugin is a .jar file, it is not loaded183 * (only the manifest is extracted). In the classloader-case, the class is184 * bootstraped (e.g. static {} - declarations will run. However, nothing else is done.185 *186 * @param pluginName The name of the plugin (in all lowercase). E.g. "lang-de"187 * @return Information about the plugin or <code>null</code>, if the plugin188 *was nowhere to be found.189 * @throws PluginException In case of broken plugins.190 */191 public static PluginInformation findPlugin(String pluginName) throws PluginException {192 String name = pluginName;193 name = name.replaceAll("[-. ]", "");194 InputStream manifestStream = PluginInformation.class.getResourceAsStream("/org/openstreetmap/josm/plugins/"+name+"/MANIFEST.MF");195 if (manifestStream != null)196 return new PluginInformation(null, pluginName, manifestStream);31 32 public final File file; 33 public final String name; 34 public final String mainversion; 35 public final String className; 36 public final String description; 37 public final boolean early; 38 public final String author; 39 public final int stage; 40 public final String version; 41 public final List<URL> libraries = new LinkedList<URL>(); 42 43 public final Map<String, String> attr = new TreeMap<String, String>(); 44 45 /** 46 * Used in the Plugin constructor to make the information of the plugin 47 * that is currently initializing available. 48 * 49 * If you think this is hacky, you are probably right. But it is 50 * convinient anyway ;-) 51 */ 52 static PluginInformation currentPluginInitialization = null; 53 54 /** 55 * @param file the plugin jar file. 56 */ 57 public PluginInformation(File file) { 58 this(file, file.getName().substring(0, file.getName().length()-4), null); 59 } 60 61 public PluginInformation(File file, String name, InputStream manifestStream) { 62 this.name = name; 63 this.file = file; 64 try { 65 Manifest manifest; 66 JarInputStream jar = null; 67 if (file != null) { 68 jar = new JarInputStream(new FileInputStream(file)); 69 manifest = jar.getManifest(); 70 if (manifest == null) 71 throw new IOException(file+" contains no manifest."); 72 } else { 73 manifest = new Manifest(); 74 manifest.read(manifestStream); 75 } 76 if (manifest != null) { 77 Attributes attr = manifest.getMainAttributes(); 78 className = attr.getValue("Plugin-Class"); 79 description = attr.getValue("Plugin-Description"); 80 early = Boolean.parseBoolean(attr.getValue("Plugin-Early")); 81 String stageStr = attr.getValue("Plugin-Stage"); 82 stage = stageStr == null ? 50 : Integer.parseInt(stageStr); 83 version = attr.getValue("Plugin-Version"); 84 mainversion = attr.getValue("Plugin-Mainversion"); 85 author = attr.getValue("Author"); 86 87 String classPath = attr.getValue(Attributes.Name.CLASS_PATH); 88 if (classPath != null) { 89 for (String entry : classPath.split(" ")) { 90 File entryFile; 91 if (new File(entry).isAbsolute()) { 92 entryFile = new File(entry); 93 } else { 94 entryFile = new File(file.getParent(), entry); 95 } 96 97 libraries.add(fileToURL(entryFile)); 98 } 99 } 100 for (Object o : attr.keySet()) 101 this.attr.put(o.toString(), attr.getValue(o.toString())); 102 } else { 103 // resource-only plugin 104 className = null; 105 mainversion = null; 106 description = tr("unknown"); 107 early = false; 108 stage = 50; 109 version = null; 110 author = null; 111 } 112 if (file != null) 113 libraries.add(0, fileToURL(file)); 114 115 if (jar != null) 116 jar.close(); 117 } catch (IOException e) { 118 throw new PluginException(null, name, e); 119 } 120 } 121 122 /** 123 * Load and instantiate the plugin 124 */ 125 public PluginProxy load(Class<?> klass) { 126 try { 127 currentPluginInitialization = this; 128 return new PluginProxy(klass.newInstance(), this); 129 } catch (Exception e) { 130 throw new PluginException(null, name, e); 131 } 132 } 133 134 /** 135 * Load the class of the plugin 136 */ 137 public Class<?> loadClass(ClassLoader classLoader) { 138 if (className == null) 139 return null; 140 try { 141 Class<?> realClass = Class.forName(className, true, classLoader); 142 return realClass; 143 } catch (Exception e) { 144 throw new PluginException(null, name, e); 145 } 146 } 147 148 public static URL fileToURL(File f) { 149 try { 150 return f.toURI().toURL(); 151 } catch (MalformedURLException ex) { 152 return null; 153 } 154 } 155 156 /** 157 * Try to find a plugin after some criterias. Extract the plugin-information 158 * from the plugin and return it. The plugin is searched in the following way: 159 * 160 *<li>first look after an MANIFEST.MF in the package org.openstreetmap.josm.plugins.<plugin name> 161 * (After removing all fancy characters from the plugin name). 162 * If found, the plugin is loaded using the bootstrap classloader. 163 *<li>If not found, look for a jar file in the user specific plugin directory 164 * (~/.josm/plugins/<plugin name>.jar) 165 *<li>If not found and the environment variable JOSM_RESSOURCES + "/plugins/" exist, look there. 166 *<li>Try for the java property josm.ressources + "/plugins/" (set via java -Djosm.plugins.path=...) 167 *<li>If the environment variable ALLUSERSPROFILE and APPDATA exist, look in 168 * ALLUSERSPROFILE/<the last stuff from APPDATA>/JOSM/plugins. 169 * (*sic* There is no easy way under Windows to get the All User's application 170 * directory) 171 *<li>Finally, look in some typical unix paths:<ul> 172 * <li>/usr/local/share/josm/plugins/ 173 * <li>/usr/local/lib/josm/plugins/ 174 * <li>/usr/share/josm/plugins/ 175 * <li>/usr/lib/josm/plugins/ 176 * 177 * If a plugin class or jar file is found earlier in the list but seem not to 178 * be working, an PluginException is thrown rather than continuing the search. 179 * This is so JOSM can detect broken user-provided plugins and do not go silently 180 * ignore them. 181 * 182 * The plugin is not initialized. If the plugin is a .jar file, it is not loaded 183 * (only the manifest is extracted). In the classloader-case, the class is 184 * bootstraped (e.g. static {} - declarations will run. However, nothing else is done. 185 * 186 * @param pluginName The name of the plugin (in all lowercase). E.g. "lang-de" 187 * @return Information about the plugin or <code>null</code>, if the plugin 188 * was nowhere to be found. 189 * @throws PluginException In case of broken plugins. 190 */ 191 public static PluginInformation findPlugin(String pluginName) throws PluginException { 192 String name = pluginName; 193 name = name.replaceAll("[-. ]", ""); 194 InputStream manifestStream = PluginInformation.class.getResourceAsStream("/org/openstreetmap/josm/plugins/"+name+"/MANIFEST.MF"); 195 if (manifestStream != null) 196 return new PluginInformation(null, pluginName, manifestStream); 197 197 198 198 Collection<String> locations = getPluginLocations(); 199 199 200 for (String s : locations) {201 File pluginFile = new File(s, pluginName + ".jar");202 if (pluginFile.exists()) {203 PluginInformation info = new PluginInformation(pluginFile);204 return info;205 }206 }207 return null;208 }209 210 public static Collection<String> getPluginLocations() {211 Collection<String> locations = Main.pref.getAllPossiblePreferenceDirs();212 Collection<String> all = new ArrayList<String>(locations.size());213 for (String s : locations)214 all.add(s+"plugins");215 return all;216 } 217 218 219 /**220 * Return information about a loaded plugin.221 * 222 * Note that if you call this in your plugins bootstrap, you may get <code>null</code> if223 * the plugin requested is not loaded yet.224 * 225 * @return The PluginInformation to a specific plugin, but only if the plugin is loaded.226 * If it is not loaded, <code>null</code> is returned.227 */228 public static PluginInformation getLoaded(String pluginName) {229 for (PluginProxy p : Main.plugins)230 if (p.info.name.equals(pluginName))231 return p.info;232 return null;233 }200 for (String s : locations) { 201 File pluginFile = new File(s, pluginName + ".jar"); 202 if (pluginFile.exists()) { 203 PluginInformation info = new PluginInformation(pluginFile); 204 return info; 205 } 206 } 207 return null; 208 } 209 210 public static Collection<String> getPluginLocations() { 211 Collection<String> locations = Main.pref.getAllPossiblePreferenceDirs(); 212 Collection<String> all = new ArrayList<String>(locations.size()); 213 for (String s : locations) 214 all.add(s+"plugins"); 215 return all; 216 } 217 218 219 /** 220 * Return information about a loaded plugin. 221 * 222 * Note that if you call this in your plugins bootstrap, you may get <code>null</code> if 223 * the plugin requested is not loaded yet. 224 * 225 * @return The PluginInformation to a specific plugin, but only if the plugin is loaded. 226 * If it is not loaded, <code>null</code> is returned. 227 */ 228 public static PluginInformation getLoaded(String pluginName) { 229 for (PluginProxy p : Main.plugins) 230 if (p.info.name.equals(pluginName)) 231 return p.info; 232 return null; 233 } 234 234 } 235 235 -
trunk/src/org/openstreetmap/josm/plugins/PluginProxy.java
r627 r1169 18 18 public class PluginProxy extends Plugin { 19 19 20 public final Object plugin;21 public final PluginInformation info;20 public final Object plugin; 21 public final PluginInformation info; 22 22 23 public PluginProxy(Object plugin, PluginInformation info) {24 this.plugin = plugin;25 this.info = info;23 public PluginProxy(Object plugin, PluginInformation info) { 24 this.plugin = plugin; 25 this.info = info; 26 26 } 27 27 28 @Override public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {29 try {30 plugin.getClass().getMethod("mapFrameInitialized", MapFrame.class, MapFrame.class).invoke(plugin, oldFrame, newFrame);28 @Override public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) { 29 try { 30 plugin.getClass().getMethod("mapFrameInitialized", MapFrame.class, MapFrame.class).invoke(plugin, oldFrame, newFrame); 31 31 } catch (NoSuchMethodException e) { 32 32 } catch (Exception e) { 33 throw new PluginException(this, info.name, e);33 throw new PluginException(this, info.name, e); 34 34 } 35 35 } 36 36 37 @Override public PreferenceSetting getPreferenceSetting() {38 try {39 return (PreferenceSetting)plugin.getClass().getMethod("getPreferenceSetting").invoke(plugin);40 } catch (NoSuchMethodException e) {41 return null;42 } catch (Exception e) {43 throw new PluginException(this, info.name, e);44 }37 @Override public PreferenceSetting getPreferenceSetting() { 38 try { 39 return (PreferenceSetting)plugin.getClass().getMethod("getPreferenceSetting").invoke(plugin); 40 } catch (NoSuchMethodException e) { 41 return null; 42 } catch (Exception e) { 43 throw new PluginException(this, info.name, e); 44 } 45 45 } 46 47 @Override public void addDownloadSelection(List<DownloadSelection> list) {48 try {49 plugin.getClass().getMethod("addDownloadSelection", List.class).invoke(plugin, list);50 } catch (NoSuchMethodException e) {51 // ignore52 } catch (Exception e) {53 throw new PluginException(this, info.name, e);54 }55 }46 47 @Override public void addDownloadSelection(List<DownloadSelection> list) { 48 try { 49 plugin.getClass().getMethod("addDownloadSelection", List.class).invoke(plugin, list); 50 } catch (NoSuchMethodException e) { 51 // ignore 52 } catch (Exception e) { 53 throw new PluginException(this, info.name, e); 54 } 55 } 56 56 }
Note:
See TracChangeset
for help on using the changeset viewer.
