Package de.innovationgate.wgpublisher.plugins

Source Code of de.innovationgate.wgpublisher.plugins.WGAPlugin

/*******************************************************************************
* 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/>.
******************************************************************************/
/**
* Represents a plugin file and offers operations to deal with it
*/
package de.innovationgate.wgpublisher.plugins;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.vfs.FileSystemException;

import de.innovationgate.utils.TemporaryFile;
import de.innovationgate.utils.WGUtils;
import de.innovationgate.webgate.api.WGIllegalArgumentException;
import de.innovationgate.wga.common.DesignDirectory;
import de.innovationgate.wga.common.beans.DesignDefinition;
import de.innovationgate.wga.common.beans.csconfig.v1.CSConfig;
import de.innovationgate.wga.common.beans.csconfig.v1.InvalidCSConfigVersionException;
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.PublisherOption;
import de.innovationgate.wgpublisher.SystemContainerManager;
import de.innovationgate.wgpublisher.WGACore;
import de.innovationgate.wgpublisher.plugins.WGAPluginSet.RuntimeContext;

public class WGAPlugin {
   
    public static final int UPDATESTATUS_NEW = 0;
    public static final int UPDATESTATUS_UPDATE = 1;
    public static final int UPDATESTATUS_INSTALL_PARALLEL = 2;
    public static final int UPDATESTATUS_INSTALL_DEACTIVATED = 1;
    public static final int UPDATESTATUS_UPDATE_IDENTICAL = 3;
   
    public static Set<String> PLATFORM_PLUGINS = new HashSet<String>();
   
    static {
        PLATFORM_PLUGINS.add("de.innovationgate.admin");
        PLATFORM_PLUGINS.add("de.innovationgate.app-ui-3-1");
        PLATFORM_PLUGINS.add("de.innovationgate.contentmanager");
        PLATFORM_PLUGINS.add("de.innovationgate.csmaintenance");
        PLATFORM_PLUGINS.add("de.innovationgate.Management");
        PLATFORM_PLUGINS.add("de.innovationgate.wga-app-framework");
        PLATFORM_PLUGINS.add("de.innovationgate.wgaservices-xfire");
    }
   
    public static class Configuration {
       
        private DesignDefinition _syncInfo;
        private CSConfig _csConfig;
        private String _licenseText;

        // Default constructor for serialisation
        private Configuration() {
        }
       
        public Configuration(DesignDefinition syncInfo, CSConfig csConfig, String licenseText) {
            super();
            _syncInfo = syncInfo;
            _csConfig = csConfig;
            _licenseText = licenseText;
        }
        public CSConfig getCsConfig() {
            return _csConfig;
        }
        public DesignDefinition getSyncInfo() {
            return _syncInfo;
        }

        public String getLicenseText() {
            return _licenseText;
        }
       
    }
   
    public class InstallationFault {

        public static final int ERROR_WRONG_WGA_VERSION = 1;
        public static final int ERROR_WRONG_JAVA_VERSION = 2;
       
        public static final int ERROR_DEPENDENCY_NOT_AVAILABLE = 3;
        public static final int ERROR_DEPENDENCY_WRONG_VERSION = 4;
        public static final int ERROR_DEPENDENCY_INACTIVE = 5;
        public static final int ERROR_CIRCULAR_REFERENCE = 6;
       
        public static final int ERROR_INITIALISATION = 7;
       
        private int _error;

        // Default constructor for serialisation
        private InstallationFault() {
        }
       
        public InstallationFault(int error) {
            _error = error;
        }

        public String toErrorMessage() {
            if (_error == ERROR_WRONG_JAVA_VERSION) {
                return "This plugin needs at least Java Version " + getCsConfig().getPluginConfig().getMinimumJavaVersion().toString();
            }
            else if (_error == ERROR_WRONG_WGA_VERSION) {
                return "This plugin needs at least WGA Version " + getCsConfig().getPluginConfig().getMinimumWGAVersion().toString();
            }
            else {
                return "Unknown error code " + _error;
            }
           
        }

        public int getError() {
            return _error;
        }
       
    }
   
    public class DependencyFault extends InstallationFault {
       
