001/*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 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 */
020package org.sonar.server.plugins;
021
022import com.google.common.collect.Lists;
023import com.google.common.collect.Maps;
024import org.sonar.updatecenter.common.*;
025
026import java.util.Date;
027import java.util.List;
028import java.util.Map;
029import java.util.SortedSet;
030
031public 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}