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

at.spardat.xma.event.global.GlobalEventManager Maven / Gradle / Ivy

/*******************************************************************************
 * 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: GlobalEventManager.java 3088 2009-01-30 16:10:02Z gub $
 *
 *
 *
 *
 *
 */
package at.spardat.xma.event.global;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;

import at.spardat.enterprise.exc.SysException;
import at.spardat.properties.XProperties;
import at.spardat.xma.session.XMASessionServer;

/**
 * This singleton class serves for creating, sending and polling GlobalEvents.
 * To send an event means to store it for this server in an GlobalEventmanager internal Map,
 * for the accesss of other servers the events are also stored in an JNDI tree.
 * Polling means to ask the map and the JNDI tree for undelivered events and to return
 * a collection with them.
 * GlobalEventListener for the server side GlobalEvents have to be registerd at this class (addGlobalEventListener()).
 * GlobalEventListener for the client side GlobalEvents have to be registerd at the XMASessionClient (addGlobalEventListener()).
 *
 * @author s3460
 * @since version_number
 */
public class GlobalEventManager {

    private static final String CTX_EVENTS = "at.spardat.xma.globalevents";

    private final String CTX_EVENTS_SCOPE;

    private static final String COUNT = "count";

    private static final long POLLING_INTERVAL_MILLIS = 5000;

    private static final String ACTIVATE_GLOBAL_EVENTS = "activateGlobalEvents";

    private static GlobalEventManager instance;
    //stores the GlobalEventListeners
    private List globalEventListeners;
    //high count of events sent by this GlobalEventManager
    private int highCount = 0;

    /**
     * server name of this GlobalEventManager instance
     */
    private String _serverName;

    private Context initCtx; //used to look up bindings

    private Context serverCtx; //used to bind new events

    /**
     * serverName/highCounts
     * stores the last highCoubnst received - used for pollServerSideEvents()
     */
    private Map myServerHighCounts = new HashMap();

    /**
     * mirrors the JNDI tree
     * key: servername_eventcount - value: GlobalEvent
     * the events sent by this GlobalEventManager are stored imidiately in this map (for Tomcat)
     */
    private Map eventMap = new HashMap();

    /**
     * mirrors the servers and their highCounts in the JNDI tree
     * servername/highCounts
     */
    private Map serverMap = new HashMap();

    /**
     *
     */
    private long lastPollingTimeMillis = 0;

    /**
     * Returns a singleton GlobalEventManager object.
     * Can only be called if xma.runtime.activateGlobalEvents!="false" ("false" is default).
     * @return @since version_number
     * @author s3460
     * @exception SysException - if xma.runtime.activateGlobalEvents is set to "false"
     */
    public static GlobalEventManager getInstance() {
        if (instance == null) {
            if(isGlobalEventActivated()){
                instance = new GlobalEventManager();
            }else{
                throw new SysException("GlobalEventManager is used but 'xma.runtime.activateGlobalEvents'is set to 'false'");
            }
        }

        return instance;
    }

    /**
     *  singleton Constructor
     */
    private GlobalEventManager() {
        super();
        this.CTX_EVENTS_SCOPE = CTX_EVENTS + "." + getScopeName();
        createServerName();
        createInitContext();
//      Creates the CTX_EVENTS it it does not exits:
        createGlobalEventCtx();
    }

    /**
     *
     * @since version_number
     * @author s3460
     */
    private void createServerName() {
        try {
            //serverName ermitteln by random
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            _serverName = String.valueOf(random.nextInt(Integer.MAX_VALUE));
        } catch (NoSuchAlgorithmException e) {
            throw new SysException(e);
        }
    }

    /**
     * Creates the CTX_EVENTS it it does not exits.
     * Creates a context for the server.
     *
     * @since version_number
     * @author s3460
     */
    private void createInitContext() {
        try {
            initCtx = new InitialContext();
        } catch (NamingException e) {
            throw new SysException(e);
        }
    }

    /**
     * creates subcontext for this server
     *
     * @since version_number
     * @author s3460
     */
    private void createServerContext(){
        try {
            serverCtx = initCtx.createSubcontext(CTX_EVENTS_SCOPE + "." + _serverName);
            //bind initial highCount
            serverCtx.bind(COUNT, new Integer(0));
            //store initial highCount in map
            serverMap.put(_serverName, new Integer(0));
        } catch (NamingException e) {
            throw new SysException(e);
        }
    }

    /**
     * Creates the CTX_EVENTS it it does not exits.
     * @throws NamingException
     * @since version_number
     * @author s3460
     */
    private void createGlobalEventCtx(){
        try {
            try {
                initCtx.lookup("at");
            } catch (NamingException e1) {
                //CTX does not exist
                initCtx.createSubcontext("at");
            }

            try {
                initCtx.lookup("at.spardat");
            } catch (NamingException e1) {
                //CTX does not exist
                initCtx.createSubcontext("at.spardat");
            }

            try {
                initCtx.lookup("at.spardat.xma");
            } catch (NamingException e1) {
                //CTX does not exist
                initCtx.createSubcontext("at.spardat.xma");
            }

            try {
                initCtx.lookup(CTX_EVENTS);
            } catch (NamingException e1) {
                //CTX does not exist
                initCtx.createSubcontext(CTX_EVENTS);
            }

            try {
                initCtx.lookup(CTX_EVENTS_SCOPE);
            } catch (NamingException e1) {
                //CTX does not exist
                initCtx.createSubcontext(CTX_EVENTS_SCOPE);
            }
        } catch (NamingException e) {
            throw new SysException(e);
        }
    }

    /**
     * @return expiration in millisec: now + 1 day
     * @since version_number
     * @author s3460
     */
    private long getDefaultExpiration() {
        //TODO default OK ?
        return System.currentTimeMillis() + 60 * 60 * 24 * 1000;
    }

    /**
     * The added GlobalEventListener will be notifyed by server events (recipient = RECIPIENT_ALL_SERVERS).
     *
     * @param listener
     * @since version_number
     * @author s3460
     */
    public void addGlobalEventListener(GlobalEventListener listener) {
        if (globalEventListeners == null){
            globalEventListeners = new ArrayList(1);
        }
        if (!globalEventListeners.contains(listener)) {
            globalEventListeners.add(listener);
        }
    }

    /**
     * removes the GlobalEventListener.
     * @param listener
     * @return true: if a listener was removed, false otherwise.
     * @since version_number
     * @author s3460
     */
    public boolean removeGlobalEventListener(GlobalEventListener listener) {
        boolean removed = false;

        if (globalEventListeners != null) {
            removed = globalEventListeners.remove(listener);
            if (globalEventListeners.size() == 0)
                globalEventListeners = null;
        }

        return removed;
    }

    /**
     * creates a GlobalEvent with the given name, the default recipient type
     * (RECIPIENT_ALL_CLIENTS_ALL_SERVERS) and the default expiration date (now + 1 day).
     * @param name type of GlobalEvent
     * @return a new created GlobalEvent
     * @since version_number
     * @author s3460
     */
    public GlobalEvent createGlobalEvent(String name) {
        return createGlobalEvent(name, GlobalEvent.RECIPIENT_ALL_CLIENTS_ALL_SERVERS, getDefaultExpiration());
    }

    /**
     * creates a GlobalEvent with the given name, recipient type and the default expiration date (now + 1 day).
     * @param name type of GlobalEvent
     * @param recipient type of recipient: RECIPIENT_ALL_SERVERS, RECIPIENT_ALL_CLIENTS, RECIPIENT_ALL_CLIENTS_ALL_SERVERS
     * @return a new created GlobalEvent
     * @since version_number
     * @author s3460
     */
    public GlobalEvent createGlobalEvent(String name, int recipient) {
        return createGlobalEvent(name, recipient, getDefaultExpiration());
    }

    /**
     * creates a GlobalEvent with the given name, recipient type and the given expiration date.
     * @param name type of GlobalEvent
     * @param recipient type of recipient: RECIPIENT_ALL_SERVERS, RECIPIENT_ALL_CLIENTS, RECIPIENT_ALL_CLIENTS_ALL_SERVERS
     * @param expiresMilliSec milli seconds after 1970
     * @return a new created GlobalEvent
     * @since version_number
     * @author s3460
     */
    public GlobalEvent createGlobalEvent(String name, int recipient, long expiresMilliSec) {
        return createGlobalEvent(name, recipient, expiresMilliSec,null);
    }

    /**
     * creates a GlobalEvent with the given name, recipient type, the given expiration date and the given session id.
     *
     * The session ID should be given if the creator of the event is the only recipient.
     * So when the session ID is stated then as recipients only GlobalEvent.RECIPIENT_BY_ID (only the listeners of the client with this session ID are called)
     * or RECIPIENT_ALL_SERVERS (only the listeners of all servers and the listeners of the client with this ID are called) make sense.
     * (The session ID it will be evaluated by the GlobalEvent.isEventForClient(String idSession) method.)
     * @param name type of GlobalEvent
     * @param recipient type of recipient: RECIPIENT_ALL_SERVERS, RECIPIENT_ALL_CLIENTS, RECIPIENT_ALL_CLIENTS_ALL_SERVERS
     * @param expiresMilliSec milli seconds after 1970
     * @param sessionId - usually session id of creator.
     * @return a new created GlobalEvent
     * @since version_number
     * @author s3460
     */
    public GlobalEvent createGlobalEvent(String name, int recipient, long expiresMilliSec, String sessionId) {
        return new GlobalEvent(name, recipient, _serverName, expiresMilliSec, sessionId);
    }

    /**
     * creates a GlobalEvent with the given name, the default recipient type
     * (RECIPIENT_ALL_CLIENTS_ALL_SERVERS) and the time from now how long this event is valid.
     *
     * @param name type of GlobalEvent
     * @param timeToLiveMilliSec -
     *            milli seconds (from now) in which this event expires.
     * @return a new created GlobalEvent
     * @since version_number
     * @author s3460
     */
    public GlobalEvent createGlobalEventTTL(String name, long timeToLiveMilliSec) {
        return createGlobalEventTTL(name,GlobalEvent.RECIPIENT_ALL_CLIENTS_ALL_SERVERS, timeToLiveMilliSec);
    }

    /**
     * creates a GlobalEvent with the given name, the given recipient type
     * and the time from now how long this event is valid.
     *
     * @param name type of GlobalEvent
     * @param recipient type of recipient: RECIPIENT_ALL_SERVERS, RECIPIENT_ALL_CLIENTS, RECIPIENT_ALL_CLIENTS_ALL_SERVERS
     * @param timeToLiveMilliSec milli seconds (from now) in which this event expires.
     * @return a new created GlobalEvent
     * @since version_number
     * @author s3460
     */
    public GlobalEvent createGlobalEventTTL(String name, int recipient, long timeToLiveMilliSec) {
        return createGlobalEventTTL(name,recipient, timeToLiveMilliSec, null);
    }

    /**
     * creates a GlobalEvent with the given name, the given recipient type
     * and the time from now how long this event is valid.
     *
     * The session ID should be given if the creator of the event is the only recipient.
     * So when the session ID is stated then as recipients only GlobalEvent.RECIPIENT_BY_ID (only the listeners of the client with this session ID are called)
     * or RECIPIENT_ALL_SERVERS (only the listeners of all servers and the listeners of the client with this ID are called) make sense.
     * (The session ID it will be evaluated by the GlobalEvent.isEventForClient(String idSession) method.)
     *
     * @param name type of GlobalEvent
     * @param recipient type of recipient: RECIPIENT_ALL_SERVERS, RECIPIENT_ALL_CLIENTS, RECIPIENT_ALL_CLIENTS_ALL_SERVERS
     * @param timeToLiveMilliSec milli seconds (from now) in which this event expires.
     * @param sessionId - usually session id of creator.
     * @return a new created GlobalEvent
     * @since version_number
     * @author s3460
     */
    public GlobalEvent createGlobalEventTTL(String name, int recipient, long timeToLiveMilliSec, String sessionId) {
        long expire = System.currentTimeMillis() + timeToLiveMilliSec;
        return createGlobalEvent(name,recipient, expire, sessionId);
    }


    /**
     * Sends this given event to the global data structure.
     * The event is then stored an can be retrieved by pollEvents().
     * @param event
     * @since version_number
     * @author s3460
     * @throws RuntimeException if XProperty 'at.spardat.xma.activateGlobalEvents=true' is not set.
     */
    public synchronized void send(GlobalEvent event) {
        if(!isGlobalEventActivated()){
            throw new RuntimeException("Cant send a GlobalEvent as XProperty 'at.spardat.xma.activateGlobalEvents=true' is not set.");
        }

        if(highCount == 0){//first call to send()
            createServerContext();
        }

        event.setCount(highCount + 1);
        try {
            Integer count = new Integer(event.getCount());
            serverCtx.rebind(COUNT, count);
            //bind event object as map:
            serverCtx.bind(String.valueOf(event.getCount()), event.toMap());
            //reassign highCount in serverMap (imidiately for Tomcat)
            serverMap.put(_serverName,count);
            //store new event imidiately in eventMap (for Tomcat)
            eventMap.put(_serverName + "_" + event.getCount(), event);
            highCount++;
        } catch (NamingException e) {
            throw new SysException(e);
        }
    }

    /**
     * Looks up the new highCount and the new events between oldCount and new
     * highCount. Returns the new highCount.
     *
     * @param serverName
     * @param oldCount
     * @param globalEvents -
     *            Collection of GlobalEvent with objects bound between oldCount
     *            and jndi highCount
     * @return new HighCount or null if server "serverName" exists not anymore
     * @since version_number
     * @author s3460
     */
    private Integer pollFromEventMap(String serverName, int oldCount, Collection globalEvents) {
//      lookup new highCount
        Integer newCount = (Integer) serverMap.get(serverName);
        if(newCount == null){
//          server exists not any more
            return null;
        }

//      lookup new events
        for (int i = oldCount + 1; i <= newCount.intValue(); i++) {
            GlobalEvent event = (GlobalEvent) eventMap.get(serverName + "_" + i);
            if(event != null){
                globalEvents.add(event);
            }
        }

        return newCount;
    }

    /**
     * Returns a Collection of GlobalEvents with objects bound between oldCount (stored in map)
     * and the new highCount of each server (stored in serverMap).
     * The param map is updated to the new highCounts and to new servers.
     * Usually the parameter map is stored in a session.
     *
     * This call only accesses serverMap and eventMap (not JNDI).
     *
     * @param map -
     *            serverName/highCount (String/Integer).
     * @return Collection of GlobalEvents
     * @since version_number
     * @author s3460
     */
    private synchronized Collection pollFromEventMap(Map map) {
        Collection coll = new ArrayList();
        pollNewSevers(map);

        //Iterates over server and polls the events of each server.
        for (Iterator iter = map.keySet().iterator(); iter.hasNext();) {
            String server = (String) iter.next();
            Integer i = (Integer) map.get(server);
            i = pollFromEventMap(server, i.intValue(), coll); //returns new highCount
            if(i != null){
                map.put(server, i); //reassign new highCount
            }else{
               iter.remove(); //server exists not any more
            }
        }

        return coll;
    }

    /**
     * Returns a Collection of GlobalEvents for the client.
     * Server side events are transmitted to the registered server side GlobalEventListener.
     * Only events are returned which were not already transmitted to the client or the server.
     *
     * @return a Collection of GlobalEvents.
     * @since version_number
     * @author s3460
     */
    public Collection pollEvents(){
        //tests if last polling befor this one was more than POLLING_INTERVAL_MILLIS ago.
        if(pollingIntervalElapsed()){
            refreshFromJNDI();
        }
        //poll events for this server and transmitt events to server side listener
        pollServerSideEventsInternal();
        //poll events for client (of actual session)
        Collection coll = pollFromEventMap(
                ((XMASessionServer) XMASessionServer
                        .getXMASession()).getServerHighCounts());

        //remove events which are not for clients and not for this client
        for (Iterator iter = coll.iterator(); iter.hasNext();) {
            GlobalEvent event = (GlobalEvent) iter.next();
            if(!event.isEventForClient() && !event.isEventForClient(((XMASessionServer) XMASessionServer
                        .getXMASession()).getHttpSession().getId())){
                iter.remove();
            }
        }
        //return null if coll is empty
        if(coll.size()>0){
            return coll;
        }
        else{
            return null;
        }
    }

    /**
     * removes expired events from eventMap.
     * @param map
     * @since version_number
     * @author s3460
     */
    private void cleanUpEventMap(){
        for (Iterator iter = this.eventMap.keySet().iterator(); iter.hasNext();) {
            String key = (String) iter.next();
            GlobalEvent event = (GlobalEvent) eventMap.get(key);
            if(event.getExpiresMilliSec() <= System.currentTimeMillis()){
                iter.remove();
            }
        }
    }

    /**
     * removes expired events from JNDI context.
     * @param ctx
     * @since version_number
     * @author s3460
     */
    private void cleanUpSubCtx(Context ctx){
        try {
            for (NamingEnumeration iter = ctx.listBindings(""); iter.hasMore();) {
                Binding element = (Binding) iter.next();
                Object obj = element.getObject();
                //GlobalEvents are stored as map in JNDI tree.
                if (obj instanceof Map) {
                    GlobalEvent event = new GlobalEvent((Map)obj);
                    if((event).getExpiresMilliSec() <= System.currentTimeMillis()){
                        ctx.unbind(element.getName());
                    }
                }
            }
        } catch (NamingException e) {
            // TODO logging
            e.printStackTrace();
        }
    }

    /**
     * Iterates over serverMap and adds new servers to map.
     * The highcount for the new server in map is set to zero,
     * because the client has got not event of the new server yet.
     *
     * @param map -
     *            serverName/highCount (String/Integer)
     * @since version_number
     * @author s3460
     */
    private void pollNewSevers(Map map) {

        for (Iterator iter = serverMap.keySet().iterator(); iter.hasNext();) {
            String server = (String) iter.next();
            if(!map.containsKey(server)){
              map.put(server, new Integer(0));
            }
        }
    }

    /**
     * Polls for new GlobalEvents with myServerHighCounts and iterates over
     * the registered sever side GlobalEventsListers.
     *
     * Usually this method is implicitly called in pollEvents().
     * But pollEvents() itself is only called if an XMA remote call is answered by the server.
     * To poll for server side events independently from XMA remote calls this method can be used.
     *
     * @since version_number
     * @author s3460
     */
    public void pollServerSideEvents(){
//      tests if last polling befor this one was more than POLLING_INTERVAL_MILLIS ago.
        if(pollingIntervalElapsed()){
            refreshFromJNDI();
        }
        //polls new events for the server and iterates over server side listener
        pollServerSideEventsInternal();
    }

    /**
     * Polls for new GlobalEvents with myServerHighCounts and iterates over
     * the registered sever side GlobalEventsListers.
     *
     * @since version_number
     * @author s3460
     */
    private void pollServerSideEventsInternal(){
        Collection coll = pollFromEventMap(this.myServerHighCounts);

        for (Iterator iter = coll.iterator(); iter.hasNext();) {
            GlobalEvent event = (GlobalEvent) iter.next();
            //only events for server are transmited to listener
            if(event.isEventForServer()){
                iterateListener(event);
            }
        }
    }

    /**
     * iterates over the registered GlobalEventsListers and calls globalEvent().
     * @param event
     * @since version_number
     * @author s3460
     */
    private void iterateListener(GlobalEvent event){
        if (globalEventListeners != null) {
            for (Iterator iter = globalEventListeners.iterator(); iter.hasNext();) {
                GlobalEventListener element = (GlobalEventListener) iter.next();
                try {
                    element.globalEvent(event);
                } catch (Exception e) {
                    // TODO logging
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * tests if last polling befor this one was more than POLLING_INTERVAL_MILLIS ago.
     * @return
     * @since version_number
     * @author s3460
     */
    private synchronized boolean pollingIntervalElapsed(){
        if(lastPollingTimeMillis + POLLING_INTERVAL_MILLIS < System.currentTimeMillis()){
            lastPollingTimeMillis = System.currentTimeMillis();
            return true;
        }else{
            return false;
        }
    }

    /**
     * Iterates over bindings of CTX_EVENTS (= iterates over sever contexts).
     * New contexts are added to serverMap.
     * Expireds events (bound to a server ctx) are removed.
     *
     * @since version_number
     * @author s3460
     */
    private void refreshServerMapAndCleanJNDI(){
        //add the other servers bound by JNDI
        try {
            for (NamingEnumeration iter = initCtx.listBindings(CTX_EVENTS_SCOPE); iter.hasMore();) {
                Binding element = (Binding) iter.next();
                Object obj = element.getObject();
                if(obj instanceof Context) {
                    cleanUpSubCtx((Context)obj);//clean up expired events from this ctx
                    if (!serverMap.containsKey(element.getName())) {//add new server
                        serverMap.put(element.getName(), new Integer(0));
                    }
                }
            }
        } catch (NamingException e) {
            // TODO logging
            //throw new SysException(e);
        }
    }

    /**
     * Iterates over serverMap and looks up the events of each server.
     * New events are added to eventMap.
     * New highCounts are reassigned to serverMap.
     * Non existing servers are removed from serverMap.
     *
     * @since version_number
     * @author s3460
     */
    private void refreshEventMapAndHighCounts(){
//      Iterates over serverMap and polls the events of each server.
        for (Iterator iter = serverMap.keySet().iterator(); iter.hasNext();) {
            String server = (String) iter.next();
            Integer i = (Integer) serverMap.get(server);
            i = refreshEventMap(server, i.intValue()); //returns new highCount
            if(i != null){
                serverMap.put(server, i); //reassign new highCount
            }else{
               iter.remove(); //server exists not any more
            }
        }
    }

    /**
     * Looks up the events of server serverName from oldCount + 1 to newHighCount
     * (which is saved in JNDI).
     * New events are stored in eventMap, the new highCount is returned.
     *
     * @param serverName
     * @param oldCount
     * @return new highCount for server serverName
     * @since version_number
     * @author s3460
     */
    private Integer refreshEventMap(String serverName, int oldCount) {
        //own events are already added (in send())
        if(_serverName.equalsIgnoreCase(serverName)){
            return new Integer(highCount);

        }else{//lookup events of other servers by JNDI
            //lookup new highCount
            Integer newCount = null;
            try {
                newCount = (Integer) initCtx.lookup(CTX_EVENTS_SCOPE + "." + serverName + "."
                        + COUNT);
            } catch (NamingException e) {
//              server exists not any more
                return null;
                //throw new SysException(e);
            }
            //lookup new events
            for (int i = oldCount + 1; i <= newCount.intValue(); i++) {
                try {
                    Object jndiObj = initCtx.lookup(CTX_EVENTS_SCOPE + "."
                            + serverName + "." + String.valueOf(i));

                    if(jndiObj instanceof Map){
                        GlobalEvent event = new GlobalEvent((Map) jndiObj);
//                      store new events in eventMap
                        eventMap.put(serverName + "_" + event.getCount(),event);
                    }
                } catch (NamingException e) {
//                  event can already be removed if expired
                    //TODO log;
                    //e.printStackTrace();
                }
            }

            return newCount;
        }
    }

    /**
     * Refreshes eventMap and serverMap with the actual structure stored in JNDI.
     * Removes non existing servers from serverMap.
     * Removes expired events from eventMap.
     * @since version_number
     * @author s3460
     */
    private synchronized void refreshFromJNDI(){
        refreshServerMapAndCleanJNDI();
        refreshEventMapAndHighCounts();
        cleanUpEventMap();
    }

    /**
     *
     * @return the name set in 'xma.runtime.activateGlobalEvents'
     * @since version_number
     * @author S3460
     * @throws SysException if 'xma.runtime.activateGlobalEvents' is set to false (default).
     */
    private static String getScopeName(){
        XProperties props = XProperties.getNodeOfPackage("xma.runtime");
        return props.get(ACTIVATE_GLOBAL_EVENTS, "false");
    }

    /**
     * Queries for the property: at.spardat.xma.activateGlobalEvents=true
     * Is called after every RPC before GlobalEventManager.getInstance().pollEvents()
     * to ommit unneccesary JNDI queries.
     * Should also be called before every GlobalEventManager.getInstance().pollServerSideEvents().
     * @return true if at.spardat.xma.activateGlobalEvents != "false" is set.
     * @since version_number
     * @author s3460
     */
    public static boolean isGlobalEventActivated(){
        return !"false".equals(getScopeName());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy