/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Icy is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.plugin;
import icy.common.Version;
import icy.file.FileUtil;
import icy.file.xml.XMLPersistent;
import icy.file.xml.XMLPersistentHelper;
import icy.image.ImageUtil;
import icy.network.NetworkUtil;
import icy.network.URLUtil;
import icy.plugin.abstract_.Plugin;
import icy.plugin.interface_.PluginBundled;
import icy.plugin.interface_.PluginImageAnalysis;
import icy.preferences.RepositoryPreferences.RepositoryInfo;
import icy.resource.ResourceUtil;
import icy.util.ClassUtil;
import icy.util.JarUtil;
import icy.util.StringUtil;
import icy.util.XMLUtil;
import java.awt.Image;
import java.net.URL;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import javax.swing.ImageIcon;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* <br>
* The plugin descriptor contains all the data needed to launch a plugin. <br>
*
* @see PluginLauncher
* @author Fabrice de Chaumont & Stephane
*/
public class PluginDescriptor implements XMLPersistent
{
public static final int ICON_SIZE = 64;
public static final int IMAGE_SIZE = 256;
public static final ImageIcon DEFAULT_ICON = ResourceUtil.getImageIcon(ResourceUtil.IMAGE_PLUGIN_SMALL);
public static final Image DEFAULT_IMAGE = ResourceUtil.IMAGE_PLUGIN;
/**
* @deprecated Use {@link PluginIdent#ID_CLASSNAME} instead
*/
@Deprecated
public static final String ID_CLASSNAME = PluginIdent.ID_CLASSNAME;
/**
* @deprecated Use {@link PluginIdent#ID_REQUIRED_KERNEL_VERSION} instead
*/
@Deprecated
public static final String ID_REQUIRED_KERNEL_VERSION = PluginIdent.ID_REQUIRED_KERNEL_VERSION;
public static final String ID_URL = "url";
public static final String ID_NAME = "name";
public static final String ID_JAR_URL = "jar_url";
public static final String ID_IMAGE_URL = "image_url";
public static final String ID_ICON_URL = "icon_url";
public static final String ID_AUTHOR = "author";
public static final String ID_CHANGELOG = "changelog";
public static final String ID_WEB = "web";
public static final String ID_EMAIL = "email";
public static final String ID_DESCRIPTION = "description";
public static final String ID_DEPENDENCIES = "dependencies";
public static final String ID_DEPENDENCY = "dependency";
protected Class<? extends Plugin> pluginClass;
protected ImageIcon icon;
protected Image image;
protected String name;
protected PluginIdent ident;
protected String xmlUrl;
protected String jarUrl;
protected String imageUrl;
protected String iconUrl;
protected String author;
protected String web;
protected String email;
protected String desc;
protected String changeLog;
protected boolean enabled;
protected boolean descriptorLoaded;
protected boolean iconLoaded;
protected boolean imageLoaded;
protected boolean changeLogLoaded;
// boolean checkingForUpdate;
// boolean updateChecked;
// PluginDescriptor onlineDescriptor;
// private final List<String> publicClasseNames;
protected final List<PluginIdent> required;
// only for online descriptor
protected RepositoryInfo repository;
// /**
// * Get online plugin of specified PluginIdent<br>
// * Take care of "allow beta" global flag<br>
// * This method can take sometime !<br>
// */
// public static PluginDescriptor getOnlinePlugin(PluginIdent ident, boolean loadImage)
// {
// PluginDescriptor betaDescriptor = null;
// PluginDescriptor stableDescriptor = null;
//
// try
// {
// // get beta online plugin descriptor if allowed
// if (PluginPreferences.getAllowBeta())
// betaDescriptor = new PluginDescriptor(ident.getUrlBeta(), loadImage);
// }
// catch (Exception e)
// {
// betaDescriptor = null;
// }
//
// try
// {
// // get stable online plugin descriptor
// stableDescriptor = new PluginDescriptor(ident.getUrlStable(), loadImage);
// }
// catch (Exception e)
// {
// stableDescriptor = null;
// }
//
// if ((betaDescriptor != null) && ((stableDescriptor == null) ||
// betaDescriptor.isNewerOrEqual(stableDescriptor)))
// return betaDescriptor;
//
// return stableDescriptor;
// }
/**
* Returns the index for the specified plugin in the specified list.<br>
* Returns -1 if not found.
*/
public static int getIndex(List<PluginDescriptor> list, PluginDescriptor plugin)
{
return getIndex(list, plugin.getIdent());
}
/**
* Returns the index for the specified plugin in the specified list.<br>
* Returns -1 if not found.
*/
public static int getIndex(List<PluginDescriptor> list, PluginIdent ident)
{
final int size = list.size();
for (int i = 0; i < size; i++)
if (list.get(i).getIdent().equals(ident))
return i;
return -1;
}
/**
* Returns the index for the specified plugin in the specified list.<br>
* Returns -1 if not found.
*/
public static int getIndex(List<PluginDescriptor> list, String className)
{
final int size = list.size();
for (int i = 0; i < size; i++)
if (list.get(i).getClassName().equals(className))
return i;
return -1;
}
/**
* Returns true if the specified plugin is present in the specified list.
*/
public static boolean existInList(List<PluginDescriptor> list, PluginDescriptor plugin)
{
return existInList(list, plugin.getIdent());
}
/**
* Returns true if the specified plugin is present in the specified list.
*/
public static boolean existInList(List<PluginDescriptor> list, PluginIdent ident)
{
return getIndex(list, ident) != -1;
}
/**
* Returns true if the specified plugin is present in the specified list.
*/
public static boolean existInList(List<PluginDescriptor> list, String className)
{
return getIndex(list, className) != -1;
}
public static boolean existInList(Set<PluginDescriptor> plugins, PluginIdent ident)
{
for (PluginDescriptor plugin : plugins)
if (plugin.getIdent().equals(ident))
return true;
return false;
}
public static void addToList(List<PluginDescriptor> list, PluginDescriptor plugin, int position)
{
if ((plugin != null) && !existInList(list, plugin))
list.add(position, plugin);
}
public static void addToList(List<PluginDescriptor> list, PluginDescriptor plugin)
{
if ((plugin != null) && !existInList(list, plugin))
list.add(plugin);
}
public static boolean removeFromList(List<PluginDescriptor> list, String className)
{
for (int i = list.size() - 1; i >= 0; i--)
{
final PluginDescriptor p = list.get(i);
if (p.getClassName().equals(className))
{
list.remove(i);
return true;
}
}
return false;
}
// public static String getPluginTypeString(int type)
// {
// if ((type >= 0) && (type < pluginTypeString.length))
// return pluginTypeString[type];
//
// return "";
// }
public static ArrayList<PluginDescriptor> getPlugins(List<PluginDescriptor> list, String className)
{
final ArrayList<PluginDescriptor> result = new ArrayList<PluginDescriptor>();
for (PluginDescriptor plugin : list)
if (plugin.getClassName().equals(className))
result.add(plugin);
return result;
}
public static PluginDescriptor getPlugin(List<PluginDescriptor> list, String className)
{
for (PluginDescriptor plugin : list)
if (plugin.getClassName().equals(className))
return plugin;
return null;
}
public static PluginDescriptor getPlugin(List<PluginDescriptor> list, PluginIdent ident, boolean acceptNewer)
{
if (acceptNewer)
{
for (PluginDescriptor plugin : list)
if (plugin.getIdent().isNewerOrEqual(ident))
return plugin;
}
else
{
for (PluginDescriptor plugin : list)
if (plugin.getIdent().equals(ident))
return plugin;
}
return null;
}
public PluginDescriptor()
{
super();
pluginClass = null;
icon = DEFAULT_ICON;
image = DEFAULT_IMAGE;
xmlUrl = "";
name = "";
ident = new PluginIdent();
jarUrl = "";
imageUrl = "";
iconUrl = "";
author = "";
web = "";
email = "";
desc = "";
changeLog = "";
required = new ArrayList<PluginIdent>();
repository = null;
// default
enabled = true;
descriptorLoaded = true;
changeLogLoaded = true;
iconLoaded = true;
imageLoaded = true;
}
/**
* Create from class, used for local plugin.
*/
public PluginDescriptor(Class<? extends Plugin> clazz)
{
this();
this.pluginClass = clazz;
final String baseResourceName = clazz.getSimpleName();
final String baseLocalName = ClassUtil.getPathFromQualifiedName(clazz.getName());
// load icon
URL iconUrl = clazz.getResource(baseResourceName + getIconExtension());
if (iconUrl == null)
iconUrl = URLUtil.getURL(baseLocalName + getIconExtension());
// loadIcon(url);
// load image
URL imageUrl = clazz.getResource(baseResourceName + getImageExtension());
if (imageUrl == null)
imageUrl = URLUtil.getURL(baseLocalName + getImageExtension());
// loadImage(url);
// load xml
URL xmlUrl = clazz.getResource(baseResourceName + getXMLExtension());
if (xmlUrl == null)
xmlUrl = URLUtil.getURL(baseLocalName + getXMLExtension());
// can't load XML from specified URL ?
if (!loadFromXML(xmlUrl))
{
// xml is absent or incorrect, we set default informations
ident.setClassName(pluginClass.getName());
name = pluginClass.getSimpleName();
desc = name + " plugin";
}
// overwrite image and icon url with their local equivalent (keep online for XML url)
this.iconUrl = iconUrl.toString();
this.imageUrl = imageUrl.toString();
// only descriptor is loaded here
descriptorLoaded = true;
changeLogLoaded = false;
iconLoaded = false;
imageLoaded = false;
}
/**
* Create from plugin online identifier, used for online plugin only.
*
* @throws IllegalArgumentException
*/
public PluginDescriptor(PluginOnlineIdent ident, RepositoryInfo repos) throws IllegalArgumentException
{
this();
this.ident.setClassName(ident.getClassName());
this.ident.setVersion(ident.getVersion());
this.ident.setRequiredKernelVersion(ident.getRequiredKernelVersion());
this.xmlUrl = ident.getUrl();
this.name = ident.getName();
this.repository = repos;
// mark descriptor and images as not yet loaded
descriptorLoaded = false;
changeLogLoaded = false;
iconLoaded = false;
imageLoaded = false;
}
/**
* @deprecated Use {@link #loadDescriptor()} or {@link #loadAll()} instead
*/
@Deprecated
public boolean load(boolean loadImages)
{
if (loadDescriptor())
{
loadChangeLog();
if (loadImages)
return loadImages();
}
return false;
}
/**
* Load descriptor informations (xmlUrl field should be correctly filled)
*/
public boolean loadDescriptor()
{
return loadDescriptor(false);
}
/**
* Load descriptor informations (xmlUrl field should be correctly filled).<br>
* Returns <code>false</code> if the operation failed.
*/
public boolean loadDescriptor(boolean reload)
{
// already loaded ?
if (descriptorLoaded && !reload)
return true;
// just to avoid retry indefinitely if it fails
descriptorLoaded = true;
// retrieve document
final Document document = XMLUtil.loadDocument(xmlUrl,
(repository != null) ? repository.getAuthenticationInfo() : null, true);
if (document != null)
{
// load xml
if (!loadFromXML(document.getDocumentElement()))
{
System.err.println("Can't find valid XML file from '" + xmlUrl + "' for plugin class '"
+ ident.getClassName() + "'");
return false;
}
return true;
}
// display error only for first load
if (!reload)
System.err.println("Can't load XML file from '" + xmlUrl + "' for plugin class '" + ident.getClassName()
+ "'");
return false;
}
/**
* Load change log field (xmlUrl field should be correctly filled)
*/
public boolean loadChangeLog()
{
// already loaded ?
if (changeLogLoaded)
return true;
// just to avoid retry indefinitely if it fails
changeLogLoaded = true;
// retrieve document
final Document document = XMLUtil.loadDocument(xmlUrl,
(repository != null) ? repository.getAuthenticationInfo() : null, true);
if (document != null)
{
final Element node = document.getDocumentElement();
if (node != null)
{
setChangeLog(XMLUtil.getElementValue(node, ID_CHANGELOG, ""));
return true;
}
System.err.println("Can't find valid XML file from '" + xmlUrl + "' for plugin class '"
+ ident.getClassName() + "'");
}
System.err.println("Can't load XML file from '" + xmlUrl + "' for plugin class '" + ident.getClassName() + "'");
return false;
}
/**
* Load 64x64 icon (icon url field should be correctly filled)
*/
public boolean loadIcon()
{
// already loaded ?
if (iconLoaded)
return true;
// need descriptor to be loaded first
loadDescriptor();
// just to avoid retry indefinitely if it fails
iconLoaded = true;
// load icon
return loadIcon(URLUtil.getURL(iconUrl));
}
/**
* Load 256x256 image (image url field should be correctly filled)
*/
public boolean loadImage()
{
// already loaded ?
if (imageLoaded)
return true;
// need descriptor to be loaded first
loadDescriptor();
// just to avoid retry indefinitely if it fails
imageLoaded = true;
// load image
return loadImage(URLUtil.getURL(imageUrl));
}
/**
* Load icon and image (both icon and image url fields should be correctly filled)
*/
public boolean loadImages()
{
return loadIcon() & loadImage();
}
/**
* Load descriptor and images if not already done
*/
public boolean loadAll()
{
return loadDescriptor() & loadChangeLog() & loadImages();
}
/**
* Check if the plugin class is an instance of (or subclass of) the specified class.
*/
public boolean isInstanceOf(Class<?> baseClazz)
{
return ClassUtil.isSubClass(pluginClass, baseClazz);
}
/**
* Return true if the plugin class is abstract
*/
public boolean isAbstract()
{
return ClassUtil.isAbstract(pluginClass);
}
/**
* Return true if the plugin class is private
*/
public boolean isPrivate()
{
return ClassUtil.isPrivate(pluginClass);
}
/**
* Return true if the plugin class is an interface
*/
public boolean isInterface()
{
return pluginClass.isInterface();
}
/**
* return true if the plugin has an action which can be started from menu
*/
public boolean isActionable()
{
return isClassLoaded() && !isPrivate() && !isAbstract() && !isInterface()
&& isInstanceOf(PluginImageAnalysis.class);
}
/**
* Return true if the plugin is bundled inside another plugin (mean it does not have a proper
* descriptor)
*/
public boolean isBundled()
{
return isClassLoaded() && isInstanceOf(PluginBundled.class);
}
/**
* Return true if the plugin is in beta state
*/
public boolean isBeta()
{
return getVersion().isBeta();
}
/**
* Return true if this plugin is a system application plugin (declared in plugins.kernel
* package).
*/
public boolean isKernelPlugin()
{
return getClassName().startsWith(PluginLoader.PLUGIN_KERNEL_PACKAGE + ".");
}
boolean loadIcon(URL url)
{
// load icon
if (url != null)
icon = ResourceUtil.getImageIcon(
ImageUtil.load(NetworkUtil.getInputStream(url,
(repository != null) ? repository.getAuthenticationInfo() : null, true, false), false),
ICON_SIZE);
// get default icon
if (icon == null)
{
icon = DEFAULT_ICON;
return false;
}
return true;
}
boolean loadImage(URL url)
{
// load image
if (url != null)
image = ImageUtil.scale(
ImageUtil.load(NetworkUtil.getInputStream(url,
(repository != null) ? repository.getAuthenticationInfo() : null, true, false), false),
IMAGE_SIZE, IMAGE_SIZE);
// get default image
if (image == null)
{
image = DEFAULT_IMAGE;
return false;
}
return true;
}
// public void save()
// {
// // save icon
// if (icon != null)
// ImageUtil.saveImage(ImageUtil.toRenderedImage(icon.getImage()), "png", getIconFilename());
// // save image
// if (image != null)
// ImageUtil.saveImage(ImageUtil.toRenderedImage(image), "png", getImageFilename());
// // save xml
// saveToXML();
// }
public boolean loadFromXML(String path)
{
return XMLPersistentHelper.loadFromXML(this, path);
}
public boolean loadFromXML(URL xmlUrl)
{
return XMLPersistentHelper.loadFromXML(this, xmlUrl);
}
@Override
public boolean loadFromXML(Node node)
{
return loadFromXML(node, false);
}
public boolean loadFromXML(Node node, boolean loadChangeLog)
{
if (node == null)
return false;
// get the plugin ident
ident.loadFromXML(node);
setName(XMLUtil.getElementValue(node, ID_NAME, ""));
setXmlUrl(XMLUtil.getElementValue(node, ID_URL, ""));
setJarUrl(XMLUtil.getElementValue(node, ID_JAR_URL, ""));
setImageUrl(XMLUtil.getElementValue(node, ID_IMAGE_URL, ""));
setIconUrl(XMLUtil.getElementValue(node, ID_ICON_URL, ""));
setAuthor(XMLUtil.getElementValue(node, ID_AUTHOR, ""));
setWeb(XMLUtil.getElementValue(node, ID_WEB, ""));
setEmail(XMLUtil.getElementValue(node, ID_EMAIL, ""));
setDescription(XMLUtil.getElementValue(node, ID_DESCRIPTION, ""));
if (loadChangeLog)
setChangeLog(XMLUtil.getElementValue(node, ID_CHANGELOG, ""));
else
setChangeLog("");
final Node nodeDependances = XMLUtil.getElement(node, ID_DEPENDENCIES);
if (nodeDependances != null)
{
final ArrayList<Node> nodesDependances = XMLUtil.getChildren(nodeDependances, ID_DEPENDENCY);
for (Node n : nodesDependances)
{
final PluginIdent ident = new PluginIdent();
// required don't need URL information as we now search from classname
ident.loadFromXML(n);
if (!ident.isEmpty())
required.add(ident);
}
}
return true;
}
public boolean saveToXML()
{
return XMLPersistentHelper.saveToXML(this, getXMLFilename());
}
@Override
public boolean saveToXML(Node node)
{
if (node == null)
return false;
ident.saveToXML(node);
XMLUtil.setElementValue(node, ID_NAME, getName());
XMLUtil.setElementValue(node, ID_URL, getXmlUrl());
XMLUtil.setElementValue(node, ID_JAR_URL, getJarUrl());
XMLUtil.setElementValue(node, ID_IMAGE_URL, getImageUrl());
XMLUtil.setElementValue(node, ID_ICON_URL, getIconUrl());
XMLUtil.setElementValue(node, ID_AUTHOR, getAuthor());
XMLUtil.setElementValue(node, ID_WEB, getWeb());
XMLUtil.setElementValue(node, ID_EMAIL, getEmail());
XMLUtil.setElementValue(node, ID_DESCRIPTION, getDescription());
loadChangeLog();
XMLUtil.setElementValue(node, ID_CHANGELOG, getChangeLog());
// synchronized (dateFormatter)
// {
// XMLUtil.addChildElement(root, ID_INSTALL_DATE, dateFormatter.format(installed));
// XMLUtil.addChildElement(root, ID_LASTUSE_DATE, dateFormatter.format(lastUse));
// }
// final Element publicClasses = XMLUtil.setElement(node, ID_PUBLIC_CLASSES);
// if (publicClasses != null)
// {
// XMLUtil.removeAllChilds(publicClasses);
// for (String className : publicClasseNames)
// XMLUtil.addValue(XMLUtil.addElement(publicClasses, ID_CLASSNAME), className);
// }
final Element dependances = XMLUtil.setElement(node, ID_DEPENDENCIES);
if (dependances != null)
{
XMLUtil.removeAllChildren(dependances);
for (PluginIdent dep : required)
dep.saveToXML(XMLUtil.addElement(dependances, ID_DEPENDENCY));
}
return true;
}
public boolean isClassLoaded()
{
return pluginClass != null;
}
/**
* Returns the plugin class name.<br>
* Ex: "plugins.tutorial.Example1"
*/
public String getClassName()
{
return ident.getClassName();
}
public String getSimpleClassName()
{
return ident.getSimpleClassName();
}
/**
* Returns the package name of the plugin class.
*/
public String getPackageName()
{
return ident.getPackageName();
}
/**
* Returns the minimum package name (remove "icy" or/and "plugin" header)<br>
*/
public String getSimplePackageName()
{
return ident.getSimplePackageName();
}
/**
* Returns the author package name (first part of simple package name)
*/
public String getAuthorPackageName()
{
return ident.getAuthorPackageName();
}
/**
* @deprecated useless method
*/
@Deprecated
public String getClassAsString()
{
if (pluginClass != null)
return pluginClass.toString();
return "";
}
/**
* @return the pluginClass
*/
public Class<? extends Plugin> getPluginClass()
{
return pluginClass;
}
/**
* return associated filename
*/
public String getFilename()
{
return ClassUtil.getPathFromQualifiedName(getClassName());
}
/**
* Returns the XML file extension.
*/
public String getXMLExtension()
{
return XMLUtil.FILE_DOT_EXTENSION;
}
/**
* return xml filename
*/
public String getXMLFilename()
{
return getFilename() + getXMLExtension();
}
/**
* return icon extension
*/
public String getIconExtension()
{
return "_icon.png";
}
/**
* return icon filename
*/
public String getIconFilename()
{
return getFilename() + getIconExtension();
}
/**
* return image extension
*/
public String getImageExtension()
{
return ".png";
}
/**
* return image filename
*/
public String getImageFilename()
{
return getFilename() + getImageExtension();
}
/**
* Returns the JAR file extension.
*/
public String getJarExtension()
{
return JarUtil.FILE_DOT_EXTENSION;
}
/**
* return jar filename
*/
public String getJarFilename()
{
return getFilename() + getJarExtension();
}
/**
* @return the icon
*/
public ImageIcon getIcon()
{
loadIcon();
return icon;
}
/**
* @return the icon as image
*/
public Image getIconAsImage()
{
final ImageIcon i = getIcon();
if (i != null)
return i.getImage();
return null;
}
/**
* @return the image
*/
public Image getImage()
{
loadImage();
return image;
}
// /**
// * @return the lastUse
// */
// public Date getLastUse()
// {
// return lastUse;
// }
//
// /**
// * @param lastUse
// * the lastUse to set
// */
// public void setLastUse(Date lastUse)
// {
// this.lastUse = lastUse;
// }
/**
* @return the ident
*/
public PluginIdent getIdent()
{
return ident;
}
/**
* @return the name
*/
public String getName()
{
return name;
}
/**
* @return the version
*/
public Version getVersion()
{
if (ident != null)
return ident.getVersion();
return new Version();
}
// /**
// * @return the url for current version
// */
// public String getUrlCurrent()
// {
// if (ident != null)
// {
// final Version ver = ident.getVersion();
//
// if (ver.isBeta())
// return ident.getUrlBeta();
//
// return ident.getUrlStable();
// }
//
// return "";
// }
/**
* @return the url
*/
public String getUrl()
{
// url is default XML url
return getXmlUrl();
}
/**
* @return the url for xml file
*/
public String getXmlUrl()
{
return xmlUrl;
}
/**
* @return the desc
* @deprecated use {@link #getDescription()} instead
*/
@Deprecated
public String getDesc()
{
return getDescription();
}
/**
* @return the description
*/
public String getDescription()
{
return desc;
}
/**
* @param xmlUrl
* the xmlUrl to set
*/
public void setXmlUrl(String xmlUrl)
{
this.xmlUrl = xmlUrl;
}
/**
* @param repository
* the repository to set
*/
public void setRepository(RepositoryInfo repository)
{
this.repository = repository;
}
/**
* @return the jarUrl
*/
public String getJarUrl()
{
return jarUrl;
}
/**
* @param jarUrl
* the jarUrl to set
*/
public void setJarUrl(String jarUrl)
{
this.jarUrl = jarUrl;
}
/**
* @return the imageUrl
*/
public String getImageUrl()
{
return imageUrl;
}
/**
* @param imageUrl
* the imageUrl to set
*/
public void setImageUrl(String imageUrl)
{
this.imageUrl = imageUrl;
}
/**
* @return the iconUrl
*/
public String getIconUrl()
{
return iconUrl;
}
/**
* @param iconUrl
* the iconUrl to set
*/
public void setIconUrl(String iconUrl)
{
this.iconUrl = iconUrl;
}
/**
* Returns the author's plugin name.
*/
public String getAuthor()
{
return author;
}
/**
* Returns the website url of this plugin.
*/
public String getWeb()
{
return web;
}
/**
* @return the email
*/
public String getEmail()
{
return email;
}
/**
* @return the changeLog
*/
public String getChangeLog()
{
return changeLog;
}
/**
* @deprecated Use {@link #getChangeLog()} instead
*/
@Deprecated
public String getChangesLog()
{
return getChangeLog();
}
/**
* @return the requiredKernelVersion
*/
public Version getRequiredKernelVersion()
{
return ident.getRequiredKernelVersion();
}
/**
* Returns true if descriptor is loaded.
*/
public boolean isDescriptorLoaded()
{
return descriptorLoaded;
}
/**
* @deprecated Use {@link #isDescriptorLoaded()} instead
*/
@Deprecated
public boolean isLoaded()
{
return descriptorLoaded;
}
/**
* Returns true if change log is loaded.
*/
public boolean isChangeLogLoaded()
{
return changeLogLoaded;
}
/**
* Returns true if icon is loaded.
*/
public boolean isIconLoaded()
{
return iconLoaded;
}
/**
* Returns true if image is loaded.
*/
public boolean isImageLoaded()
{
return imageLoaded;
}
/**
* Returns true if image and icon are loaded.
*/
public boolean isImagesLoaded()
{
return iconLoaded && imageLoaded;
}
/**
* Returns true if both descriptor and images are loaded.
*/
public boolean isAllLoaded()
{
return descriptorLoaded && changeLogLoaded && iconLoaded && imageLoaded;
}
/**
* @return the required
*/
public List<PluginIdent> getRequired()
{
return new ArrayList<PluginIdent>(required);
}
public RepositoryInfo getRepository()
{
return repository;
}
/**
* @return the enabled
*/
public boolean isEnabled()
{
return enabled;
}
/**
* @param enabled
* the enabled to set
*/
public void setEnabled(boolean enabled)
{
this.enabled = enabled;
}
/**
* Return true if plugin is installed (corresponding JAR file exist)
*/
public boolean isInstalled()
{
return FileUtil.exists(getJarFilename());
}
// /**
// * @return the hasUpdate
// */
// public boolean getHasUpdate()
// {
// // true if online version > local version
// return (onlineDescriptor != null) && onlineDescriptor.getVersion().isGreater(getVersion());
// }
//
// /**
// * @return the checkingForUpdate
// */
// public boolean isCheckingForUpdate()
// {
// return checkingForUpdate;
// }
//
// /**
// * @return the onlineDescriptor
// */
// public PluginDescriptor getOnlineDescriptor()
// {
// return onlineDescriptor;
// }
// /**
// * @return the updateChecked
// */
// public boolean isUpdateChecked()
// {
// return updateChecked;
// }
//
// /**
// * check for update (asynchronous as it can take sometime)
// */
// public void checkForUpdate()
// {
// if (updateChecked)
// return;
//
// checkingForUpdate = true;
//
// ThreadUtil.bgRunWait(new Runnable()
// {
// @Override
// public void run()
// {
// try
// {
// onlineDescriptor = getOnlinePlugin(getIdent(), false);
// }
// catch (Exception E)
// {
// onlineDescriptor = null;
// }
// finally
// {
// checkingForUpdate = false;
// updateChecked = true;
// }
// }
// });
// }
/**
* @param name
* the name to set
*/
public void setName(String name)
{
this.name = name;
}
/**
* @param author
* the author to set
*/
public void setAuthor(String author)
{
this.author = author;
}
/**
* @param web
* the web to set
*/
public void setWeb(String web)
{
this.web = web;
}
/**
* @param email
* the email to set
*/
public void setEmail(String email)
{
this.email = email;
}
/**
* @param desc
* the description to set
*/
public void setDescription(String desc)
{
this.desc = desc;
}
/**
* @param value
* the changeLog to set
*/
public void setChangeLog(String value)
{
this.changeLog = value;
}
/**
* @deprecated use {@link #setChangeLog(String)}
*/
@Deprecated
public void setChangesLog(String value)
{
setChangeLog(value);
}
/**
* Return true if specified plugin is required by current plugin
*/
public boolean requires(PluginDescriptor plugin)
{
final PluginIdent curIdent = plugin.getIdent();
for (PluginIdent ident : required)
if (ident.isOlderOrEqual(curIdent))
return true;
return false;
}
public boolean isOlderOrEqual(PluginDescriptor plugin)
{
return ident.isOlderOrEqual(plugin.getIdent());
}
public boolean isOlder(PluginDescriptor plugin)
{
return ident.isOlder(plugin.getIdent());
}
public boolean isNewerOrEqual(PluginDescriptor plugin)
{
return ident.isNewerOrEqual(plugin.getIdent());
}
public boolean isNewer(PluginDescriptor plugin)
{
return ident.isNewer(plugin.getIdent());
}
@Override
public String toString()
{
return getName() + " " + getVersion().toString();
}
@Override
public boolean equals(Object obj)
{
if (obj instanceof PluginDescriptor)
{
final PluginDescriptor plug = (PluginDescriptor) obj;
return getClassName().equals(plug.getClassName()) && getVersion().equals(plug.getVersion());
}
return super.equals(obj);
}
@Override
public int hashCode()
{
return getClassName().hashCode() ^ getVersion().hashCode();
}
public static class PluginIdent implements XMLPersistent
{
/**
* Returns the index for the specified plugin ident in the specified list.<br>
* Returns -1 if not found.
*/
public static int getIndex(List<PluginIdent> list, PluginIdent ident)
{
final int size = list.size();
for (int i = 0; i < size; i++)
if (list.get(i).equals(ident))
return i;
return -1;
}
/**
* Returns the index for the specified plugin in the specified list.<br>
* Returns -1 if not found.
*/
public static int getIndex(List<? extends PluginIdent> list, String className)
{
final int size = list.size();
for (int i = 0; i < size; i++)
if (list.get(i).getClassName().equals(className))
return i;
return -1;
}
public static final String ID_CLASSNAME = "classname";
public static final String ID_VERSION = "version";
public static final String ID_REQUIRED_KERNEL_VERSION = "required_kernel_version";
protected String className;
protected Version version;
protected Version requiredKernelVersion;
/**
*
*/
public PluginIdent()
{
super();
// default
className = "";
version = new Version();
requiredKernelVersion = new Version();
}
public boolean loadFromXMLShort(Node node)
{
if (node == null)
return false;
setClassName(XMLUtil.getElementValue(node, ID_CLASSNAME, ""));
setVersion(new Version(XMLUtil.getElementValue(node, ID_VERSION, "")));
return true;
}
@Override
public boolean loadFromXML(Node node)
{
if (!loadFromXMLShort(node))
return false;
setRequiredKernelVersion(new Version(XMLUtil.getElementValue(node, ID_REQUIRED_KERNEL_VERSION, "")));
return true;
}
public boolean saveToXMLShort(Node node)
{
if (node == null)
return false;
XMLUtil.setElementValue(node, ID_CLASSNAME, getClassName());
XMLUtil.setElementValue(node, ID_VERSION, getVersion().toString());
return true;
}
@Override
public boolean saveToXML(Node node)
{
if (!saveToXMLShort(node))
return false;
XMLUtil.setElementValue(node, ID_REQUIRED_KERNEL_VERSION, getRequiredKernelVersion().toString());
return true;
}
public boolean isEmpty()
{
return StringUtil.isEmpty(className) && version.isEmpty() && requiredKernelVersion.isEmpty();
}
/**
* @return the className
*/
public String getClassName()
{
return className;
}
/**
* @param className
* the className to set
*/
public void setClassName(String className)
{
this.className = className;
}
/**
* return the simple className
*/
public String getSimpleClassName()
{
return ClassUtil.getSimpleClassName(className);
}
/**
* return the package name
*/
public String getPackageName()
{
return ClassUtil.getPackageName(className);
}
/**
* return the minimum package name (remove "icy" or/and "plugin" header)<br>
*/
public String getSimplePackageName()
{
String result = getPackageName();
if (result.startsWith("icy."))
result = result.substring(4);
if (result.startsWith(PluginLoader.PLUGIN_PACKAGE))
result = result.substring(PluginLoader.PLUGIN_PACKAGE.length() + 1);
return result;
}
/**
* return the author package name (first part of simple package name)
*/
public String getAuthorPackageName()
{
final String result = getSimplePackageName();
final int index = result.indexOf('.');
if (index != -1)
return result.substring(0, index);
return result;
}
/**
* @param version
* the version to set
*/
public void setVersion(Version version)
{
this.version = version;
}
/**
* @return the version
*/
public Version getVersion()
{
return version;
}
/**
* @return the requiredKernelVersion
*/
public Version getRequiredKernelVersion()
{
return requiredKernelVersion;
}
/**
* @param requiredKernelVersion
* the requiredKernelVersion to set
*/
public void setRequiredKernelVersion(Version requiredKernelVersion)
{
this.requiredKernelVersion = requiredKernelVersion;
}
public boolean isOlderOrEqual(PluginIdent ident)
{
return className.equals(ident.getClassName()) && version.isOlderOrEqual(ident.getVersion());
}
public boolean isOlder(PluginIdent ident)
{
return className.equals(ident.getClassName()) && version.isOlder(ident.getVersion());
}
public boolean isNewerOrEqual(PluginIdent ident)
{
return className.equals(ident.getClassName()) && version.isNewerOrEqual(ident.getVersion());
}
public boolean isNewer(PluginIdent ident)
{
return className.equals(ident.getClassName()) && version.isNewer(ident.getVersion());
}
@Override
public boolean equals(Object obj)
{
if (obj instanceof PluginIdent)
{
final PluginIdent ident = (PluginIdent) obj;
return ident.getClassName().equals(className) && ident.getVersion().equals(getVersion());
}
return super.equals(obj);
}
@Override
public int hashCode()
{
return className.hashCode() ^ version.hashCode();
}
@Override
public String toString()
{
return className + " " + version.toString();
}
}
public static class PluginOnlineIdent extends PluginIdent
{
protected String name;
protected String url;
public PluginOnlineIdent()
{
super();
name = "";
url = "";
}
/**
* @return the name
*/
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
/**
* @return the url
*/
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
@Override
public boolean loadFromXML(Node node)
{
if (super.loadFromXML(node))
{
setName(XMLUtil.getElementValue(node, PluginDescriptor.ID_NAME, ""));
setUrl(XMLUtil.getElementValue(node, PluginDescriptor.ID_URL, ""));
return true;
}
return false;
}
@Override
public boolean saveToXML(Node node)
{
if (super.saveToXML(node))
{
XMLUtil.setElementValue(node, PluginDescriptor.ID_NAME, getName());
XMLUtil.setElementValue(node, PluginDescriptor.ID_URL, getUrl());
return true;
}
return false;
}
}
/**
* Sort plugins on name with kernel plugins appearing first.
*/
public static class PluginKernelNameSorter implements Comparator<PluginDescriptor>
{
// static class
public static PluginKernelNameSorter instance = new PluginKernelNameSorter();
// static class
private PluginKernelNameSorter()
{
super();
}
@Override
public int compare(PluginDescriptor o1, PluginDescriptor o2)
{
final String packageName1 = o1.getPackageName();
final String packageName2 = o2.getPackageName();
if (packageName1.startsWith(PluginLoader.PLUGIN_KERNEL_PACKAGE))
{
if (!packageName2.startsWith(PluginLoader.PLUGIN_KERNEL_PACKAGE))
return -1;
}
else if (packageName2.startsWith(PluginLoader.PLUGIN_KERNEL_PACKAGE))
return 1;
return o1.toString().compareToIgnoreCase(o2.toString());
}
}
/**
* Sort plugins on name.
*/
public static class PluginNameSorter implements Comparator<PluginDescriptor>
{
// static class
public static PluginNameSorter instance = new PluginNameSorter();
// static class
private PluginNameSorter()
{
super();
}
@Override
public int compare(PluginDescriptor o1, PluginDescriptor o2)
{
return o1.toString().compareToIgnoreCase(o2.toString());
}
}
/**
* Sort plugins on class name.
*/
public static class PluginClassNameSorter implements Comparator<PluginDescriptor>
{
// static class
public static PluginClassNameSorter instance = new PluginClassNameSorter();
// static class
private PluginClassNameSorter()
{
super();
}
@Override
public int compare(PluginDescriptor o1, PluginDescriptor o2)
{
return o1.getClassName().compareToIgnoreCase(o2.getClassName());
}
}
}