Changeset 243 in josm for src/org/openstreetmap


Ignore:
Timestamp:
2007-05-22T21:58:09+02:00 (18 years ago)
Author:
imi
Message:
  • added josm.plugins - Java property to load plugins regardless of preferences
  • fixed posibility to load Plugins from bootstrap classloader (with full manifest support)
  • added System wide plugin and ressource directories
Location:
src/org/openstreetmap/josm
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/org/openstreetmap/josm/Main.java

    r242 r243  
    1111import java.net.URI;
    1212import java.net.URISyntaxException;
     13import java.util.Arrays;
    1314import java.util.Collection;
    1415import java.util.LinkedList;
     16import java.util.List;
    1517import java.util.Map;
    1618import java.util.SortedMap;
     
    199201         */
    200202        public static void loadPlugins(boolean early) {
    201                 if (!Main.pref.hasKey("plugins"))
     203                List<String> plugins = new LinkedList<String>();
     204                if (Main.pref.hasKey("plugins"))
     205                        plugins.addAll(Arrays.asList(Main.pref.get("plugins").split(",")));
     206                if (System.getProperty("josm.plugins") != null)
     207                        plugins.addAll(Arrays.asList(System.getProperty("josm.plugins").split(",")));
     208                if (plugins.isEmpty())
    202209                        return;
     210
    203211                SortedMap<Integer, Collection<PluginInformation>> p = new TreeMap<Integer, Collection<PluginInformation>>();
    204                 for (String pluginName : Main.pref.get("plugins").split(",")) {
    205                         File pluginFile = new File(pref.getPreferencesDir()+"plugins/"+pluginName+".jar");
    206                         if (pluginFile.exists()) {
    207                                 PluginInformation info = new PluginInformation(pluginFile);
     212                for (String pluginName : plugins) {
     213                        PluginInformation info = PluginInformation.findPlugin(pluginName);
     214                        if (info != null) {
    208215                                if (info.early != early)
    209216                                        continue;
     
    224231                                        ImageProvider.sources.add(0, klass);
    225232                                        System.out.println("loading "+info.name);
    226                                         plugins.add(info.load(klass));
     233                                        Main.plugins.add(info.load(klass));
    227234                                } catch (PluginException e) {
    228235                                        e.printStackTrace();
  • src/org/openstreetmap/josm/data/Preferences.java

    r205 r243  
    5858
    5959        /**
    60          * Return the location of the preferences file
     60         * Return the location of the user defined preferences file
    6161         */
    6262        public String getPreferencesDir() {
     
    6565                return System.getProperty("user.home")+"/.josm/";
    6666        }
     67
     68        /**
     69         * @return A list of all existing directories, where ressources could be stored.
     70         */
     71        public Collection<String> getAllPossiblePreferenceDirs() {
     72            LinkedList<String> locations = new LinkedList<String>();
     73        locations.add(Main.pref.getPreferencesDir());
     74        String s;
     75        if ((s = System.getenv("JOSM_RESSOURCES")) != null) {
     76                if (!s.endsWith("/") && !s.endsWith("\\"))
     77                        s = s + "/";
     78                locations.add(System.getenv("JOSM_RESSOURCES"));
     79        }
     80        if ((s = System.getProperty("josm.ressources")) != null) {
     81                if (!s.endsWith("/") && !s.endsWith("\\"))
     82                        s = s + "/";
     83                locations.add(System.getProperty("josm.ressources"));
     84        }
     85        String appdata = System.getenv("APPDATA");
     86        if (System.getenv("ALLUSERSPROFILE") != null && appdata != null && appdata.lastIndexOf("\\") != -1) {
     87                appdata = appdata.substring(appdata.lastIndexOf("\\"));
     88                locations.add(System.getenv("ALLUSERSPROFILE")+appdata+"/JOSM/");
     89        }
     90        locations.add("/usr/local/share/josm/");
     91        locations.add("/usr/local/lib/josm/");
     92        locations.add("/usr/share/josm/");
     93        locations.add("/usr/lib/josm/");
     94            return locations;
     95        }
     96
    6797
    6898        synchronized public boolean hasKey(final String key) {
  • src/org/openstreetmap/josm/gui/MainApplication.java

    r231 r243  
    2121
    2222import org.openstreetmap.josm.Main;
    23 import org.openstreetmap.josm.plugins.PluginInformation;
    2423import org.openstreetmap.josm.tools.BugReportExceptionHandler;
    2524/**
     
    5049         * Main application Startup
    5150         */
     51        @SuppressWarnings("deprecation")
    5252        public static void main(final String[] argArray) {
    5353                /////////////////////////////////////////////////////////////////////////
     
    112112                }
    113113
    114                 // determine what classloader to be used for plugins
    115                 if (args.containsKey("default-classloader"))
    116                         PluginInformation.useJosmClassloader = true;
    117 
    118114                // load the early plugins
    119115                Main.loadPlugins(true);
     
    131127                                        "\t--downloadgps=minlat,minlon,maxlat,maxlon "+tr("Download the bounding box as raw gps")+"\n"+
    132128                                        "\t--selection=<searchstring>                "+tr("Select with the given search")+"\n"+
    133                                         "\t--default-classloader                     "+tr("Load all plugins with the default class loader")+"\n"+
    134129                                        "\t--no-fullscreen                           "+tr("Don't launch in fullscreen mode")+"\n"+
    135130                                        "\t--reset-preferences                       "+tr("Reset the preferences to default")+"\n\n"+
  • src/org/openstreetmap/josm/gui/preferences/PluginPreference.java

    r215 r243  
    88import java.util.Arrays;
    99import java.util.Collection;
     10import java.util.Collections;
     11import java.util.Comparator;
    1012import java.util.HashMap;
    1113import java.util.LinkedList;
     14import java.util.List;
    1215import java.util.Map;
    1316import java.util.Map.Entry;
     
    3336                pluginMap = new HashMap<PluginInformation, Boolean>();
    3437                Box pluginPanel = Box.createVerticalBox();
    35                 Collection<PluginInformation> availablePlugins = new LinkedList<PluginInformation>();
    36                 File[] pluginFiles = new File(Main.pref.getPreferencesDir()+"plugins").listFiles();
    37                 if (pluginFiles != null) {
    38                         Arrays.sort(pluginFiles);
    39                         for (File f : pluginFiles) {
    40                                 if (f.isFile() && f.getName().endsWith(".jar")) {
    41                                         try {
    42                             availablePlugins.add(new PluginInformation(f));
    43                     } catch (PluginException x) {
    44                     }
     38                List<PluginInformation> availablePlugins = new LinkedList<PluginInformation>();
     39                for (String location : PluginInformation.getPluginLocations()) {
     40                        File[] pluginFiles = new File(location).listFiles();
     41                        if (pluginFiles != null) {
     42                                Arrays.sort(pluginFiles);
     43                                for (File f : pluginFiles) {
     44                                        if (f.isFile() && f.getName().endsWith(".jar")) {
     45                                                try {
     46                                    availablePlugins.add(new PluginInformation(f));
     47                            } catch (PluginException x) {
     48                            }
     49                                        }
    4550                                }
    4651                        }
    4752                }
     53                Collections.sort(availablePlugins, new Comparator<PluginInformation>(){
     54                        public int compare(PluginInformation o1, PluginInformation o2) {
     55                    return o1.name.compareTo(o2.name);
     56            }
     57                });
    4858
    4959                Collection<String> enabledPlugins = Arrays.asList(Main.pref.get("plugins").split(","));
     
    5363                        pluginPanel.add(pluginCheck);
    5464
    55                         pluginCheck.setToolTipText(plugin.file.getAbsolutePath());
     65                        pluginCheck.setToolTipText(plugin.file != null ? plugin.file.getAbsolutePath() : tr("Plugin bundled with JOSM"));
    5666                        JLabel label = new JLabel("<html><i>"+(plugin.description==null?"no description available":plugin.description)+"</i></html>");
    5767                        label.setBorder(BorderFactory.createEmptyBorder(0,20,0,0));
  • src/org/openstreetmap/josm/plugins/PluginInformation.java

    r215 r243  
    44import java.io.FileInputStream;
    55import java.io.IOException;
     6import java.io.InputStream;
    67import java.net.URL;
    78import java.net.URLClassLoader;
    89import java.util.ArrayList;
     10import java.util.Collection;
    911import java.util.List;
    1012import java.util.Map;
     
    1315import java.util.jar.JarInputStream;
    1416import java.util.jar.Manifest;
     17
     18import org.openstreetmap.josm.Main;
    1519
    1620/**
     
    2125 */
    2226public class PluginInformation {
    23        
    24         /**
    25          * Whether to use the standard classloader to load the plugins or
    26          * an seperate class loader. Note that in case of the standard classloader,
    27          * all plugin files has to be included in the main josm.jar classpath
    28          *
    29          * Set via command line parameter to true.
    30          *
    31          * This switch is intended for debugging JOSM (or prepackaging plugins
    32          * together with JOSM).
    33          */
    34         public static boolean useJosmClassloader = false;
    3527       
    3628        public final File file;
     
    4941         */
    5042        public PluginInformation(File file) {
     43                this(file, file.getName().substring(0, file.getName().length()-4), null);
     44        }
     45       
     46        public PluginInformation(File file, String name, InputStream manifestStream) {
     47                this.name = name;
    5148                this.file = file;
    52                 name = file.getName().substring(0, file.getName().length()-4);
    5349                try {
    54                         JarInputStream jar = new JarInputStream(new FileInputStream(file));
    55                         Manifest manifest = jar.getManifest();
    56                         if (manifest == null)
    57                                 throw new IOException(file+" contains no manifest.");
     50                        Manifest manifest;
     51                        JarInputStream jar = null;
     52                        if (file != null) {
     53                                jar = new JarInputStream(new FileInputStream(file));
     54                                manifest = jar.getManifest();
     55                                if (manifest == null)
     56                                        throw new IOException(file+" contains no manifest.");
     57                        } else {
     58                                manifest = new Manifest();
     59                        manifest.read(manifestStream);
     60                        }
    5861                        Attributes attr = manifest.getMainAttributes();
    5962                        className = attr.getValue("Plugin-Class");
     
    6366                        stage = stageStr == null ? 50 : Integer.parseInt(stageStr);
    6467                        author = attr.getValue("Author");
    65                         libraries.add(new URL(getURLString(file.getAbsolutePath())));
     68                        if (file != null)
     69                                libraries.add(new URL(getURLString(file.getAbsolutePath())));
    6670                        String classPath = attr.getValue("Class-Path");
    6771                        if (classPath != null) {
     
    8589                        for (Object o : attr.keySet())
    8690                                this.attr.put(o.toString(), attr.getValue(o.toString()));
    87                         jar.close();
     91                        if (jar != null)
     92                                jar.close();
    8893                } catch (IOException e) {
    8994                        throw new PluginException(null, name, e);
     
    107112        public Class<?> loadClass() {
    108113                try {
    109                         if (useJosmClassloader)
    110                                 return Class.forName(className);
    111 
    112114                        URL[] urls = new URL[libraries.size()];
    113115                        urls = libraries.toArray(urls);
     
    125127                return "file://"+fileName;
    126128        }
     129       
     130        /**
     131         * Try to find a plugin after some criterias. Extract the plugin-information
     132         * from the plugin and return it. The plugin is searched in the following way:
     133         *
     134         *<li>first look after an MANIFEST.MF in the package org.openstreetmap.josm.plugins.<plugin name>
     135         *    (After removing all fancy characters from the plugin name).
     136         *    If found, the plugin is loaded using the bootstrap classloader.
     137         *<li>If not found, look for a jar file in the user specific plugin directory
     138         *    (~/.josm/plugins/<plugin name>.jar)
     139         *<li>If not found and the environment variable JOSM_RESSOURCES + "/plugins/" exist, look there.
     140         *<li>Try for the java property josm.ressources + "/plugins/" (set via java -Djosm.plugins.path=...)
     141         *<li>If the environment variable ALLUSERSPROFILE and APPDATA exist, look in
     142         *    ALLUSERSPROFILE/<the last stuff from APPDATA>/JOSM/plugins.
     143         *    (*sic* There is no easy way under Windows to get the All User's application
     144         *    directory)
     145         *<li>Finally, look in some typical unix paths:<ul>
     146         *    <li>/usr/local/share/josm/plugins/
     147         *    <li>/usr/local/lib/josm/plugins/
     148         *    <li>/usr/share/josm/plugins/
     149         *    <li>/usr/lib/josm/plugins/
     150         *
     151         * If a plugin class or jar file is found earlier in the list but seem not to
     152         * be working, an PluginException is thrown rather than continuing the search.
     153         * This is so JOSM can detect broken user-provided plugins and do not go silently
     154         * ignore them.
     155         *
     156         * The plugin is not initialized. If the plugin is a .jar file, it is not loaded
     157         * (only the manifest is extracted). In the classloader-case, the class is
     158         * bootstraped (e.g. static {} - declarations will run. However, nothing else is done.
     159         *
     160         * @param pluginName The name of the plugin (in all lowercase). E.g. "lang-de"
     161         * @return Information about the plugin or <code>null</code>, if the plugin
     162         *             was nowhere to be found.
     163         * @throws PluginException In case of broken plugins.
     164         */
     165        public static PluginInformation findPlugin(String pluginName) throws PluginException {
     166        String name = pluginName;
     167        name = name.replaceAll("[-. ]", "");
     168        InputStream manifestStream = PluginInformation.class.getResourceAsStream("/org/openstreetmap/josm/plugins/"+name+"/MANIFEST.MF");
     169        if (manifestStream != null)
     170                return new PluginInformation(null, pluginName, manifestStream);
     171
     172        Collection<String> locations = getPluginLocations();
     173
     174        for (String s : locations) {
     175                File pluginFile = new File(s+"/"+pluginName+".jar");
     176                if (pluginFile.exists()) {
     177                                PluginInformation info = new PluginInformation(pluginFile);
     178                                return info;
     179                }
     180        }
     181        return null;
     182        }
     183
     184        public static Collection<String> getPluginLocations() {
     185            Collection<String> locations = Main.pref.getAllPossiblePreferenceDirs();
     186            Collection<String> all = new ArrayList<String>(locations.size());
     187            for (String s : locations)
     188                all.add(s+"plugins");
     189            return all;
     190    }
    127191}
  • src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java

    r205 r243  
    5454                        String pluginName = guessPlugin(e);
    5555                        if (pluginName != null) {
    56                                 LinkedList<String> plugins = new LinkedList<String>(Arrays.asList(Main.pref.get("plugins").split(",")));
    57                                 if (plugins.contains(pluginName)) {
     56                                boolean loaded = false;
     57                                for (PluginProxy p : Main.plugins)
     58                                        if (p.info.name.equals(pluginName))
     59                                                loaded = true;
     60                                if (loaded) {
    5861                                        String author = findPluginAuthor(pluginName);
    5962                                        int answer = JOptionPane.showConfirmDialog(
     
    6568                                                        JOptionPane.YES_NO_OPTION);
    6669                                        if (answer == JOptionPane.OK_OPTION) {
    67                                                 while (plugins.remove(pluginName)) {}
    68                                                 String p = "";
    69                                                 for (String s : plugins)
    70                                                         p += ","+s;
    71                                                 if (p.length() > 0)
    72                                                         p = p.substring(1);
    73                                                 Main.pref.put("plugins", p);
    74                                                 JOptionPane.showMessageDialog(Main.parent, tr("The plugin has been removed from the configuration. Please restart JOSM to unload the plugin."));
     70                                                LinkedList<String> plugins = new LinkedList<String>(Arrays.asList(Main.pref.get("plugins").split(",")));
     71                                                if (plugins.contains(pluginName)) {
     72                                                        while (plugins.remove(pluginName)) {}
     73                                                        String p = "";
     74                                                        for (String s : plugins)
     75                                                                p += ","+s;
     76                                                        if (p.length() > 0)
     77                                                                p = p.substring(1);
     78                                                        Main.pref.put("plugins", p);
     79                                                        JOptionPane.showMessageDialog(Main.parent, tr("The plugin has been removed from the configuration. Please restart JOSM to unload the plugin."));
     80                                                } else {
     81                                                        JOptionPane.showMessageDialog(Main.parent, tr("The plugin could not be removed. Please tell the people you got JOSM from about the problem."));
     82                                                }
    7583                                                return;
    7684                                        }
  • src/org/openstreetmap/josm/tools/ImageProvider.java

    r204 r243  
    1010import java.awt.Transparency;
    1111import java.awt.image.BufferedImage;
     12import java.io.File;
     13import java.net.MalformedURLException;
    1214import java.net.URL;
    1315import java.util.HashMap;
     
    7072                        subdir += "/";
    7173                String ext = name.indexOf('.') != -1 ? "" : ".png";
    72                 URL path = null;
    73                 for (Class<?> source : sources) {
    74                         path = source.getResource("/images/"+subdir+name+ext);
    75                         if (path != null)
    76                                 break;
    77                 }
     74
     75                URL path = getImageUrl(subdir+name+ext);
    7876                if (path == null)
    7977                        return null;
     78               
    8079                Image img = cache.get(path);
    8180                if (img == null) {
     
    8584                return new ImageIcon(img);
    8685        }
     86
     87        private static URL getImageUrl(String imageName) {
     88            URL path = null;
     89            for (Class<?> source : sources)
     90                        if ((path = source.getResource("/images/"+imageName)) != null)
     91                                return path;
     92           
     93            // Try all ressource directories as well
     94                for (String location : Main.pref.getAllPossiblePreferenceDirs()) {
     95                        try {
     96                                if (new File(location+"images/"+imageName).exists())
     97                                        return new URL("file", "", location+"images/"+imageName);
     98            } catch (MalformedURLException e) {
     99            }
     100                }
     101            return null;
     102    }
    87103
    88104        /**
Note: See TracChangeset for help on using the changeset viewer.