001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.server.plugins;
021    
022    import com.google.common.collect.Lists;
023    import com.google.common.collect.Maps;
024    import org.sonar.updatecenter.common.*;
025    
026    import java.util.Date;
027    import java.util.List;
028    import java.util.Map;
029    import java.util.SortedSet;
030    
031    public final class UpdateCenterMatrix {
032    
033      private UpdateCenter center;
034      private Version installedSonarVersion;
035      private Map<Plugin, Version> installedPlugins = Maps.newHashMap();
036      private List<String> pendingPluginFilenames = Lists.newArrayList();
037      private Date date;
038    
039      public UpdateCenterMatrix(UpdateCenter center, Version installedSonarVersion) {
040        this.center = center;
041        this.installedSonarVersion = installedSonarVersion;
042      }
043    
044      public UpdateCenterMatrix(UpdateCenter center, String installedSonarVersion) {
045        this(center, Version.create(installedSonarVersion));
046      }
047    
048      public UpdateCenter getCenter() {
049        return center;
050      }
051    
052      public Version getInstalledSonarVersion() {
053        return installedSonarVersion;
054      }
055    
056      public UpdateCenterMatrix registerInstalledPlugin(String pluginKey, Version pluginVersion) {
057        Plugin plugin = center.getPlugin(pluginKey);
058        if (plugin != null) {
059          installedPlugins.put(plugin, pluginVersion);
060        }
061        return this;
062      }
063    
064      public UpdateCenterMatrix registerPendingPluginsByFilename(String filename) {
065        pendingPluginFilenames.add(filename);
066        return this;
067      }
068    
069      public List<PluginUpdate> findAvailablePlugins() {
070        List<PluginUpdate> availables = Lists.newArrayList();
071        for (Plugin plugin : center.getPlugins()) {
072          if (!installedPlugins.containsKey(plugin) && !isAlreadyDownloaded(plugin)) {
073            Release release = plugin.getLastCompatibleRelease(installedSonarVersion);
074            if (release != null) {
075              availables.add(PluginUpdate.createWithStatus(release, PluginUpdate.Status.COMPATIBLE));
076    
077            } else {
078              release = plugin.getLastCompatibleReleaseIfUpgrade(installedSonarVersion);
079              if (release != null) {
080                availables.add(PluginUpdate.createWithStatus(release, PluginUpdate.Status.REQUIRE_SONAR_UPGRADE));
081              }
082            }
083          }
084        }
085        return availables;
086      }
087    
088      private boolean isAlreadyDownloaded(Artifact artifact) {
089        for (Release r : artifact.getReleases()) {
090          if (pendingPluginFilenames.contains(r.getFilename())) {
091            // already downloaded
092            return true;
093          }
094        }
095        return false;
096      }
097    
098      public List<PluginUpdate> findPluginUpdates() {
099        List<PluginUpdate> updates = Lists.newArrayList();
100        for (Map.Entry<Plugin, Version> entry : installedPlugins.entrySet()) {
101          Plugin plugin = entry.getKey();
102          if (!isAlreadyDownloaded(plugin)) {
103            Version pluginVersion = entry.getValue();
104            for (Release release : plugin.getReleasesGreaterThan(pluginVersion)) {
105              updates.add(PluginUpdate.createForPluginRelease(release, installedSonarVersion));
106            }
107          }
108        }
109        return updates;
110      }
111    
112      public List<SonarUpdate> findSonarUpdates() {
113        List<SonarUpdate> updates = Lists.newArrayList();
114        SortedSet<Release> releases = center.getSonar().getReleasesGreaterThan(installedSonarVersion);
115        for (Release release : releases) {
116          updates.add(createSonarUpdate(release));
117        }
118        return updates;
119      }
120    
121      SonarUpdate createSonarUpdate(Release sonarRelease) {
122        SonarUpdate update = new SonarUpdate(sonarRelease);
123        for (Map.Entry<Plugin, Version> entry : installedPlugins.entrySet()) {
124          Plugin plugin = entry.getKey();
125          Version pluginVersion = entry.getValue();
126          Release pluginRelease = plugin.getRelease(pluginVersion);
127    
128          if (pluginRelease != null && pluginRelease.supportSonarVersion(sonarRelease.getVersion())) {
129            update.addCompatiblePlugin(plugin);
130    
131          } else {
132            // search for a compatible plugin upgrade
133            boolean ok = false;
134            Release compatibleRelease = null;
135            for (Release greaterPluginRelease : plugin.getReleasesGreaterThan(pluginVersion)) {
136              if (greaterPluginRelease.supportSonarVersion(sonarRelease.getVersion())) {
137                compatibleRelease = greaterPluginRelease;
138                ok = true;
139              }
140            }
141            if (ok) {
142              update.addPluginToUpgrade(compatibleRelease);
143            } else {
144              update.addIncompatiblePlugin(plugin);
145            }
146          }
147        }
148        return update;
149      }
150    
151      public Date getDate() {
152        return date;
153      }
154    
155      public UpdateCenterMatrix setDate(Date d) {
156        this.date = d;
157        return this;
158      }
159    }