All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.spardat.xma.session.XMASessionClient Maven / Gradle / Ivy

There is a newer version: 6.0.2
Show newest version
/*******************************************************************************
 * Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     s IT Solutions AT Spardat GmbH - initial API and implementation
 *******************************************************************************/

// @(#) $Id: XMASessionClient.java 2611 2008-06-23 13:01:55Z gub $
package at.spardat.xma.session;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;

import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import at.spardat.enterprise.exc.Notification;
import at.spardat.enterprise.exc.SysException;
import at.spardat.xma.baserpc.BaseRPCClient;
import at.spardat.xma.boot.BootRuntime;
import at.spardat.xma.boot.comp.AppContainer;
import at.spardat.xma.boot.component.IComponent;
import at.spardat.xma.boot.component.IRtXMASessionClient;
import at.spardat.xma.boot.logger.LogLevel;
import at.spardat.xma.boot.logger.Logger;
import at.spardat.xma.boot.transport.XMA_URI;
import at.spardat.xma.component.ComponentClient;
import at.spardat.xma.component.IComponentClient;
import at.spardat.xma.component.ProxyHandler;
import at.spardat.xma.event.global.GlobalEvent;
import at.spardat.xma.event.global.GlobalEventListener;
import at.spardat.xma.exception.Codes;
import at.spardat.xma.page.NotificationBox;
import at.spardat.xma.pipes.XMAPipe;
import at.spardat.xma.plugins.PluginManager;
import at.spardat.xma.plugins.PluginManagerClient;
import at.spardat.xma.security.XMACallbackHandler;
import at.spardat.xma.security.XMAContext;
import at.spardat.xma.security.XMALoginContext;

/**
 * Manages all active Components at the client that are executing in a single
 * JVM and belong to exactly one server side application instance.
 */
public class XMASessionClient extends XMASession implements IRtXMASessionClient {

    private static final String PIPE_NAME = "at.spardat.xma.pipename";

    /**
     * The highest id assigned to a component in this session so far.
     */
    private short lastComponentId_;

    /**
     * Holds a collection of Short s which are ids of components
     * which have been destructed at the client but the server does not know
     * anything about the destruction yet. Only stateful components needs to be
     * managed here.
     */
    private ArrayList deadComponents_ = new ArrayList();

    /**
     * Manages a collection of Component s that have been registered
     * but not yet removed.
     */
    private ArrayList components_ = new ArrayList();

    /**
     * The Id of the Session. If HTTP is used for Communiction the Id is the
     * cookie.
     */
    private String id;

    /**
     * The PluginManager is responsible for providing plugin implementations for
     * provided interface names at the session level.
     */
    private PluginManagerClient pluginManager_ = new PluginManagerClient(this);

    /**
     * for client side login via JAAS.
     */
    private XMALoginContext loginContext;

    /**
     * the uri of the corresponding server application
     */
    private XMA_URI baseUri;

    /**
     * informations about the application prepared by the boot runtime.
     */
    private AppContainer appContainer_;

    /**
     * client side logger
     */
    private Logger log;

    /**
     * timer for calling keepAlive periodically
     */
    private Timer keepAliveTimer;

    /**
     * default intervall between keepAlive calls in seconds. It is only used if
     * the property boot.session.keepalive_interval cannot be read from
     * at.spardat.xma.boot.bootcfg.properties or is not a number.
     */
    public final static int defaultKeepAliveInterval = 3300;

    /**
     * allready logged in on the server
     */
    private boolean serverLoggedIn = false;

    /**
     * need to encrypt the communication for preLoginInfo, login, contextchange,
     * logout
     */
    private boolean needEncryption = false;

    /**
     * client side properties vom XProperties-system.
     */
    private Properties runtimeProperties;

    /**
     * contains all external-event-listeners for this Session
     */
    private List externalEventlisteners;

    /**
     * The thread listening for external events via Pipes
     */
    private PipeListenerThread pipeListenerThread;

    /**
     * display needed for showException() and syncExec().
     */
    Display display;

    /**
     * if display was created newly it has to be disposed on logout().
     */
    private boolean doDisposeDisplay;

    /**
     * stores the GlobalEventListeners
     */
    private List globalEventListeners;

    /**
     * Constructor.
     */
    public XMASessionClient(XMA_URI uri, AppContainer appcIn) {

        appContainer_ = appcIn;
        baseUri = uri;
        log = Logger.getLogger("Session: " + uri.toString());
    }

