Ignore:
Timestamp:
2012-11-26T19:16:05+01:00 (8 years ago)
Author:
Don-vip
Message:

fix #7680, fix #8209 - Better handling of plugin automatic updates (automatic dependencies resolution + version number update)

Location:
trunk/src/org/openstreetmap/josm/plugins
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java

    r5508 r5601  
    424424        }
    425425
    426         return checkRequiredPluginsPreconditions(parent, plugins, plugin);
     426        return checkRequiredPluginsPreconditions(parent, plugins, plugin, true);
    427427    }
    428428
     
    434434     * @param plugins the collection of all loaded plugins
    435435     * @param plugin the plugin for which preconditions are checked
     436     * @param local Determines if the local or up-to-date plugin dependencies are to be checked.
    436437     * @return true, if the preconditions are met; false otherwise
    437      */
    438     public static boolean checkRequiredPluginsPreconditions(Component parent, Collection<PluginInformation> plugins, PluginInformation plugin) {
    439 
     438     * @since 5601
     439     */
     440    public static boolean checkRequiredPluginsPreconditions(Component parent, Collection<PluginInformation> plugins, PluginInformation plugin, boolean local) {
     441
     442        String requires = local ? plugin.localrequires : plugin.requires;
     443       
    440444        // make sure the dependencies to other plugins are not broken
    441445        //
    442         if(plugin.requires != null){
     446        if (requires != null) {
    443447            Set<String> pluginNames = new HashSet<String>();
    444448            for (PluginInformation pi: plugins) {
     
    446450            }
    447451            Set<String> missingPlugins = new HashSet<String>();
    448             for (String requiredPlugin : plugin.requires.split(";")) {
    449                 requiredPlugin = requiredPlugin.trim();
     452            List<String> requiredPlugins = local ? plugin.getLocalRequiredPlugins() : plugin.getRequiredPlugins();
     453            for (String requiredPlugin : requiredPlugins) {
    450454                if (!pluginNames.contains(requiredPlugin)) {
    451455                    missingPlugins.add(requiredPlugin);
     
    730734        );
    731735    }
     736   
     737    private static Set<PluginInformation> findRequiredPluginsToDownload(
     738            Collection<PluginInformation> pluginsToUpdate, List<PluginInformation> allPlugins, Set<PluginInformation> pluginsToDownload) {
     739        Set<PluginInformation> result = new HashSet<PluginInformation>();
     740        for (PluginInformation pi : pluginsToUpdate) {
     741            for (String name : pi.getRequiredPlugins()) {
     742                try {
     743                    PluginInformation installedPlugin = PluginInformation.findPlugin(name);
     744                    if (installedPlugin == null) {
     745                        // New required plugin is not installed, find its PluginInformation
     746                        PluginInformation reqPlugin = null;
     747                        for (PluginInformation pi2 : allPlugins) {
     748                            if (pi2.getName().equals(name)) {
     749                                reqPlugin = pi2;
     750                                break;
     751                            }
     752                        }
     753                        // Required plugin is known but not already on download list
     754                        if (reqPlugin != null && !pluginsToDownload.contains(reqPlugin)) {
     755                            result.add(reqPlugin);
     756                        }
     757                    }
     758                } catch (PluginException e) {
     759                    System.out.println(tr("Warning: failed to find plugin {0}", name));
     760                    e.printStackTrace();
     761                }
     762            }
     763        }
     764        return result;
     765    }
    732766
    733767    /**
     
    757791            );
    758792            Future<?> future = service.submit(task1);
     793            List<PluginInformation> allPlugins = null;
     794           
    759795            try {
    760796                future.get();
     797                allPlugins = task1.getAvailablePlugins();
    761798                plugins = buildListOfPluginsToLoad(parent,monitor.createSubTaskMonitor(1, false));
    762799            } catch(ExecutionException e) {
     
    778815                }
    779816            }
    780 
     817           
    781818            if (!pluginsToUpdate.isEmpty()) {
     819               
     820                Set<PluginInformation> pluginsToDownload = new HashSet<PluginInformation>(pluginsToUpdate);
     821               
     822                if (allPlugins != null) {
     823                    // Updated plugins may need additional plugin dependencies currently not installed
     824                    //
     825                    Set<PluginInformation> additionalPlugins = findRequiredPluginsToDownload(pluginsToUpdate, allPlugins, pluginsToDownload);
     826                    pluginsToDownload.addAll(additionalPlugins);
     827                   
     828                    // Iterate on required plugins, if they need themselves another plugins (i.e A needs B, but B needs C)
     829                    while (!additionalPlugins.isEmpty()) {
     830                        // Install the additional plugins to load them later
     831                        plugins.addAll(additionalPlugins);
     832                        additionalPlugins = findRequiredPluginsToDownload(additionalPlugins, allPlugins, pluginsToDownload);
     833                        pluginsToDownload.addAll(additionalPlugins);
     834                    }
     835                }
     836
    782837                // try to update the locally installed plugins
    783838                //
    784839                PluginDownloadTask task2 = new PluginDownloadTask(
    785840                        monitor.createSubTaskMonitor(1,false),
    786                         pluginsToUpdate,
     841                        pluginsToDownload,
    787842                        tr("Update plugins")
    788843                );
     
    800855                    return plugins;
    801856                }
     857               
     858                // Update Plugin info for downloaded plugins
     859                //
     860                refreshLocalUpdatedPluginInfo(task2.getDownloadedPlugins());
     861               
    802862                // notify user if downloading a locally installed plugin failed
    803863                //
     
    921981        return;
    922982    }
     983   
     984    /**
     985     * Replies the updated jar file for the given plugin name.
     986     * @param name The plugin name to find.
     987     * @return the updated jar file for the given plugin name. null if not found or not readable.
     988     * @since 5601
     989     */
     990    public static File findUpdatedJar(String name) {
     991        File pluginDir = Main.pref.getPluginsDirectory();
     992        // Find the downloaded file. We have tried to install the downloaded plugins
     993        // (PluginHandler.installDownloadedPlugins). This succeeds depending on the
     994        // platform.
     995        File downloadedPluginFile = new File(pluginDir, name + ".jar.new");
     996        if (!(downloadedPluginFile.exists() && downloadedPluginFile.canRead())) {
     997            downloadedPluginFile = new File(pluginDir, name + ".jar");
     998            if (!(downloadedPluginFile.exists() && downloadedPluginFile.canRead())) {
     999                return null;
     1000            }
     1001        }
     1002        return downloadedPluginFile;
     1003    }
     1004   
     1005    /**
     1006     * Refreshes the given PluginInformation objects with new contents read from their corresponding jar file.
     1007     * @param updatedPlugins The PluginInformation objects to update.
     1008     * @since 5601
     1009     */
     1010    public static void refreshLocalUpdatedPluginInfo(Collection<PluginInformation> updatedPlugins) {
     1011        if (updatedPlugins == null) return;
     1012        for (PluginInformation pi : updatedPlugins) {
     1013            File downloadedPluginFile = findUpdatedJar(pi.name);
     1014            if (downloadedPluginFile == null) {
     1015                continue;
     1016            }
     1017            try {
     1018                pi.updateFromJar(new PluginInformation(downloadedPluginFile, pi.name));
     1019            } catch(PluginException e) {
     1020                e.printStackTrace();
     1021            }
     1022        }
     1023    }
    9231024
    9241025    private static boolean confirmDeactivatingPluginAfterException(PluginProxy plugin) {
  • trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java

    r5588 r5601  
    4444    public boolean oldmode = false;
    4545    public String requires = null;
     46    public String localrequires = null;
    4647    public String link = null;
    4748    public String description = null;
     
    157158        this.attr.putAll(other.attr);
    158159    }
    159 
     160   
     161    /**
     162     * Updates the plugin information of this plugin information object with the
     163     * plugin information in a plugin information object retrieved from a plugin
     164     * jar.
     165     *
     166     * @param other the plugin information object retrieved from the jar file
     167     * @since 5601
     168     */
     169    public void updateFromJar(PluginInformation other) {
     170        updateLocalInfo(other);
     171        if (other.icon != null) {
     172            this.icon = other.icon;
     173        }
     174        this.early = other.early;
     175        this.className = other.className;
     176        this.libraries = other.libraries;
     177        this.stage = other.stage;
     178    }
     179   
    160180    private void scanManifest(Manifest manifest, boolean oldcheck){
    161181        String lang = LanguageInfo.getLanguageCodeManifest();
     
    452472    }
    453473
     474    /**
     475     * Replies the plugin icon, scaled to 24x24 pixels.
     476     * @return the plugin icon, scaled to 24x24 pixels.
     477     */
    454478    public ImageIcon getScaledIcon() {
    455479        if (icon == null)
     
    462486        return getName();
    463487    }
     488
     489    private static List<String> getRequiredPlugins(String pluginList) {
     490        List<String> requiredPlugins = new ArrayList<String>();
     491        if (pluginList != null) {
     492            for (String s : pluginList.split(";")) {
     493                String plugin = s.trim();
     494                if (!plugin.isEmpty()) {
     495                    requiredPlugins.add(plugin);
     496                }
     497            }
     498        }
     499        return requiredPlugins;
     500    }
     501   
     502    /**
     503     * Replies the list of plugins required by the up-to-date version of this plugin.
     504     * @return List of plugins required. Empty if no plugin is required.
     505     * @since 5601
     506     */
     507    public List<String> getRequiredPlugins() {
     508        return getRequiredPlugins(requires);
     509    }
     510   
     511    /**
     512     * Replies the list of plugins required by the local instance of this plugin.
     513     * @return List of plugins required. Empty if no plugin is required.
     514     * @since 5601
     515     */
     516    public List<String> getLocalRequiredPlugins() {
     517        return getRequiredPlugins(localrequires);
     518    }
     519   
     520    /**
     521     * Updates the local fields ({@link #localversion}, {@link #localmainversion}, {@link #localrequires})
     522     * to values contained in the up-to-date fields ({@link #version}, {@link #mainversion}, {@link #requires})
     523     * of the given PluginInformation.
     524     * @param info The plugin information to get the data from.
     525     * @since 5601
     526     */
     527    public void updateLocalInfo(PluginInformation info) {
     528        if (info != null) {
     529            this.localversion = info.version;
     530            this.localmainversion = info.mainversion;
     531            this.localrequires = info.requires;
     532        }
     533    }
    464534}
  • trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java

    r5266 r5601  
    6363        );
    6464        if (!availablePlugins.containsKey(info.getName())) {
    65             info.localversion = info.version;
    66             info.localmainversion = info.mainversion;
     65            info.updateLocalInfo(info);
    6766            availablePlugins.put(info.getName(), info);
    6867        } else {
    6968            PluginInformation current = availablePlugins.get(info.getName());
    70             current.localversion = info.version;
    71             current.localmainversion = info.mainversion;
    72             if (info.icon != null) {
    73                 current.icon = info.icon;
    74             }
    75             current.early = info.early;
    76             current.className = info.className;
    77             current.libraries = info.libraries;
    78             current.stage = info.stage;
    79             current.requires = info.requires;
     69            current.updateFromJar(info);
    8070        }
    8171    }
  • trunk/src/org/openstreetmap/josm/plugins/ReadRemotePluginInformationTask.java

    r5587 r5601  
    382382     *
    383383     * @return  the list of plugins
    384      */
    385     public List<PluginInformation> getAvailabePlugins() {
     384     * @since 5601
     385     */
     386    public List<PluginInformation> getAvailablePlugins() {
    386387        return availablePlugins;
    387388    }
Note: See TracChangeset for help on using the changeset viewer.