/*******************************************************************************
* Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
*
* This file is part of the OpenWGA server platform.
*
* OpenWGA 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.
*
* In addition, a special exception is granted by the copyright holders
* of OpenWGA called "OpenWGA plugin exception". You should have received
* a copy of this exception along with OpenWGA in file COPYING.
* If not, see <http://www.openwga.com/gpl-plugin-exception>.
*
* OpenWGA 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 OpenWGA in file COPYING.
* If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package de.innovationgate.wgpublisher.plugins;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.vfs.FileSystemException;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.Dom4JDriver;
import com.thoughtworks.xstream.io.xml.DomDriver;
import de.innovationgate.utils.MD5HashingInputStream;
import de.innovationgate.utils.MD5HashingOutputStream;
import de.innovationgate.utils.WGUtils;
import de.innovationgate.utils.XStreamUtils;
import de.innovationgate.webgate.api.WGDatabase;
import de.innovationgate.webgate.api.WGIllegalArgumentException;
import de.innovationgate.webgate.api.WGIllegalStateException;
import de.innovationgate.wga.common.beans.csconfig.v1.PluginConfig;
import de.innovationgate.wga.common.beans.csconfig.v1.PluginID;
import de.innovationgate.wga.common.beans.csconfig.v1.Version;
import de.innovationgate.wgpublisher.WGACore;
import de.innovationgate.wgpublisher.WGAVersion;
import de.innovationgate.wgpublisher.plugins.WGAPlugin.InitialisationFault;
public class WGAPluginSet {
public static transient final int UPDATESTRATEGY_UPDATE_KEEP_DATA = 1;
public static transient final int UPDATESTRATEGY_INSTALL_IN_PARALLEL = 2;
public static class RuntimeContext {
private boolean _reconnect = false;
private boolean _updated = false;
public boolean isReconnect() {
return _reconnect;
}
public void setReconnect(boolean reconnect) {
_reconnect = reconnect;
}
public boolean isUpdated() {
return _updated;
}
public void setUpdated(boolean updated) {
_updated = updated;
}
}
private static final XStream XSTREAM = new XStream(new Dom4JDriver());
static {
XSTREAM.alias("WGAPluginSet", WGAPluginSet.class);
XSTREAM.alias("WGAPlugin", WGAPlugin.class);
}
public static WGAPluginSet load(File file) throws IOException, NoSuchAlgorithmException {
FileInputStream in = new FileInputStream(file);
MD5HashingInputStream hashIn = new MD5HashingInputStream(in);
WGAPluginSet set = (WGAPluginSet) XStreamUtils.loadUtf8FromInputStream(XSTREAM, hashIn);
set._hash = hashIn.getHash();
return set;
}
public void save(File file) throws IOException, WGIllegalStateException, NoSuchAlgorithmException {
if (_workspaceSet) {
throw new WGIllegalStateException("You cannot save a workspace plugin set");
}
// Write first to ByteArrayOutputStream and create hash to see if it changed
ByteArrayOutputStream out = new ByteArrayOutputStream();
MD5HashingOutputStream hashOut = new MD5HashingOutputStream(out);
XStreamUtils.writeUtf8ToOutputStream(this, XSTREAM, hashOut);
// Only write if the hash differs
String newHash = hashOut.getHash();
if (!newHash.equals(_hash)) {
FileOutputStream fileOut = new FileOutputStream(file);
fileOut.write(out.toByteArray());
fileOut.close();
_hash = newHash;
}
}
public void save() throws WGIllegalStateException, IOException, NoSuchAlgorithmException {
File file = new File(_pluginsDir, "plugins.xml");
save(file);
}
private Set<WGAPlugin> _plugins = new LinkedHashSet<WGAPlugin>();
private Set<WGAPlugin> _workspacePlugins = new HashSet<WGAPlugin>();
private transient Map<String,WGAPlugin> _activePluginsByUniqueName;
private transient Map<String,WGAPlugin> _pluginsByInstallationKey;
private transient File _pluginsDir;
private transient File _pluginFilesDir;
private transient WGACore _core;
private transient File _pluginDBsDir;
private transient File _pluginWorkspaceDir;
private transient boolean _workspaceSet;
private transient String _hash;
private transient Map<PluginID,RuntimeContext> _runtimeContexts;
public Map<String,WGAPlugin> getActivePluginsByUniqueName() {
return _activePluginsByUniqueName;
}
public void validatePlugins() {
boolean validityChanged;
// If a plugin was determined to be invalid, we must re-evaluate everything to find
// dependent plugins that now are invalid too. So we loop over the whole process until validity does not change anymore.
do {
validityChanged = false;
// Validate plugins and build dependency tree
Iterator pluginsIt = _pluginsByInstallationKey.values().iterator();
while (pluginsIt.hasNext()) {
WGAPlugin plugin = (WGAPlugin) pluginsIt.next();
// If already marked invalid or inactive we end here
if (plugin.isActive() == false || plugin.isValid() == false) {
continue;
}
try {
plugin.validate();
}
catch (InvalidPluginException e) {
plugin.addInstallationFault(plugin.new InitialisationFault(e.getMessage()));
}
// WGA Version
Version wgaVersion = WGAVersion.toCsConfigVersion();
int comp = wgaVersion.compareTo(plugin.getCsConfig().getPluginConfig().getMinimumWGAVersion());
if (comp < 0) {
plugin.addInstallationFault(plugin.new InstallationFault(WGAPlugin.InstallationFault.ERROR_WRONG_WGA_VERSION));
}
// Java Version
Version javaVersion = Version.getJavaVersion();
comp = javaVersion.compareTo(plugin.getCsConfig().getPluginConfig().getMinimumJavaVersion());
if (comp < 0) {
plugin.addInstallationFault(plugin.new InstallationFault(WGAPlugin.InstallationFault.ERROR_WRONG_JAVA_VERSION));
}
// Dependencies
plugin.checkDependencies();
// Check faults
if (plugin.getInstallationFaults().size() > 0) {
plugin.setValid(false);
validityChanged = true;
if (!_workspaceSet) {
_core.getLog().warn("Invalid WGA Plugin " + plugin.getPluginID().getUniqueName() + ":");
for (Iterator iter = plugin.getInstallationFaults().iterator(); iter.hasNext();) {
WGAPlugin.InstallationFault fault = (WGAPlugin.InstallationFault) iter.next();
_core.getLog().error("- " + fault.toErrorMessage());
}
}
}
}
} while (validityChanged == true);
}
public Set<String> connectPlugins(Map domainConfig) throws WGIllegalArgumentException, FileSystemException, IOException {
// Disconnect inactive/invalid plugins
Iterator pluginsIt = _plugins.iterator();
while (pluginsIt.hasNext()) {
WGAPlugin plugin = (WGAPlugin) pluginsIt.next();
if (plugin.getInstallationKey() != null && (!plugin.isActive() || !plugin.isValid() || plugin.isReconnectDatabase())) {
_core.disconnectPlugin(plugin);
plugin.setReconnectDatabase(false);
if (!plugin.isActive()) {
removePluginFromMaps(plugin, false);
plugin.setInstallationKey(null);
}
}
}
// Connect active plugins
Set<String> pluginsDBs = new HashSet<String>();
pluginsIt = _pluginsByInstallationKey.values().iterator();
while (pluginsIt.hasNext()) {
WGAPlugin plugin = (WGAPlugin) pluginsIt.next();
WGDatabase db = null;
if (plugin.isActive() && plugin.isValid()) {
try {
db = _core.connectPlugin(plugin, domainConfig);
}
catch (InvalidPluginException e) {
if (e.getPlugin() == plugin) {
_core.getLog().error("Unable to connect plugin " + plugin.getPluginID().getUniqueName());
}
else {
_core.getLog().error("Unable to connect plugin " + plugin.getPluginID().getUniqueName() + " because of dependency plugin " + e.getPlugin().getPluginID().getUniqueName());
}
_core.getLog().error(e.getMessage(), e.getCause());
}
if (db == null) {
continue;
}
// db can be successfully connected
pluginsDBs.add(db.getDbReference());
}
}
return pluginsDBs;
}
public WGACore getCore() {
return _core;
}
private WGAPlugin createPlugin(String path) throws WGIllegalArgumentException, IOException, InvalidPluginException {
File file = _core.getWGAFile(path);
if (!file.exists()) {
throw new WGIllegalArgumentException("File '" + file.getPath() + " does not exist or is no regular data file");
}
WGAPlugin plugin = new WGAPlugin(this, path);
return plugin;
}
public void init(WGACore core, File pluginsDir) throws PluginSetInitException {
init(core, pluginsDir, false);
}
private void init(WGACore core, File pluginsDir, boolean workspaceSet) throws PluginSetInitException {
try {
_core = core;
_workspaceSet = workspaceSet;
_runtimeContexts = new HashMap<PluginID, RuntimeContext>();
_pluginsDir = pluginsDir;
createPluginDirectories();
_pluginsByInstallationKey = new HashMap<String,WGAPlugin>();
_activePluginsByUniqueName = new HashMap<String,WGAPlugin>();
Iterator<WGAPlugin> plugins = _plugins.iterator();
while (plugins.hasNext()) {
WGAPlugin plugin = (WGAPlugin) plugins.next();
try {
plugin.init();
if (plugin.isActive()) {
_activePluginsByUniqueName.put(plugin.getPluginID().getUniqueName(), plugin);
if (plugin.getInstallationKey() != null) {
_pluginsByInstallationKey.put(plugin.getInstallationKey(), plugin);
}
}
}
catch (MissingDefaultPluginException e) {
// Will be tolerated for now, handled later on default plugin evaluation
}
catch (InvalidPluginException e) {
_core.getLog().error("Error initializing plugin " + plugin.getPluginID().toString(), e);
}
}
}
catch (PluginSetInitException e) {
throw e;
}
catch (Exception e) {
throw new PluginSetInitException("Exception initializing plugin set", e);
}
}
private void createPluginDirectories() throws PluginSetInitException {
// Plugin files dir: Contains installed plugins
_pluginFilesDir = new File(_pluginsDir, "files");
if (!_pluginFilesDir.exists()) {
if (_workspaceSet || !_pluginFilesDir.mkdir()) {
throw new PluginSetInitException("Could not create plugin files directory '" + _pluginFilesDir.getPath() + "'. No WGA Plugins will be connected.");
}
}
// Plugin databases dir: Contains HSQL databases for plugin content stores
_pluginDBsDir = new File(_pluginsDir, "#dbs");
// check for old plugin dbs dir name and rename
File oldPluginDBsDir = new File(_pluginsDir, "dbs");
if (oldPluginDBsDir.exists()) {
oldPluginDBsDir.renameTo(_pluginDBsDir);
}
if (!_pluginDBsDir.exists()) {
if (_workspaceSet || !_pluginDBsDir.mkdir()) {
throw new PluginSetInitException("Could not create plugin databases directory '" + _pluginDBsDir.getPath() + "'. No WGA Plugins will be connected.");
}
}
// Plugin workspace dir: Contains uploaded but not yet installed plugins
_pluginWorkspaceDir = new File(_pluginsDir, "#workspace");
File oldPluginWorkspaceDir = new File(_pluginsDir, "workspace");
if (oldPluginWorkspaceDir.exists()) {
oldPluginWorkspaceDir.renameTo(_pluginWorkspaceDir);
}
if (!_pluginWorkspaceDir.exists()) {
if (_workspaceSet || !_pluginWorkspaceDir.mkdir()) {
throw new PluginSetInitException("Could not create plugin workspace directory '" + _pluginWorkspaceDir.getPath() + "'. No WGA Plugins will be connected.");
}
}
}
public synchronized WGAPlugin installPlugin(File file, int updateStrategy, boolean defaultPlugin) throws PluginException {
return installPlugin(file, updateStrategy, false, defaultPlugin, null);
}
protected synchronized WGAPlugin installPlugin(File file, int updateStrategy, boolean workspace, boolean defaultPlugin, String replaceKey) throws PluginException {
try {
WGAPlugin sourcePlugin = createPlugin(file.getAbsolutePath());
if (!_workspaceSet) {
_core.getLog().info("Installing WGA plugin " + sourcePlugin.getPluginID().getUniqueName() + " Version " + sourcePlugin.getPluginID().getVersion().toString());
}
// Determine if a plugin of that id already exists
boolean existed = false;
WGAPlugin previousPlugin = getPluginByID(sourcePlugin.getPluginID());
if (previousPlugin != null) {
if (!_workspaceSet) {
File prevPluginFile = previousPlugin.getPluginFile();
if (prevPluginFile.isFile()) {
if (!previousPlugin.isDefaultPlugin()) {
_core.getLog().info("Removing previous file for plugin " + previousPlugin.getPluginID().toString());
prevPluginFile.delete();
}
else {
_core.getLog().warn("You are overwriting a default plugin. The previous version will stay and may be reinstalled automatically.");
}
}
else {
_core.getLog().info("Previous plugin file was a directory and will not be deleted");
}
}
existed = true;
}
String fileName = sourcePlugin.getPluginID().buildQualifiedFileName();
File targetFile = new File(getPluginFilesDir(), fileName);
// Normal mode: Copy source to target file.
if (!workspace && !defaultPlugin && file.isFile() && !targetFile.equals(file)) {
InputStream in = new FileInputStream(file);
OutputStream out = new FileOutputStream(targetFile);
WGUtils.inToOut(in, out, 2048);
in.close();
out.close();
}
// Developer plugins, default plugins or reinstalled plugin from plugins folder: Just use the source file
else {
targetFile = file;
}
WGAPlugin targetPlugin = null;
// If there already was a plugin file try to find an existing plugin definition.
// If so, just tell it to reconnect, change nothing else
if (existed) {
targetPlugin = getPluginByID(sourcePlugin.getPluginID());
if (targetPlugin != null) {
targetPlugin.setFilePath(getCore().createWGAFilePath(targetFile));
targetPlugin.setDefaultPlugin(defaultPlugin);
targetPlugin.setReconnectDatabase(true);
targetPlugin.setUpdateStatus(WGAPlugin.UPDATESTATUS_UPDATE_IDENTICAL);
targetPlugin.getRuntimeContext().setUpdated(true);
targetPlugin.init();
if (!workspace) {
if (targetPlugin.isActive()) {
return activatePlugin(targetPlugin, updateStrategy, workspace, targetPlugin.getInstallationKey());
}
}
else {
// In workspace mode we must fake that the source plugin was installed, as we do not touch the target plugin
sourcePlugin.setInstallationKey(targetPlugin.getInstallationKey());
sourcePlugin.setActive(targetPlugin.isActive());
return sourcePlugin;
}
}
}
// If plugin did not exist yet, create a new one for the target
targetPlugin = createPlugin(getCore().createWGAFilePath(targetFile));
targetPlugin.setDefaultPlugin(defaultPlugin);
// Determine if the current installation status of this plugin is deactivated (plugins exist but are all inactive) REMOVED PER #00000867
// boolean isPluginDeactivated = isPluginDeactivated(targetPlugin.getPluginID().getUniqueName());
// Install it and activate it unless it was deactivated before
_plugins.add(targetPlugin);
return activatePlugin(targetPlugin, updateStrategy, workspace, replaceKey);
}
catch (PluginException e) {
throw e;
}
catch (InvalidPluginException e) {
throw new PluginException(e.getMessage(), e.getCause());
}
catch (Exception e) {
throw new PluginException("Exception installing plugin", e);
}
}
private boolean isPluginDeactivated(String uniqueName) {
List<WGAPlugin> plugins = getPluginsByUniqueName(uniqueName);
if (plugins.size() == 0) {
return false;
}
for (WGAPlugin plugin : plugins) {
if (plugin.isActive()) {
return false;
}
}
return true;
}
protected WGAPlugin activatePlugin(WGAPlugin plugin, int updateStrategy, boolean isWorkspacePlugin, String replaceKey) throws WGIllegalArgumentException, FileSystemException, IOException, PluginException {
String installationKey = null;
plugin.setActive(true);
boolean clearPluginDatabase = false;
// Deactivate previous plugin if available
// Replace key given: Check if this is a previous version of the plugin under that key, deactivate it if so
if (updateStrategy == UPDATESTRATEGY_UPDATE_KEEP_DATA && replaceKey != null) {
WGAPlugin previousPlugin = (WGAPlugin) _pluginsByInstallationKey.get(replaceKey);
if (previousPlugin == null) {
throw new PluginException("The installation key to replace does not exist: " + replaceKey);
}
if (!previousPlugin.getPluginID().getUniqueName().equals(plugin.getPluginID().getUniqueName())) {
throw new PluginException("The plugin under installation key '" + replaceKey + "' is no plugin of name " + plugin.getPluginID().getUniqueName());
}
installationKey = previousPlugin.getInstallationKey();
if (previousPlugin != plugin) {
if (!_workspaceSet) {
_core.getLog().info("Deactivating WGA plugin " + previousPlugin.getPluginID().getUniqueName() + " Version " + previousPlugin.getPluginID().getVersion().toString());
}
deactivatePlugin(previousPlugin);
}
plugin.setUpdateStatus(WGAPlugin.UPDATESTATUS_UPDATE);
}
// No replace key given: Find previously installed version of this plugin and deactivate it
else {
WGAPlugin previousPlugin = (WGAPlugin) _activePluginsByUniqueName.get(plugin.getPluginID().getUniqueName());
if (previousPlugin != null && previousPlugin != plugin && previousPlugin.isActive() == true && previousPlugin.getInstallationKey() != null) {
// New plugin should replace old plugin, old will be deactivated
if (updateStrategy == UPDATESTRATEGY_UPDATE_KEEP_DATA) {
if (!_workspaceSet) {
_core.getLog().info("Deactivating WGA plugin " + previousPlugin.getPluginID().getUniqueName() + " Version " + previousPlugin.getPluginID().getVersion().toString());
}
installationKey = previousPlugin.getInstallationKey();
deactivatePlugin(previousPlugin);
plugin.setUpdateStatus(WGAPlugin.UPDATESTATUS_UPDATE);
}
else {
plugin.setUpdateStatus(WGAPlugin.UPDATESTATUS_INSTALL_PARALLEL);
}
}
}
// Activate plugin
plugin.getRuntimeContext().setUpdated(true);
if (plugin.isActive()) {
if (installationKey != null) {
plugin.setInstallationKey(installationKey);
}
else {
determineInstallationKey(plugin);
}
_pluginsByInstallationKey.put(plugin.getInstallationKey(), plugin);
_activePluginsByUniqueName.put(plugin.getPluginID().getUniqueName(), plugin);
}
return plugin;
}
public void uninstallPlugin(WGAPlugin plugin, boolean workspace) {
if (!workspace) {
_core.getLog().info("Uninstalling plugin " + plugin.getIdentification());
}
removePluginFromMaps(plugin, true);
if (!workspace && !plugin.isDefaultPlugin()) {
_core.getLog().info("Removing plugin file " + plugin.getIdentification());
File pluginFile = plugin.getPluginFile();
if (pluginFile.exists() && pluginFile.isFile()) {
pluginFile.delete();
}
}
}
private void removePluginFromMaps(WGAPlugin plugin, boolean completeRemoval) {
if (completeRemoval && _plugins.contains(plugin)) {
_plugins.remove(plugin);
}
WGAPlugin mapPlugin = (WGAPlugin) _activePluginsByUniqueName.get(plugin.getPluginID().getUniqueName());
if (mapPlugin != null && mapPlugin.equals(plugin)) {
_activePluginsByUniqueName.remove(plugin.getPluginID().getUniqueName());
}
if (plugin.getInstallationKey() != null) {
mapPlugin = (WGAPlugin) _pluginsByInstallationKey.get(plugin.getInstallationKey());
if (mapPlugin != null && mapPlugin.equals(plugin)) {
_pluginsByInstallationKey.remove(plugin.getInstallationKey());
}
}
}
public void deactivatePlugin(WGAPlugin plugin) {
// Only set the flag here. WGACore.connectPlugins() takes care of disconnect and cleanup operations, but needs a filled installation key to do this.
plugin.setActive(false);
/*
plugin.setInstallationKey(null);
removePluginFromMaps(plugin, false);*/
}
private synchronized void determineInstallationKey(WGAPlugin targetPlugin) throws WGIllegalArgumentException, FileSystemException, IOException, PluginException {
String key = targetPlugin.getPluginID().buildShortName().toLowerCase();
if (!_pluginsByInstallationKey.containsKey(key)) {
targetPlugin.setInstallationKey(key);
return;
}
key = targetPlugin.getPluginID().buildShortName() + "-" + targetPlugin.getPluginID().getVersion().getMajorVersion() + "." + targetPlugin.getPluginID().getVersion().getMinorVersion();
key = key.toLowerCase();
if (!_pluginsByInstallationKey.containsKey(key)) {
targetPlugin.setInstallationKey(key);
return;
}
key = targetPlugin.getPluginID().buildShortName() + "-" + targetPlugin.getPluginID().getVersion().getMainVersionString();
key = key.toLowerCase();
if (!_pluginsByInstallationKey.containsKey(key)) {
targetPlugin.setInstallationKey(key);
return;
}
key = targetPlugin.getPluginID().getUniqueName() + "-" + targetPlugin.getPluginID().getVersion().getMainVersionString();
key = key.toLowerCase();
if (!_pluginsByInstallationKey.containsKey(key)) {
targetPlugin.setInstallationKey(key);
return;
}
throw new PluginException("Cannot determine a free installation key");
}
public File getPluginDBsDir() {
return _pluginDBsDir;
}
public File getPluginFilesDir() {
return _pluginFilesDir;
}
public File getPluginWorkspaceDir() {
return _pluginWorkspaceDir;
}
public List<WGAPlugin> getPlugins() {
List<WGAPlugin> plugins = new ArrayList<WGAPlugin>(_plugins);
Collections.sort(plugins, new Comparator<WGAPlugin>() {
public int compare(WGAPlugin p1, WGAPlugin p2) {
int state1 = (!p1.isActive() ? 3 : !p1.isValid() ? 2 : 1);
int state2 = (!p2.isActive() ? 3 : !p2.isValid() ? 2 : 1);
return state1 - state2;
}
});
return plugins;
}
public Map<String,WGAPlugin> getPluginsByInstallationKey() {
return _pluginsByInstallationKey;
}
public WGAPluginSet createWorkspacePluginSet(List ops) throws PluginException, FileSystemException, PluginSetInitException {
WGAPluginSet set = createClone();
// Add Workspace Operations
set.performOperations(ops, true);
// Validate plugins
set.validatePlugins();
return set;
}
public Set<WGAPlugin> getWorkspacePlugins() {
return _workspacePlugins;
}
public InstallPluginOperation loadPluginToWorkspace(File file) throws IOException {
File targetFile = File.createTempFile("plugin", ".wgaplugin", getPluginWorkspaceDir());
//B000048C2 - not necessary workspace dir is cleared on wga shutdown now
// targetFile.deleteOnExit();
WGUtils.copyFile(file, targetFile);
InstallPluginOperation op = new InstallPluginOperation(targetFile, UPDATESTRATEGY_UPDATE_KEEP_DATA);
return op;
}
public InstallPluginOperation loadPluginToWorkspace(InputStream in) throws IOException {
File targetFile = File.createTempFile("plugin", ".wgaplugin", getPluginWorkspaceDir());
WGUtils.inToOut(in, new FileOutputStream(targetFile), 1024);
InstallPluginOperation op = new InstallPluginOperation(targetFile, UPDATESTRATEGY_UPDATE_KEEP_DATA);
return op;
}
public File getPluginsDir() {
return _pluginsDir;
}
public List<String> getChanges(WGAPluginSet set) {
List<String> changes = new ArrayList<String>();
// Installed plugins that will get deactivated
Iterator<WGAPlugin> oldPlugins = set.getPluginsByInstallationKey().values().iterator();
while (oldPlugins.hasNext()) {
WGAPlugin oldPlugin = (WGAPlugin) oldPlugins.next();
WGAPlugin newPlugin = (WGAPlugin) getPluginByID(oldPlugin.getPluginID());
WGAPlugin newInstalledPlugin = (WGAPlugin) _pluginsByInstallationKey.get(oldPlugin.getInstallationKey());
if (newPlugin == null) {
changes.add("The plugin " + oldPlugin.getIdentification() + " will be removed.");
continue;
}
if (newInstalledPlugin != null && !newInstalledPlugin.getPluginID().equals(oldPlugin.getPluginID())) {
changes.add("The plugin " + oldPlugin.getIdentification() + " will be replaced by " +
newInstalledPlugin.getIdentification() + ". The previous version will be deactivated.");
continue;
}
if (newInstalledPlugin != null && newInstalledPlugin.getUpdateStatus() == WGAPlugin.UPDATESTATUS_UPDATE_IDENTICAL) {
changes.add("The plugin " + oldPlugin.getIdentification() + " will be replaced by a new plugin with identical version number.");
}
if (oldPlugin.isActive() && !newPlugin.isActive()) {
changes.add("The plugin " + newPlugin.getIdentification() + " will be deactivated.");
}
if (oldPlugin.isValid() && !newPlugin.isValid()) {
changes.add("The plugin " + newPlugin.getIdentification() + " will be invalid.");
}
if (newPlugin.getOperation() instanceof ResetDatabaseOperation) {
changes.add("All stored data for plugin " + newPlugin.getIdentification() + " will be erased. The plugin will initialize itself again.");
}
}
// Workspace plugins that will not work - We don't want this information here, since we are only
// interested in effects on existing plugins
/*Iterator wsPlugins = _workspacePlugins.iterator();
while (wsPlugins.hasNext()) {
WGAPlugin wsPlugin = (WGAPlugin) wsPlugins.next();
if (wsPlugin.isValid() == false) {
changes.add("New plugin " + wsPlugin.getIdentification() + " will be invalid.");
}
else if (wsPlugin.isActive() == false) {
changes.add("New plugin " + wsPlugin.getIdentification() + " will be inactive.");
}
}*/
return changes;
}
public void removePluginFromWorkspace(File pluginFile) {
if (pluginFile.exists() && pluginFile.getPath().startsWith(_pluginWorkspaceDir.getPath())) {
pluginFile.delete();
}
else {
throw new IllegalArgumentException("The plugin file '" + pluginFile.getPath() + "' is no plugin in workspace.");
}
}
private void performOperations(List<WorkspaceOperation> ops, boolean workspace) throws PluginOperationException {
Iterator opsIt = ops.iterator();
while (opsIt.hasNext()) {
WorkspaceOperation op = (WorkspaceOperation) opsIt.next();
WGAPlugin plugin = op.perform(this, _core, workspace);
if (plugin != null) {
plugin.setOperation(op);
}
if (workspace) {
_workspacePlugins.add(plugin);
}
}
}
public void performOperations(List<WorkspaceOperation> ops) throws PluginOperationException {
performOperations(ops, false);
}
public WGAPlugin getPluginByID(PluginID id) {
Iterator<WGAPlugin> plugins = _plugins.iterator();
while (plugins.hasNext()) {
WGAPlugin plugin = (WGAPlugin) plugins.next();
if (plugin.getPluginID().equals(id)) {
return plugin;
}
}
return null;
}
public WGAPlugin getPluginByID(String idString) {
return getPluginByID(new PluginID(idString));
}
public WGAPluginSet createClone() throws PluginSetInitException {
String xml = XSTREAM.toXML(this);
WGAPluginSet clone = (WGAPluginSet) XSTREAM.fromXML(xml);
clone.init(_core, _pluginsDir, true);
return clone;
}
public List<WGAPlugin> getPluginsByUniqueName(String name) {
List<WGAPlugin> results = new ArrayList<WGAPlugin>();
Iterator<WGAPlugin> plugins = _plugins.iterator();
while (plugins.hasNext()) {
WGAPlugin plugin = (WGAPlugin) plugins.next();
if (plugin.getPluginID().getUniqueName().equals(name)) {
results.add(plugin);
}
}
Collections.sort(results, new Comparator<WGAPlugin>() {
public int compare(WGAPlugin p1, WGAPlugin p2) {
return p1.getPluginID().getVersion().compareTo(p2.getPluginID().getVersion());
}
});
return results;
}
public WGAPlugin getPluginByUniqueName(String name) {
List<WGAPlugin> plugins = getPluginsByUniqueName(name);
if (plugins.size() > 0) {
Iterator<WGAPlugin> pluginsIt = plugins.iterator();
// Try to return an active plugin of this name
while (pluginsIt.hasNext()) {
WGAPlugin plugin = pluginsIt.next();
if (plugin.isActive()) {
return plugin;
}
}
return plugins.get(0);
}
else {
return null;
}
}
public void deletePluginDatabase(WGAPlugin plugin) {
String installKey = plugin.getInstallationKey();
List<String> suffixes = new ArrayList<String>();
suffixes.add(".log");
suffixes.add(".script");
suffixes.add(".properties");
suffixes.add(".data");
suffixes.add(".lck");
suffixes.add(".backup");
for (String suffix : suffixes) {
File dbFile = new File(getPluginDBsDir(), installKey + suffix);
if (dbFile.exists()) {
dbFile.delete();
}
}
}
/**
* clears temporary resources e.g. tempfiles in the workspace dir
* called before wga shutdown
*/
public void clearTempResources() {
if (_pluginWorkspaceDir != null && _pluginWorkspaceDir.exists()) {
WGUtils.delTree(_pluginWorkspaceDir, false);
}
}
/**
* Tests if there are some invalid plugins in this plugin set
*/
public boolean hasInvalidPlugins() {
Iterator<WGAPlugin> plugins = _plugins.iterator();
while (plugins.hasNext()) {
WGAPlugin plugin = (WGAPlugin) plugins.next();
if (!plugin.isValid()) {
return true;
}
}
return false;
}
public synchronized RuntimeContext getRuntimeContext(WGAPlugin plugin) {
RuntimeContext cx = _runtimeContexts.get(plugin.getPluginID());
if (cx == null) {
cx = new RuntimeContext();
_runtimeContexts.put(plugin.getPluginID(), cx);
}
return cx;
}
public void importRuntimeContexts(WGAPluginSet oldSet) {
_runtimeContexts = oldSet._runtimeContexts;
}
}