    /**
     * Does a client and server side login with the configured authentication plugin.
     * @return true if the login succeeded, false otherwise
     * @throws SysException if the authentication plugin does not provide
     *      exactly one {@link XMAContext}, or some Exception occured in the
     *      authentication plugin.
     */
    public boolean login() {
        return login(new Properties());
    }

    /**
     * Does a client and server side login with the configured authentication plugin.
     * @param props input data for the login module; will be propagated as options to initialize.
     * @return true if the login succeeded, false otherwise
     * @throws SysException if the authentication plugin does not provide
     *      exactly one {@link XMAContext}, or some Exception occured in the
     *      authentication plugin.
     */
    public boolean login(Properties props) {
        boolean success = false;
        try {
            createDisplay();
            serverLoggedIn=false;
            loginContext = new XMALoginContext(new XMACallbackHandler(this), pluginManager_,props);
            loginContext.login();
            Set principals = loginContext.getSubject().getPrincipals(XMAContext.class);
            if (principals.size() != 1) {
                throw new RuntimeException("ambigous user: "
                        + loginContext.getSubject().toString());
            }
            if (serverLoggedIn) {
                success = true;
            } else {
                success = loginServer(loginContext.getSubject());
                if (!success) {
                    showException(new Notification(Codes
                            .getText(Codes.LOGIN_DENIED_SERVER))
                            .setCode(Codes.LOGIN_DENIED_SERVER));
                    loginContext.logout();
                }
            }
        } catch (LoginException lexc) {
            showException(new Notification(Codes.getText(Codes.LOGIN_DENIED))
                    .setCode(Codes.LOGIN_DENIED));
            return false;

        } catch (Exception exc) {
            showException(new SysException(exc, Codes
                    .getText(Codes.LOGIN_TECHNICAL_ERROR)).setCode(
                            Codes.LOGIN_TECHNICAL_ERROR).setShowToEndUser(true));
            if (loginContext != null) {
                try {
                    loginContext.logout();
                } catch (Exception e) {
                    log.log(LogLevel.WARNING, "exception:", e);
                }
            }
            return false;
        }

        //create Pipe and start listener
        if(success){
            try {
                startPipeListener(props);
            } catch (IOException e) {
                showException(new SysException(e, Codes
                        .getText(Codes.WINREUSE_STARTUP)).setCode(
                                Codes.WINREUSE_STARTUP).setShowToEndUser(true));

                logout();
                return false;
            }
        }

        return success;
    }

    /**
     * Creates the Display (getCurrent() / getDefault()).
     *
     * @since version_number
     * @author s3460
     */
    private void createDisplay() {
        display = Display.getCurrent();
        if (display == null) {
            display = Display.getDefault();
            doDisposeDisplay = true;
        } else {
            doDisposeDisplay = false;
        }
    }

    /**
     * Creates und starts the PipeListenerThread daemon.
     *
     * @since version_number
     * @author s3460
     */
    private void startPipeListener(Properties prop) throws IOException {
        String pipeName = getPipeName(prop);

        if (pipeName != null) {
            pipeListenerThread = new PipeListenerThread(this, createPipe(pipeName));
            pipeListenerThread.start();
        }
    }

    /**
     * creates a Pipe
     * @param pipeName
     * @return
     * @throws IOException
     * @since version_number
     * @author s3460
     */
    private XMAPipe createPipe(String pipeName) throws IOException{
        XMAPipe pipe = null;

        for (int i = 0; i < 2; i++) {
            try {
                pipe = XMAPipe.getInstance(pipeName);
                break;
            } catch (IOException e) {
                log.log(LogLevel.WARNING, "can't create XMAPipe " + i + ". Try :", e);
                if (i == 1) {
                    log.log(LogLevel.SEVERE, "No pipe can be created -> throw IOException",e);
                    throw e;
                }
            }
            //sleep for 2. try
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }

        return pipe;
    }

    /**
     * The pipename can be set by the XMABootruntime caller.
     * TODO: also set or enable by XProperties
     * @return
     * @since version_number
     * @author s3460
     */
    private String getPipeName(Properties prop){
        return prop.getProperty(PIPE_NAME);
    }

    /**
     * Shows an Exception in a MessageBox.
     *
     * @param exc
     *            the catched Exception
     */
    private void showException(Object exc) {
        Shell shell = display.getActiveShell();
        if (shell == null)
            shell = new Shell(display);

        XMAContext context = null;
        if (loginContext != null) {
            Set principals = loginContext.getSubject().getPrincipals(XMAContext.class);
            if (principals.size() > 0) {
                context = (XMAContext) principals.iterator().next();
            }
        }
        if (context == null) {
            context = new XMAContext() {
                public Locale getLocale() {
                    return Locale.getDefault();
                }

                public String getMandant() {
                    return "";
                }

                public String getEnvironment() {
                    return XMAContext.prod;
                }

                public boolean isLocal() {
                    return false;
                }

                public String getName() {
                    return "";
                }
            };
        }

        NotificationBox.show(exc, shell, context, this);
        if (exc instanceof Throwable) {
            log.log(LogLevel.WARNING, "exception:", (Throwable) exc);
        } else {
            log.log(LogLevel.WARNING, "notification: {0}", exc);
        }
    }

    /**
     * Returns the execution context of this session. All callers of this method
     * may rely on the fact that the information stored in the
     * XMAContext remain stable, i.e., won't change over the lifetime
     * of this session. This pertains to the authenticated user, the mandant and
     * the environment.
     *
     * @return context never null.
     */
    public XMAContext getContext() {
        Set principals = loginContext.getSubject().getPrincipals(XMAContext.class);
        return (XMAContext) principals.iterator().next();
    }

    /**
     * Returns the subject as supplied by the JAAS conforming login module.
     *
     * @return the subject provided by the login module.
     */
    public Subject getSubject() {
        return loginContext.getSubject();
    }

    /**
     * Registers a Component with this Session. Must only be called
     * from class ComponentClient.
     *
     * @param c
     *            the Component to register.
     */
    public void registerComponent(ComponentClient c) {
        components_.add(c);
        c.setId(++lastComponentId_);
    }

    /**
     * Deregisters a given Component. The same component must have
     * been registered before. Must only be called from class
     * ComponentClient.
     *
     * @param c
     *            the Component to deregister.
     */
    public void removeComponent(ComponentClient c) {
        if (!components_.remove(c))
            throw new IllegalStateException();
        if (!c.isStateless()) {
            deadComponents_.add(new Short(c.getId()));
        }
    }

    /**
     * Returns a newly created array of ids of dead components.
     *
     * @return an array of component ids. The length of the array may be zero if
     *         there are no dead components.
     */
    public short[] getIdsOfDeadComponents() {
        short[] ids = new short[deadComponents_.size()];
        for (int i = 0; i < ids.length; i++) {
            ids[i] = ((Short) deadComponents_.get(i)).shortValue();
        }
        return ids;
    }

    /**
     * Empties the list of dead component ids.
     */
    public void resetDeadComponentList() {
        deadComponents_.clear();
    }

    /**
     * Returns an Iterator over the list of registered Components.
     */
    public Iterator getComponents() {
        return components_.iterator();
    }

    /**
     * Gets the id of the session; with http-comunication this is the session
     * cookie.
     *
     * @return the id of the session
     */
    public String getId() {
        return id;
    }

    /**
     * Sets the id of the session; with http-comunication this is the session
     * cookie. This method must only be called by the runtime!
     *
     * @param string
     *            the new session id.
     */
    public void setId(String string) {
        id = string;
    }

    /**
     * Gets the application-uri
     *
     * @return the uri of the corresponding server application
     */
    public XMA_URI getUri() {
        return new XMA_URI(baseUri);
    }

    /**
     * Returns the PluginManager that must be used to retrieve client side
     * plugin implementations.
     *
     * @return a PluginManagerClient that is never null.
     */
    public PluginManager getPluginManager() {
        return pluginManager_;
    }

    /**
     * Does a client and server side logout with the configured authentication
     * plugin. This method must only be called by the runtime!
     */
    public void logout() {
        try {
            loginContext.logout();
        } catch (LoginException exc) {
            log.log(LogLevel.WARNING, "exception:", exc);
        }
        if (serverLoggedIn) {
            logoutServer();
        }

        if (pipeListenerThread != null)
            pipeListenerThread.stopThread();
        if (doDisposeDisplay && display != null)
            display.dispose();
    }

    /**
     * Does a server side login. This creates an authenticated Session on the
     * server on success. This method must only be called by the login module or
     * the runtime!
     *
     * @return true if the login succeeds 
* false otherwise */ public boolean loginServer(Subject subject) { if (runtimeProperties == null) { serverGetPreLoginInfo(); } BaseRPCClient rpc = new BaseRPCClient("login", "session", this); rpc.setNeedEncryption(needEncryption); rpc.setUnserializableCollection(0, subject.getPrincipals()); rpc.setUnserializableCollection(1, subject.getPublicCredentials()); rpc.execute(); boolean loginOk = ((Boolean) rpc.getParameter(0)).booleanValue(); subject.getPrincipals().clear(); subject.getPrincipals().addAll(rpc.getUnserializableCollection(1)); subject.getPublicCredentials().clear(); subject.getPublicCredentials().addAll(rpc.getUnserializableCollection(2)); if (loginOk) { startKeepAlive(); serverLoggedIn = true; return true; } else { return false; } } /** * Gets the pre login information from the server. This method must only be * called by the login module or the runtime! * * @return the information send by the server */ public Object serverGetPreLoginInfo() { runtimeProperties = new Properties(); BaseRPCClient rpc = new BaseRPCClient("getPreLoginInfo", "session", this); // rpc.setNeedEncryption(needEncryption); String version; try { Class cl = Class.forName("at.spardat.xma.boot.util.Version"); Object obj = cl.newInstance(); version = (String) cl.getMethod("getVersion",null).invoke(obj,null); } catch (Exception e) { version = "<1.4.0"; log.log(LogLevel.INFO,"at.spardat.xma.boot.util.Version is not available -> Bootrt-Version: <1.4.0"); } rpc.setParameter(0,version); try { rpc.setParameter(1,InetAddress.getLocalHost().getHostAddress()); } catch (UnknownHostException e) { log.log(LogLevel.WARNING,"The clients IP adress can not be resolved and is not transmitted to the server",e); } rpc.execute(); boolean loginOk = ((Boolean) rpc.getParameter(0)).booleanValue(); Object result = null; if (loginOk) { result = rpc.getParameter(1); } // handle properties for client side String props = (String) rpc.getParameter(2); for (StringTokenizer tok = new StringTokenizer(props, "\n"); tok.hasMoreTokens();) { String key = tok.nextToken(); String value = tok.nextToken(); runtimeProperties.setProperty(key, value); } return result; } /** * Starts the keepAliveTimer. keepAlive() will be called periodically. * The intervall is defined in the property xma.runtime.keepalive_interval. * If this property is not set, the bootruntime property boot.session.keepalive_interval is used. * If it cannot be read or is not a number, defaultKeepAliveInterval (55 min) is used instead. *

* Keepalive can be disabled completeley by setting the property * xma.runtime.doKeepAlive=false. */ private void startKeepAlive() { if("false".equalsIgnoreCase(getRuntimeProperty("doKeepAlive","true"))) return; keepAliveTimer = new Timer(true); long timeout; try { String number = getRuntimeProperty("keepAliveInterval"); if(number==null) { Properties props = BootRuntime.getInstance().getConfigProperties(); number = props.getProperty("boot.session.keepalive_interval"); } timeout = Integer.parseInt(number) * 1000; if (timeout <= 0) timeout = defaultKeepAliveInterval * 1000; } catch (Exception e) { timeout = defaultKeepAliveInterval * 1000; } keepAliveTimer.schedule(new TimerTask() { public void run() { keepAlive(); } }, timeout, timeout); } /** * Does an empty server request to prevent inactivity timeout. * * @return true on success
* false in case of communication problems */ public boolean keepAlive() { try { new BaseRPCClient("keepAlive", "session", this).execute(); return true; } catch (Exception e) { log.log(LogLevel.WARNING, "exception:", e); return false; } } /** * Stops the keepAliveTimer. No more periodically keepAlives will be send. */ private void stopKeepAlive() { if(keepAliveTimer!=null) keepAliveTimer.cancel(); } // /** // * Does a server side logout. This destroyes the server session. // * This method must only be called by the runtime! // * @return true on success
// * false in case of communication problems // */ // private boolean logoutServer() { // serverLoggedIn=false; // stopKeepAlive(); // XMA_URI uri = new XMA_URI(baseUri); // uri.setResource("session"); // uri.addParameter("operation","logout"); // if(needEncryption&&!"https".equals(uri.getProtocol_())) { // String port = runtimeProperties.getProperty("SSLPort","443"); // uri.setProtocol("https"); // uri.setPort(new Integer(port).intValue()); // } // try{ // Transport.getTransport().callServerEvent(this,uri,new byte[0]); // return true; // } catch (CommunicationException e) { // log.log(LogLevel.WARNING, "exception:", e); // return false; // } // } /** * Does a server side logout. This destroyes the server session. This method * must only be called by the runtime! * * @return true on success
* false in case of communication problems */ private boolean logoutServer() { serverLoggedIn = false; stopKeepAlive(); try { BaseRPCClient rpc = new BaseRPCClient("logout", "session", this); rpc.setNeedEncryption(needEncryption); rpc.execute(); return true; } catch (Exception e) { log.log(LogLevel.WARNING, "exception:", e); return false; } } /** * Does a server side context change. This changes the subject in the server * side session on success. This method must only be called by the login * module or the runtime! * * @return true if the login succeeds
* false otherwise */ public boolean contextChangeServer(Subject subject) { BaseRPCClient rpc = new BaseRPCClient("contextChanged", "session", this); rpc.setNeedEncryption(needEncryption); rpc.setUnserializableCollection(0, subject.getPrincipals()); rpc.setUnserializableCollection(1, subject.getPublicCredentials()); rpc.execute(); boolean loginOk = ((Boolean) rpc.getParameter(0)).booleanValue(); subject.getPrincipals().clear(); subject.getPrincipals().addAll(rpc.getUnserializableCollection(1)); subject.getPublicCredentials().clear(); subject.getPublicCredentials().addAll(rpc.getUnserializableCollection(2)); if (loginOk) { return true; } else { return false; } } /** * Get the application container used by the boot runtime to manage the * component files of this application. * * @return the application container of this session. */ public AppContainer getAppContainer() { return appContainer_; } /** * Creates a Component of the same application. The implementation of the * component is located and downloaded if necessary. * * @param componentName * the relative uri of the desired component. relative uris are * relative to the uri of this session (see {@link #getUri}). * @return the initialized Component */ public IComponentClient getComponent(String componentName) { try { XMA_URI application = new XMA_URI(this.getUri()); application.setComponent(componentName); String url = application.getHTTP_URI().toString(); return (IComponentClient) appContainer_.getAppManager().getComponent(url); } catch (Exception e) { throw new SysException(e, Codes.getText(Codes.CANNOT_CONSTRUCT_COMPONENT)) .setCode(Codes.CANNOT_CONSTRUCT_COMPONENT).setShowToEndUser(true); } } /** * Creates a Component from an other application. The implementation of the * component is located and downloaded if necessary. * * @param componentName * the absolute uri of the desired component in another * webapplication. * @return the initialized Component */ public IComponentClient getComponentExtern(String componentName) { try { Object comp = appContainer_.getAppManager().getComponent(componentName); return (IComponentClient) ProxyHandler.bridgeClassLoaders(this.getClass() .getClassLoader(), comp); } catch (Exception e) { throw new SysException(e, Codes.getText(Codes.CANNOT_CONSTRUCT_COMPONENT)) .setCode(Codes.CANNOT_CONSTRUCT_COMPONENT).setShowToEndUser(true); } } /** * Launch method for modal Components of the same application. * * @param component * relative name of the component within the application * @param input * input properties * @return Properties */ public Properties launchRelative(String component, Properties input, Composite parent) { IComponent cmp = null; try { cmp = getComponent(component); cmp.setProperties(input); cmp.invoke(parent); Properties out = cmp.getProperties(); return out; } finally { if (cmp != null) cmp.dispose(); } } /** * Launch method for modal Components of other applications. * * @param component * abslute uri of the component * @param input * input properties * @return Properties */ public Properties launchExtern(String component, Properties input, Composite parent) { IComponent cmp = null; try { cmp = getComponentExtern(component); cmp.setProperties(input); cmp.invoke(parent); Properties out = cmp.getProperties(); return out; } finally { if (cmp != null) cmp.dispose(); } } /** * Get the client side logger * * @return the client side logger */ public Logger getLogger() { return log; } /** * Application Hash-Code built from application descriptors. * * @return Application Version Hash-Code */ public byte[] getApplicationVersion() { return getAppContainer().getDigest(); } /** * Get if this session uses SSL-Encryption for session management calls to * the server. (login, logoff, prelogininfo, contextchange) * * @return if SSL-Encryption will be used * @since 1.4.0 */ public boolean isNeedEncryption() { return needEncryption; } /** * Sets if SSL-Encryption is neccessary for session management calls to the * server. (login, logoff, prelogininfo, contextchange) * * @param enc * true means use SSL-Encryption * @since 1.4.0 */ public void setNeedEncryption(boolean enc) { if (enc) { try { baseUri.getClass().getMethod("setProtocol", new Class[] { String.class }); } catch (Exception e) { throw new IllegalStateException("encryption not supported"); } } needEncryption = enc; } /** * Returns the property with the specified key in the runtime properties. * The method returns null if the property is not found. * * @param key * the hashtable key. * @return the value for the specified key. */ public String getRuntimeProperty(String key) { return runtimeProperties!=null?runtimeProperties.getProperty(key):null; } /** * Returns the property with the specified key in the runtime properties. * The method returns the default value argument if the property is not * found. * * @param key * the hashtable key. * @param defaultValue * a default value. * @return the value for the specified key. */ public String getRuntimeProperty(String key, String defaultValue) { return runtimeProperties!=null?runtimeProperties.getProperty(key, defaultValue):defaultValue; } public byte[] inverseTransform(String transform, byte[] data) { return Transform.decode(transform, data); } /** * Adds an ExternalEventListener to the listeners of the session. * * @param listener * @since version_number * @author s3460 */ public void addExternalEventListener(ExternalEventListener listener) { if (externalEventlisteners == null) externalEventlisteners = new ArrayList(1); if (!externalEventlisteners.contains(listener)) externalEventlisteners.add(listener); } /** * Removes an ExternalEventListener to the listeners of the session. * * @param listener * @since version_number * @author s3460 */ public void removeExternalEventListener(ExternalEventListener listener) { if (externalEventlisteners != null) { externalEventlisteners.remove(listener); if (externalEventlisteners.size() == 0) externalEventlisteners = null; } } /** * notifies all listeners of the ExternalEvent. * * @param event * @return null if there are not return values * @since version_number * @author s3460 */ public Properties notifyExternalEvent(ExternalEvent event) { Properties allProps = null; if (externalEventlisteners != null) { for (Iterator it = externalEventlisteners.iterator(); it.hasNext();) { ExternalEventListener listener = (ExternalEventListener) it.next(); try { Properties prop = listener.externalEvent(event); if (prop != null) { if (allProps == null) { allProps = new Properties(); } allProps.putAll(prop); } } catch (Exception e) { showException(e); } } } return allProps; } /** * @see at.spardat.xma.session.XMASession#isAtServer() */ public boolean isAtServer() { return false; } /** * The added GlobalEventListener will be notifyed by server events. * (by pollServerSideEvents()). */ public void addGlobalEventListener(GlobalEventListener listener) { if (globalEventListeners == null){ globalEventListeners = new ArrayList(1); } if (!globalEventListeners.contains(listener)) { globalEventListeners.add(listener); } } /** * removes the GlobalEventListener. */ public boolean removeGlobalEventListener(GlobalEventListener listener) { boolean removed = false; if (globalEventListeners != null) { removed = globalEventListeners.remove(listener); if (globalEventListeners.size() == 0) globalEventListeners = null; } return removed; } /** * iterates over the registered GlobalEventsListers and calls globalEvent(). * @param event * @since version_number * @author s3460 */ private void iterateGlobalEventListener(GlobalEvent event){ if (globalEventListeners != null) { for (Iterator iter = globalEventListeners.iterator(); iter.hasNext();) { GlobalEventListener element = (GlobalEventListener) iter.next(); try { element.globalEvent(event); } catch (Exception e) { getLogger().log(LogLevel.SEVERE,"Exception in GlobalEventListener " + element.toString(),e); showException(e); } } } } /** * Calls globalEvent() at the registered listeners with the * GlobalEvents from the paramter globalEvents. * The listeners are called by display.asyncExec(). * * @param globalEvents Collection with GlobalEvents. * @since version_number * @author s3460 */ public void callGlobalEventListener(Collection globalEvents){ //inner class - to execute in display.asyncExec() class GlobalEventListenerRunner implements Runnable { Collection events; GlobalEventListenerRunner(Collection events){ this.events = events; } public void run() { if(serverLoggedIn){//execute events only if still logged in for (Iterator iter = events.iterator(); iter.hasNext();) { GlobalEvent element = (GlobalEvent) iter.next(); iterateGlobalEventListener(element); } } } } //execution of inner class GlobalEventListenerRunner runner = new GlobalEventListenerRunner(globalEvents); display.asyncExec(runner); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy