/* * 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()); } } }