/*******************************************************************************
* Copyright (c) 2012 Pivotal Software, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springsource.ide.eclipse.commons.frameworks.core.internal.plugins;
import java.util.ArrayList;
import java.util.List;
/**
* Represents a published plugin model, which among other things,
* contains a list of published versions.
* <p>
* It specifies the latest version of the plugin as it would be installed IF the
* plugin were installed without specifying a version number. NOTE that this is
* NOT the same as being the most recent version of the plugin that is
* available. There may be newer milestone versions available OR newer versions
* that are only compatible with newer runtimes. Therefore this model provides two
* API for retrieving new versions:
* <li>
* The latest version available for the given version of a runtime used by a
* project. This is the version that is installed if a user installs the plugin
* WITHOUT specifying a version number.</li>
* <li>
* The most recent version added, which may be a milestone or only available for
* newer versions of a runtime, which a user must manually specify when installing
* the plugin. As the list of versions are ORDERED, the most recent version
* added version should be the last version that was added to the list.</li>
* </p>
* <p>
* This model represents both a published plugin as well as an in-place plugin.
* In-place plugins usually only have one child version (i.e the only version
* that is available), and this version is considered the latest version.
* </p>
*
* @author Nieraj Singh
* @author Andrew Eisenberg
*/
public class Plugin {
/**
* never null
*/
private List<PluginVersion> versions = new ArrayList<PluginVersion>();
private PluginVersion latestVersion;
private String name;
/**
* Default is always false, meaning when created it is assumed it is
* published
*/
private boolean isInplace = false;
public Plugin(String name) {
this.name = name;
}
/**
* Returns a COPY of an ORDERED list of versions, where the first entry is
* the oldest and the last the most recent. The last entry does NOT
* necessarily mean the version that will get install if the plugin were
* to be installed without specifying a version number. It just means the
* most recent version that is available for this plugin. The
* "latest version" (the version that installs when no version number
* is specified) may in fact be an older version than the most recent
* version that was added.
*
* @return all versions of this plugin, including new milestones. List is
* ordered, with the most recent entry being the last entry. Its
* never null, and should not be empty as a plugin has at least one
* version
*/
public List<PluginVersion> getVersions() {
return new ArrayList<PluginVersion>(versions);
}
/**
* Ordered addition of a version. If the version doesn't already exist and
* is not null, it is added at the end of the list and true is returned if
* successfully added.
* <p>
* Any version that is successfully added also has its parent set to this
* instance.
* </p>
*
* @param version
* to add to the end of the list. The version must correspond to
* the same plugin (i.e must have the same plugin name)
* @return true if successfully added. False otherwise
*/
public boolean addVersion(PluginVersion version) {
if (version != null && !versions.contains(version)
&& getName().equals(version.getName())) {
versions.add(version);
version.setParent(this);
return true;
}
return false;
}
public void removeVersion(PluginVersion version) {
versions.remove(version);
}
/**
* Gets the version model for the given ID, or null if not found
*
* @param versionID
* @return
*/
public PluginVersion getVersion(String versionID) {
if (versionID == null) {
return null;
}
for (PluginVersion version : getVersions()) {
if (versionID.equals(version.getVersion())) {
return version;
}
}
return null;
}
/**
*
* @return true if it is in place, false if it is published.
*/
public boolean isInPlace() {
return isInplace;
}
/**
* Set to true ONLY if this plugin has not been published.
*
* @param isInplace
* true if it is in-place, false if it is published
*/
public void setIsInPlace(boolean isInplace) {
this.isInplace = isInplace;
}
public boolean isInstalled() {
return getInstalled() != null;
}
public PluginVersion getInstalled() {
for (PluginVersion version : getVersions()) {
if (version.isInstalled()) {
return version;
}
}
return null;
}
/**
* Will set the latest version IF the latest version already exists in the
* list of version, OR if it does not exist, it is successfully added at the
* end of the list. Returns true if latest version successfully set. False
* otherwise.
* <p>
* Note that this CANNOT be null.
* </p>
*
* @param latestVersion
* latest released version
* @return true if successfully set, false otherwise
*/
public boolean setLatestReleasedVersion(PluginVersion latestVersion) {
if (versions.contains(latestVersion) || addVersion(latestVersion)) {
this.latestVersion = latestVersion;
//Note: it is possible that latestVersion was a 'duplicate' element. So although it
// is equals it may not be the same object. That means the parent could remain null
// unless we explicitly set it here. This causes NPE later on.
// See: STS-2490
this.latestVersion.setParent(this);
return true;
}
return false;
}
/**
* This may be different and more recent thatn the lastest released version
*
* @return the most recent version of the plugin that is available. This may
* OR may not be the same as the latest version available.
*/
public PluginVersion getMostRecentVersionAdded() {
List<PluginVersion> children = getVersions();
if (children != null && !children.isEmpty()) {
return children.get(children.size() - 1);
}
return null;
}
/**
* Gets the latest version of this plugin, but may NOT necessarily be the
* most recent version. The "latest version" is defined as the version
* that installs when NO version number is specified when installing the
* plugin. This version is set when this plugin model is first
* created , and is considered the "latest version" for the particular
* version of the runtime that a project is using, although newer versions may
* exist. This cannot be null.
*
* @return latest version. Should not be null.
*/
public PluginVersion getLatestReleasedVersion() {
return latestVersion;
}
/**
* Given a plugin, check if it is a version of this pluging. Return false if
* it is not a version of this plugin.
*
* @param pluginToCheck
* @return true if version. False otherwise.
*/
public boolean isVersion(PluginVersion pluginToCheck) {
if (pluginToCheck == null) {
return false;
}
String nameToCheck = pluginToCheck.getName();
String versionToCheck = pluginToCheck.getVersion();
List<PluginVersion> versions = getVersions();
if (versions != null && versionToCheck != null && nameToCheck != null
&& nameToCheck.equals(getName())) {
for (PluginVersion ver : versions) {
if (versionToCheck.equals(ver.getVersion())) {
return true;
}
}
}
return false;
}
public String getName() {
return name;
}
/**
* Determines whether an update exists for the installed version. The
* lastest version available is the version that installs when the
* install-plugin command is run without specifying a version number.
* However, this may not necessarily be the newest version, as newer
* milestone versions may exist, as well as versions that are only
* compatible with newer runtimes.
* <p>
* If a plugin is installed to the latest version, but newer milestone
* versions are available, this method returns false. It only returns true
* if the plugin is installed at an older version, but if the user were to
* run the install plugin command, a more recent released version would be
* installed instead.
* </p>
*
* @return true if and only if the plugin is installed and a newer released
* version exists. If the plugin is not installed or it is installed
* with the latest released version, this returns false.
*/
public boolean hasUpdate() {
// Should never be null
PluginVersion latestVersion = getLatestReleasedVersion();
PluginVersion installedVersion = getInstalled();
if (installedVersion == null) {
return false;
}
return isVersionHigher(latestVersion, installedVersion);
}
/**
* Checks if the first plugin is higher than the second plugin argument.
* False otherwise, including if one or the other or both arguments are
* null. True if and only if both version are NOT null and the first
* version is higher than the second.
*
* @param data1
* @param data2
* @return true if data1 is higher than data2
*/
public static boolean isVersionHigher(PluginVersion data1,
PluginVersion data2) {
String version1 = data1.getVersion();
String version2 = data2.getVersion();
if (version1 != null && version2 != null) {
return version1.compareToIgnoreCase(version2) > 0;
}
return false;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(name);
if (isInplace) {
sb.append(" (in-place)");
}
return sb.toString();
}
}