de.xirp.plugin.SecurePluginView.java Source code

Java tutorial

Introduction

Here is the source code for de.xirp.plugin.SecurePluginView.java

Source

/** 
 * ============================================================================
 * Xirp 2: eXtendable interface for robotic purposes.
 * ============================================================================
 * 
 * Copyright (C) 2005-2007, by Authors and Contributors listed in CREDITS.txt
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at:
 *
 *             http://www.opensource.org/licenses/cpl1.0.php
 *
 * ----------------------------
 * SecurePluginView.java
 * ----------------------------
 *
 * Original Author:  Rabea Gransberger [rgransberger AT web.de]
 * Contributor(s):   
 *
 * Changes
 * -------
 * 10.10.2006:      Created by Rabea Gransberger.
 */
package de.xirp.plugin;

import java.util.Collections;
import java.util.List;
import java.util.Locale;

import org.apache.commons.lang.ClassUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.log4j.Logger;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.CoolItem;

import de.xirp.io.comm.CommunicationManager;
import de.xirp.report.Report;
import de.xirp.settings.Settings;
import de.xirp.ui.widgets.ApplicationToolBar;
import de.xirp.ui.widgets.custom.XToolBar;
import de.xirp.ui.widgets.dialogs.AboutPluginsDialog;
import de.xirp.ui.widgets.dialogs.GenericDialog;
import de.xirp.ui.widgets.dialogs.PreferencesDialog;
import de.xirp.ui.widgets.panels.COPComposite;
import de.xirp.ui.widgets.panels.GenericLayoutPart;
import de.xirp.ui.widgets.panels.RobotToolbar;
import de.xirp.util.Constants;
import de.xirp.util.I18n;
import de.xirp.util.collections.ConcurrentMultiValueHashMap;

/**
 * Secure View for plugins which allows only some classes to access
 * the methods of a plugin
 * 
 * @param <GAbstractPluginGUI>
 *            The type of the GUI for this plugin
 * @author Rabea Gransberger
 */
public final class SecurePluginView<GAbstractPluginGUI extends AbstractPluginGUI>
        implements IPlugable<GAbstractPluginGUI> {

    /**
     * Log4j Logger for this Class
     */
    private static Logger logClass = Logger.getLogger(SecurePluginView.class);
    /**
     * Index where the method which was originally called may be found
     * in the stack trace
     */
    private static int methodIndex = 3;

    /**
     * Map containing all classes for each method for which access to
     * this method is allowed
     */
    private static ConcurrentMultiValueHashMap<String, String> accessControl = new ConcurrentMultiValueHashMap<String, String>();

    static {
        accessControl.put("getSettings", PreferencesDialog.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getIdentifier", GenericDialog.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getIdentifier", "GenericDialog.1"); //$NON-NLS-1$ //$NON-NLS-2$
        accessControl.put("getInstanceID", "GenericDialog.1"); //$NON-NLS-1$ //$NON-NLS-2$
        accessControl.put("getIdentifier", GenericLayoutPart.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getNameKey", GenericLayoutPart.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getGUI", GenericLayoutPart.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getGUI", COPComposite.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getNameKey", COPComposite.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getNameKey", "GenericDialog.2"); //$NON-NLS-1$ //$NON-NLS-2$
        accessControl.put("getNameKey", GenericDialog.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getNameKey", PreferencesDialog.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getNameKey", RobotToolbar.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getGUI", GenericDialog.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getToolBar", RobotToolbar.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getToolBar", ApplicationToolBar.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getDescriptionKey", AboutPluginsDialog.class.getSimpleName()); //$NON-NLS-1$
        accessControl.put("getIdentifier", "AbstractLayoutPart.3"); //$NON-NLS-1$ //$NON-NLS-2$
        accessControl.put("requiredLibs", PluginLoader.class.getSimpleName()); //$NON-NLS-1$ 
        accessControl.put("setLocale", PluginManager.class.getSimpleName()); //$NON-NLS-1$ 
        accessControl.put("getOriginalPlugin", RobotPluginContainer.class.getSimpleName()); //$NON-NLS-1$ 
        accessControl.put("getOriginalPlugin", CommunicationManager.class.getSimpleName()); //$NON-NLS-1$ 
        accessControl.put("getOriginalPlugin", UnrefPluginContainer.class.getSimpleName()); //$NON-NLS-1$ 

        /**
         * For Java 1.6 the method index has changed
         */
        if (SystemUtils.IS_JAVA_1_6) {
            methodIndex = 2;
        }
    }

    /**
     * The original plugin of this secure view
     */
    private IPlugable<GAbstractPluginGUI> originalPlugin;

    /**
     * Constructs a new Secure View of a plugin
     * 
     * @param plugin
     *            the plugin to secure (may be a secure view, if this
     *            is the case the view is replaced with this one)
     * @throws InstantiationException
     *             if the given plugin was <code>null</code>
     */
    protected SecurePluginView(IPlugable<GAbstractPluginGUI> plugin) throws InstantiationException {
        if (plugin == null) {
            throw new InstantiationException("The given plugin must not be null."); //$NON-NLS-1$
        }
        this.originalPlugin = getRealPlugin(plugin);
    }

    /**
     * Gets the real plugin of a plugin which may be a secure view.
     * 
     * @param plugin
     *            The plugin to get the original plugin from
     * @return a plugin which is not a secure view
     */
    @SuppressWarnings("unchecked")
    private IPlugable<GAbstractPluginGUI> getRealPlugin(IPlugable<GAbstractPluginGUI> plugin) {
        if (plugin instanceof SecurePluginView) {
            SecurePluginView<GAbstractPluginGUI> secure = (SecurePluginView<GAbstractPluginGUI>) plugin;
            return getRealPlugin(secure.getOriginalPlugin());
        }
        return plugin;
    }

    /**
     * Gets the original plugin out of this secure view.
     * 
     * @return the original plugin
     */
    public IPlugable<GAbstractPluginGUI> getOriginalPlugin() {
        if (accessAllowed()) {
            return originalPlugin;
        }
        return null;
    }

    /**
     * Prints a log message that the access to the given method was
     * not allowed.
     * 
     * @param methodName
     *            the method name for which the access wasn't allowed
     */
    private void accessNotAllowed(String methodName) {
        try {
            throw new IllegalAccessException(I18n.getString("SecurePluginView.exception.noPermission1", //$NON-NLS-1$
                    methodName, getName()));
        } catch (IllegalAccessException e) {
            logClass.error("Error: " + e.getMessage() + Constants.LINE_SEPARATOR, e); //$NON-NLS-1$
        }
    }

    /**
     * Prints a log message that the access to the given method was
     * not allowed from the given class
     * 
     * @param methodName
     *            the name of the method
     * @param callerClassName
     *            the name of the class which tried to call this
     *            method
     */
    private void accessNotAllowed(String methodName, String callerClassName) {
        try {
            throw new IllegalAccessException(I18n.getString("SecurePluginView.exception.noPermission2", //$NON-NLS-1$
                    callerClassName, methodName, getName()));
        } catch (IllegalAccessException e) {
            logClass.error("Error: " + e.getMessage() + Constants.LINE_SEPARATOR, e); //$NON-NLS-1$
        }
    }

    /**
     * Checks if the access to the last called method was allowed by
     * the class which originally called the method. The called method
     * and caller class are determined using the currents thread stack
     * trace.
     * 
     * @return <code>true</code> if access to the method is allowed
     *         for the caller class, <code>false</code> otherwise.
     *         In this case a log message is printed.
     */
    private boolean accessAllowed() {
        StackTraceElement[] elems = Thread.currentThread().getStackTrace();
        String methodName = elems[methodIndex].getMethodName();
        String callerClassName = elems[methodIndex + 1].getClassName();

        callerClassName = ClassUtils.getShortClassName(callerClassName);
        if (!accessControl.get(methodName).contains(callerClassName)) {
            accessNotAllowed(methodName, callerClassName);
            return false;
        }
        return true;
    }

    /**
     * Gets the description of the original plugin.
     * 
     * @return the description of the plugin
     * @see de.xirp.plugin.IPlugable#getDescription()
     */
    public String getDescription() {
        return originalPlugin.getDescription();
    }

    /**
     * Gets the key used for translating the description for this
     * plugin if access is allowed for the caller class.
     * 
     * @return the key for the description or an empty string if
     *         access was not allowed.
     * @see de.xirp.plugin.IPlugable#getDescriptionKey()
     */
    public String getDescriptionKey() {
        if (accessAllowed()) {
            return originalPlugin.getDescriptionKey();
        }
        return ""; //$NON-NLS-1$
    }

    /**
     * Gets the UI of the current plugin if access is allowed for the
     * caller class.
     * 
     * @param parentPanel
     *            the parent panel to build the UI upon
     * @return the UI or <code>null</code> if access was not
     *         allowed.
     * @see de.xirp.plugin.IPlugable#getGUI(org.eclipse.swt.widgets.Composite)
     */
    public GAbstractPluginGUI getGUI(Composite parentPanel) {
        if (accessAllowed()) {
            return originalPlugin.getGUI(parentPanel);
        }
        return null;
    }

    /**
     * Gets the identifier of the current plugin if access is allowed
     * for the caller class.
     * 
     * @return the identifier of the plugin or <code>null</code> if
     *         access was not allowed.
     * @see de.xirp.plugin.IPlugable#getIdentifier()
     */
    public String getIdentifier() {
        if (accessAllowed()) {
            return originalPlugin.getIdentifier();
        }
        return null;
    }

    /**
     * Gets the information about the plugin.
     * 
     * @return the information about the plugin.
     * @see de.xirp.plugin.IPlugable#getInfo()
     */
    public PluginInfo getInfo() {
        return originalPlugin.getInfo();
    }

    /**
     * Access for this method is not allowed.
     * 
     * @return <code>-1</code>
     * @see de.xirp.plugin.IPlugable#getInstanceID()
     */
    public int getInstanceID() {
        if (accessAllowed()) {
            return originalPlugin.getInstanceID();
        }
        return -1;
    }

    /**
     * Gets the name of the plugin.
     * 
     * @return the name of the plugin.
     * @see de.xirp.plugin.IPlugable#getName()
     */
    public String getName() {
        return originalPlugin.getName();
    }

    /**
     * Gets the key used for translating the name of the plugin if
     * access is allowed for the caller class.
     * 
     * @return the name key of the plugin or an empty string if access
     *         was not allowed.
     * @see de.xirp.plugin.IPlugable#getNameKey()
     */
    public String getNameKey() {
        if (accessAllowed()) {
            return originalPlugin.getNameKey();
        }
        return ""; //$NON-NLS-1$
    }

    /**
     * Gets the type of the plugin.
     * 
     * @return the type of the plugin
     * @see de.xirp.plugin.IPlugable#getPluginType()
     */
    public int getPluginType() {
        return originalPlugin.getPluginType();
    }

    /**
     * Gets the report of this plugin.
     * 
     * @return the report of this plugin.
     * @see de.xirp.plugin.IPlugable#getReport()
     */
    public Report getReport() {
        return originalPlugin.getReport();
    }

    /**
     * Gets the robot name of this plugin
     * 
     * @return the name of the robot of this plugin
     * @see de.xirp.plugin.IPlugable#getRobotName()
     */
    public String getRobotName() {
        return originalPlugin.getRobotName();
    }

    /**
     * Gets the settings of this plugin if access is allowed for the
     * caller class.
     * 
     * @return the settings of this plugin or <code>null</code> if
     *         access was not allowed.
     * @see de.xirp.plugin.IPlugable#getSettings()
     */
    public Settings getSettings() {
        if (accessAllowed()) {
            return originalPlugin.getSettings();
        }
        return null;
    }

    /**
     * Gets the toolbar of this plugin if access is allowed for the
     * caller class.
     * 
     * @param parent
     *            the parent for the toolbar
     * @return the toolbar or <code>null</code> if access was not
     *         allowed.
     * @see de.xirp.plugin.IPlugable#getToolBar(org.eclipse.swt.widgets.CoolItem)
     */
    public XToolBar getToolBar(CoolItem parent) {
        if (accessAllowed()) {
            return originalPlugin.getToolBar(parent);
        }
        return null;
    }

    /**
     * Gets the visualization type for this plugin.
     * 
     * @return the visualization type
     * @see de.xirp.plugin.IPlugable#getVisualizationType()
     */
    public int getVisualizationType() {
        return originalPlugin.getVisualizationType();
    }

    /**
     * Checks if this plugin may generate a report.
     * 
     * @return <code>true</code> if the plugin has a report
     * @see de.xirp.plugin.IPlugable#hasReport()
     */
    public boolean hasReport() {
        return originalPlugin.hasReport();
    }

    /**
     * Checks if the plugin is running.
     * 
     * @return <code>true</code> if the plugin is running.
     * @see de.xirp.plugin.IPlugable#isRunning()
     */
    public boolean isRunning() {
        return originalPlugin.isRunning();
    }

    /**
     * Access to this method is not allowed.
     * 
     * @see de.xirp.plugin.IPlugable#preLoad()
     */
    public void preLoad() {
        accessNotAllowed("preLoad"); //$NON-NLS-1$
    }

    /**
     * Gets the list of required libraries for this plugin if access
     * is allowed for the caller class.
     * 
     * @return list of required plugins or an empty list of access is
     *         not allowed.
     * @see de.xirp.plugin.IPlugable#requiredLibs()
     */
    @SuppressWarnings("unchecked")
    public List<String> requiredLibs() {
        if (accessAllowed()) {
            List<String> reqLibs = originalPlugin.requiredLibs();
            if (reqLibs != null) {
                return Collections.unmodifiableList(reqLibs);
            }
            return Collections.emptyList();
        }
        return Collections.emptyList();
    }

    /**
     * Access to this method is not allowed. Use the
     * {@link PluginManager} to run a plugin.
     * 
     * @see de.xirp.plugin.IPlugable#run()
     */
    public void run() {
        accessNotAllowed("run"); //$NON-NLS-1$
    }

    /**
     * Access to this method is not allowed.
     * 
     * @param id
     *            (unused)
     * @see de.xirp.plugin.IPlugable#setIdentifier(java.lang.String)
     */
    public void setIdentifier(@SuppressWarnings("unused") String id) {
        accessNotAllowed("setIdentifier"); //$NON-NLS-1$
    }

    /**
     * Access to this method is not allowed.
     * 
     * @param id
     *            (unused)
     * @see de.xirp.plugin.IPlugable#setInstanceID(int)
     */
    public void setInstanceID(@SuppressWarnings("unused") int id) {
        accessNotAllowed("setInstanceID"); //$NON-NLS-1$
    }

    /**
     * Access to this method is not allowed.
     * 
     * @param robotName
     *            (unused)
     * @see de.xirp.plugin.IPlugable#setRobot(java.lang.String)
     */
    public void setRobot(@SuppressWarnings("unused") String robotName) {
        accessNotAllowed("setRobot"); //$NON-NLS-1$
    }

    /**
     * Access to this method is not allowed. Use the
     * {@link PluginManager} to stop a plugin.
     * 
     * @return <code>false</code>
     * @see de.xirp.plugin.IPlugable#stop()
     */
    public boolean stop() {
        accessNotAllowed("stop"); //$NON-NLS-1$
        return false;
    }

    /**
     * Sets the locale for this plugin if access for the caller class
     * is allowed.
     * 
     * @see de.xirp.plugin.IPlugable#setLocale(java.util.Locale)
     */
    public void setLocale(Locale locale) {
        if (accessAllowed()) {
            originalPlugin.setLocale(locale);
        }
    }

    /**
     * Gets the handler used for translations for this plugin.
     * 
     * @return the translation handler of this plugin
     * @see de.xirp.plugin.IPlugable#getHandler()
     */
    public PluginI18NHandler getHandler() {
        return originalPlugin.getHandler();
    }

    /**
     * @see de.xirp.plugin.IPlugable#getWindowStyle()
     */
    @Override
    public int getWindowStyle() {
        return originalPlugin.getWindowStyle();
    }

}