        public String toErrorMessage() {
          
            if (getError() == ERROR_DEPENDENCY_NOT_AVAILABLE) {
                return "This plugin depends on another WGA Plugin " + _depPluginID.getUniqueName() + " " + _depPluginID.getVersion().toString() + " which is either not installed or not active.";
            }
            else if (getError() == ERROR_DEPENDENCY_WRONG_VERSION) {
                return "This plugin depends on another WGA Plugin " + _depPluginID.getUniqueName() + " " + _depPluginID.getVersion().toString() + " which has a too low version.";
            }
            else if (getError() == ERROR_DEPENDENCY_INACTIVE) {
                return "This plugin depends on another WGA Plugin " + _depPluginID.getUniqueName() + " " + _depPluginID.getVersion().toString() + " which is inactive.";
            }
            else if (getError() == ERROR_CIRCULAR_REFERENCE) {
                return "This plugin causes a circular reference bc. it's dependency tree contains itself. WGA therefor cannot determine a correct order to connect plugins.";
            }
            else {
                return super.toErrorMessage();
            }
           
        }

        private PluginID _depPluginID;

        // Default constructor for serialisation
        private DependencyFault() {
        }
       
        public DependencyFault(PluginID pluginID, int error) {
            super(error);
            _depPluginID = pluginID;
        }
       
    }
   
    public class InitialisationFault extends InstallationFault {

        private String _msg;

        public InitialisationFault(String msg) {
            super(InstallationFault.ERROR_INITIALISATION);
            _msg = msg;
        }
       
        // Default constructor for serialisation
        private InitialisationFault() {
        }

        public String toErrorMessage() {
           return "Unable to initialize plugin: " + _msg;
        }

    }
   

    // Persistent fields
    private WGAPluginSet _parent = null;
    private boolean _active = true;
    private boolean _defaultPlugin = false;
    private boolean _reconnectDatabase = false;
    private String _filePath;
    private String _installationKey;
    // May not be transient bc. it distinguishes the plugin in a HashSet
    private PluginID _pluginID;
   
    private transient Map _mandatoryPlugins;
    private transient Map _dependentPlugins;
    private transient boolean _valid = true;
   
    private transient WorkspaceOperation _operation;
    private transient int _updateStatus = UPDATESTATUS_NEW;

    private transient long _fileLastModified;
    private transient List _installationFaults;
    private transient Configuration _config;
    private WGAPlugin() {
    }
   
    protected WGAPlugin(WGAPluginSet parent, String path) throws WGIllegalArgumentException, IOException, InvalidPluginException {
        _parent = parent;
        _filePath = path;
        init();
    }
   
   
    public File getPluginFile() {
        File file = getParent().getCore().getWGAFile(_filePath);
       
        // Backward compatibility to WGA4: find relative to plugins folder
        if (file == null || !file.exists()) {
            file = new File(getParent().getPluginsDir(), _filePath);
        }
       
        return file;
    }


    public void init() throws FileSystemException, IOException, InvalidPluginException {

        _valid = true;
        _mandatoryPlugins = new HashMap();
        _dependentPlugins = new HashMap();
        _installationFaults = new ArrayList();
       
        try {
            validate();
        }
        catch (InvalidPluginException e) {
            _installationFaults.add(new InitialisationFault(e.getMessage()));
            throw e;
        }
       
    }

    public void validate() throws InvalidPluginException {
        try {
            File file = getPluginFile();
            if (file == null || !file.exists()) {
                if (isDefaultPlugin()) {
                    throw new MissingDefaultPluginException(this);
                }
                else {
                    throw new InvalidPluginException(this, "The plugin file/directory does not exist (any more): " + _filePath);
                }
            }
           
            loadMetadata(file);
        }
        catch (InvalidPluginException e) {
            _valid = false;
           throw e;
        }
    }



    /**
     * Load all metadata about the plugin
     * - syncinfo.xml
     * - csconfig.xml
     * - File last modified time
     * @throws InvalidPluginException
     */
    private synchronized void loadMetadata(File file) throws InvalidPluginException {
       
        try {
            _fileLastModified = file.lastModified();
            _config = loadConfiguration(file);
            if (_config == null) {
                throw new InvalidPluginException(this, "This plugin does not contain a mandatory file: syncinfo.xml/design.xml or csconfig.xml");
            }
           
            if (_config.getCsConfig().getPluginConfig() == null) {
                throw new InvalidPluginException(this, "The plugin is invalid because its csconfig.xml does not contain a plugin configuration");
            }
           
            _pluginID = _config.getCsConfig().getPluginConfig().getId();
        }
        catch (InvalidCSConfigVersionException e) {
            throw new InvalidPluginException(this, "This plugin was developed for a higher WGA version: " + e.getTargetVersion());
        }
        catch (Exception e) {
            throw new InvalidPluginException(this, "Cannot read plugin metadata bc. of exception ",e);
        }
       
    }

    public static Configuration loadConfiguration(File file) throws FileNotFoundException, IOException, InvalidCSConfigVersionException {
       
        DesignDefinition syncInfo = null;
        CSConfig csConfig = null;
        String licenseText = null;
       
        // Normal plugin file
        if (file.isFile()) {
            ZipInputStream zipIn = new ZipInputStream(new FileInputStream(file));
            try {
                ZipEntry entry;
                while ((entry = zipIn.getNextEntry()) != null) {
                   
                    String entryName = entry.getName();
                    if (entryName.equals(DesignDirectory.DESIGN_DEFINITION_FILE) || entryName.equals(DesignDirectory.SYNCINFO_FILE)) {
                        TemporaryFile tempFile = new TemporaryFile("design", zipIn, null);
                        syncInfo = DesignDefinition.load(tempFile.getFile());
                        tempFile.delete();
                    }
                    else if (entryName.equals(SystemContainerManager.CSCONFIG_PATH)) {
                        TemporaryFile tempFile = new TemporaryFile("csconfig", zipIn, null);
                        csConfig = CSConfig.load(tempFile.getFile());
                        tempFile.delete();
                    }
                    else if (entryName.equals(SystemContainerManager.LICENSE_PATH)) {
                        licenseText = WGUtils.readString(new InputStreamReader(zipIn,  "UTF-8")).trim();
                    }
                   
                    if (syncInfo != null && csConfig != null) {
                        break;
                    }
                }
            }
            finally {
                zipIn.close();
            }
        }
       
        // Developer plugin folder
        else {
            File syncInfoFile = DesignDirectory.getDesignDefinitionFile(file);
            if (syncInfoFile.exists()) {
                syncInfo = DesignDefinition.load(syncInfoFile);
            }
            File csConfigFile = new File(file, SystemContainerManager.CSCONFIG_PATH);
            if (csConfigFile.exists()) {
                csConfig = CSConfig.load(csConfigFile);
            }
            File licenseTextFile = new File(file, SystemContainerManager.LICENSE_PATH);
            if (licenseTextFile.exists()) {
                Reader reader = new InputStreamReader(new FileInputStream(licenseTextFile) , "UTF-8");
                licenseText = WGUtils.readString(reader).trim();
                reader.close();
            }
           
        }
       
        if (syncInfo != null && csConfig != null && csConfig.getPluginConfig() != null) {
            return new Configuration(syncInfo, csConfig, licenseText);
        }
        else {
            return null;
        }
       
    }
   
    public String getDesignURL() throws FileSystemException {
        if (getPluginFile().isFile()) {
            return "zip:file:///" + getPluginFile().getAbsolutePath();
        }
        else {
            return getPluginFile().getAbsolutePath();
        }
    }

    public PluginID getPluginID() {
        return _pluginID;
    }

    public boolean isActive() {
        return _active;
    }

    public void setActive(boolean active) {
        _active = active;
    }

    public void checkDependencies() {
       
        Iterator depsIt = _config.getCsConfig().getPluginConfig().getDependencies().iterator();
        while (depsIt.hasNext()) {
            PluginID depId = (PluginID) depsIt.next();
            WGAPlugin depPlugin = (WGAPlugin) _parent.getActivePluginsByUniqueName().get(depId.getUniqueName());
            if (depPlugin == null) {
                addInstallationFault(new DependencyFault(depId, DependencyFault.ERROR_DEPENDENCY_NOT_AVAILABLE));
                continue;
            }
           
            int versionCompare = depId.getVersion().compareTo(depPlugin.getPluginID().getVersion());
            if (versionCompare > 0) {
                addInstallationFault(new DependencyFault(depId, DependencyFault.ERROR_DEPENDENCY_WRONG_VERSION));
                continue;
            }
           
            if (depPlugin.isActive() == false || depPlugin.isValid() == false) {
                addInstallationFault(new DependencyFault(depId, DependencyFault.ERROR_DEPENDENCY_INACTIVE));
                continue;
            }
           
            if (detectCircularReference(depPlugin)) {
                addInstallationFault(new DependencyFault(depId, DependencyFault.ERROR_CIRCULAR_REFERENCE));
                continue;
            }
           
            depPlugin.addDependentPlugin(this);
            _mandatoryPlugins.put(depPlugin.getPluginID(), depPlugin);
           
           
        }
       
    }

    private boolean detectCircularReference(WGAPlugin depPlugin) {
       
        if (depPlugin.equals(this)) {
            return true;
        }
       
        Iterator dependencies = depPlugin.getCsConfig().getPluginConfig().getDependencies().iterator();
        while (dependencies.hasNext()) {
            PluginID id = (PluginID) dependencies.next();
            WGAPlugin plugin = getParent().getPluginByID(id);
            if (plugin != null && detectCircularReference(plugin)) {
                return true;
            }
        }
       
       
        return false;
    }


    private void addDependentPlugin(WGAPlugin plugin) {
        _dependentPlugins.put(plugin.getPluginID(), plugin);
    }

    public Map getMandatoryPlugins() {
        return _mandatoryPlugins;
    }

    public boolean isValid() {
        return _valid;
    }

    public void setValid(boolean valid) {
        _valid = valid;
    }



    public WGAPluginSet getParent() {
        return _parent;
    }

    public String getInstallationKey() {
        return _installationKey;
    }



    public void setInstallationKey(String installationKey) {
        _installationKey = installationKey;
    }
   
    public String buildDatabasePath() throws FileSystemException {
        return new File(_parent.getPluginDBsDir(), getInstallationKey()).getPath();
    }



    public long getFileLastModified() {
        return _fileLastModified;
    }



    public String getFilePath() {
        return FilenameUtils.normalize(getParent().getCore().getWGAFile(_filePath).getAbsolutePath());
    }



    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = PRIME * result + ((_pluginID == null) ? 0 : _pluginID.hashCode());
        return result;
    }



    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final WGAPlugin other = (WGAPlugin) obj;
        if (_pluginID == null) {
            if (other._pluginID != null)
                return false;
        }
        else if (!_pluginID.equals(other._pluginID))
            return false;
        return true;
    }



    public List getInstallationFaults() {
        return _installationFaults;
    }
   
   
    public void addInstallationFault(InstallationFault fault) {
        _installationFaults.add(fault);
    }
   
    public String getIdentification() {
        return getPluginID().toString();
    }



    public WorkspaceOperation getOperation() {
        return _operation;
    }



    public void setOperation(WorkspaceOperation operation) {
        _operation = operation;
    }



    public int getUpdateStatus() {
        return _updateStatus;
    }



    public void setUpdateStatus(int updateStatus) {
        _updateStatus = updateStatus;
    }


    public String buildDatabaseKey() {
        return PluginConfig.PLUGIN_DBKEY_PREFIX + getInstallationKey();
    }


    public boolean isReconnectDatabase() {
        return getRuntimeContext().isReconnect();
    }


    public void setReconnectDatabase(boolean reconnectDatabase) {
        getRuntimeContext().setReconnect(reconnectDatabase);
    }
   
    public String getPluginHomepage() {
       
        PluginConfig pc = getCsConfig().getPluginConfig();
       
        if (!pc.isUsageAsContentStore()) {
            return null;
        }
       
        String ph = pc.getPluginHomepage();
        if (ph != null && !ph.trim().equals("")) {
            return ph;
        }
       
        PublisherOption option = getCsConfig().findPublisherOption(WGACore.DBATTRIB_HOME_PAGE);
        if (option != null) {
            return option.getValue();
        }
        else {
            return null;
        }
       
       
       
    }


    protected void setFilePath(String filePath) {
        _filePath = filePath;
    }


    public boolean isDirectory() {
       return getPluginFile().isDirectory();
    }


    public Map getDependentPlugins() {
        return _dependentPlugins;
    }

    public CSConfig getCsConfig() {
        if (_config != null) {
            return _config.getCsConfig();
        }
        else {
            throw new IllegalStateException("The plugin has no valid configuration: " + _filePath);
        }
    }
   
    public String getLicenseText() {
        if (_config != null) {
            return _config.getLicenseText();
        }
        else {
            return null;
        }
    }
   
    public DesignDefinition getSyncInfo() {
        return _config.getSyncInfo();
    }

    public boolean isUpdated() {
        return (getUpdateStatus() == UPDATESTATUS_UPDATE || getUpdateStatus() == UPDATESTATUS_UPDATE_IDENTICAL);
    }
   
    public RuntimeContext getRuntimeContext() {
        return _parent.getRuntimeContext(this);
    }

    public String getRegisteredFilePath() {
        return _filePath;
    }

    public boolean isDefaultPlugin() {
        return _defaultPlugin;
    }

    public void setDefaultPlugin(boolean defaultPlugin) {
        _defaultPlugin = defaultPlugin;
    }
   
    public boolean isPlatformPlugin() {
        boolean isPlatformPlugin = (_filePath != null && _filePath.contains("${wga.defaultpluginsdir}"));
        if (!isPlatformPlugin) {
            isPlatformPlugin = PLATFORM_PLUGINS.contains(getPluginID().getUniqueName());
        }
        return isPlatformPlugin;
    }
   
}
TOP

Related Classes of de.innovationgate.wgpublisher.plugins.WGAPlugin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.