
openwfe.org.ApplicationContext Maven / Gradle / Ivy
/*
* Copyright (c) 2001-2006, John Mettraux, OpenWFE.org
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name of the "OpenWFE" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ApplicationContext.java 2673 2006-05-26 21:08:46Z jmettraux $
*/
//
// ApplicationContext.java
//
// [email protected]
//
// generated with
// jtmpl 1.0.04 20.11.2001 John Mettraux ([email protected])
//
package openwfe.org;
import openwfe.org.state.PausedState;
import openwfe.org.state.RunningState;
import openwfe.org.state.StoppedState;
import openwfe.org.state.ServiceState;
/**
* Something that keeps track of 1 expression pool and its associated
* workflow instance builder
*
* CVS Info :
*
$Author: jmettraux $
*
$Date: 2006-05-26 23:08:46 +0200 (Fri, 26 May 2006) $
*
$Id: ApplicationContext.java 2673 2006-05-26 21:08:46Z jmettraux $
*
* @author [email protected]
*/
public class ApplicationContext
implements OwfeRunnable
{
private final static org.apache.log4j.Logger log = org.apache.log4j.Logger
.getLogger(ApplicationContext.class.getName());
//
// CONSTANTS & co
protected final static String SHARED = "shared";
// identifier for a global scratch application context
// (maybe useful for passing stuff inside an application)
/**
* If a service uses this parameter and gives it a value, this value
* should be the name of a ServiceIterator instance.
* As of this writing, this system will only be used to order
* WorkitemStores.
*/
public final static String P_SERVICE_ITERATOR
= "serviceIterator";
//
// global parameters
/**
* This [global] parameter name helps an OpenWFE application determine
* its location in the filesystem. The name of this key is
* 'applicationDirectory'.
*/
public final static String P_APPLICATION_DIRECTORY
= "applicationDirectory";
/**
* This constant contains the name of a key stored in the context
* and yielding the date (long) of when the configuration file used for
* generating this context was last modified.
*/
public final static String K_LAST_MODIFIED
= "__last_modified__";
//
// a singleton allowing to retrieve any application context in the JVM
public static final java.util.Map contextMap = new java.util.HashMap();
//
// FIELDS
private ApplicationContext parentContext = null;
private String applicationName = null;
private java.util.Map map = new java.util.HashMap();
private java.util.Map serviceIterators = new java.util.HashMap();
private ServiceState contextState = new RunningState();
//
// CONSTRUCTORS
//
// METHODS
/**
* Returns the date when the configuration file used to define this
* application was last modified.
* Will return -1 if this value couldn't be determined.
*/
public long getLastModified ()
{
final Long l = (Long)this.map.get(K_LAST_MODIFIED);
if (l == null) return -1;
return l.longValue();
}
/**
* This method is only used upon building the context; it stores the
* date at which the configuration file used to build the context was
* last modified.
*/
public void setLastModified (final long l)
{
this.map.put(K_LAST_MODIFIED, new Long(l));
}
/**
* Sets the application name of this application context.
*/
public void setApplicationName (final String s)
{
this.applicationName = s;
}
/**
* This method could have been called 'getMap', but well, it's
* better like that (to be used in conjunction with MapUtils).
*/
public java.util.Map asMap ()
{
return this.map;
}
/**
* Removes a service or a variable from this context.
*/
public Object remove (final String key)
{
return this.map.remove(key);
}
/**
* Adds a service, a sub application context or just a variable to
* this application context.
*/
public void put (final String key, final Object o)
{
this.map.put(key, o);
}
/**
* Adds a service to this application context.
*/
public void add (final Service s)
{
this.put(s.getName(), s);
}
/**
* Feeding a param map into this application context.
*/
public void putAll (final java.util.Map m)
{
this.map.putAll(m);
}
/**
* Returns an entry in the application context.
* Almost deprecated as of OpenWFE 1.4.2
*/
public Object get (final String key)
{
return lookup(key);
}
//
// lookup() and friends
protected ApplicationContext getRootContext ()
{
if (this.parentContext == null) return this;
return this.parentContext.getRootContext();
}
/**
* This method should supplant get() in the middle term, it allows for
* lookup among nested application context (a new concept since OpenWFE
* 1.4.2).
*/
public Object lookup (final String key)
{
//log.debug("lookup() '"+key+"' in '"+getApplicationName()+"'");
if (key == null) return null;
final int i = key.indexOf("/");
if (i < 0) return this.map.get(key);
if (key.startsWith("./"))
return lookup(key.substring(2));
if (key.startsWith("../"))
return getParentContext().lookup(key.substring(3));
if (key.startsWith("/"))
return getRootContext().lookup(key.substring(1));
final String subContextName = key.substring(0, i);
if (log.isDebugEnabled())
log.debug("lookup() subContextName is '"+subContextName+"'");
final ApplicationContext subContext =
(ApplicationContext)this.map.get(subContextName);
if (subContext == null) return null;
return subContext.lookup(key.substring(i+1));
}
//
// various getX methods
public long getTime (String key)
throws NumberFormatException
{
return MapUtils.getAsTime(this.map, key);
}
public long getLong (String key)
throws NumberFormatException
{
return MapUtils.getAsLong(this.map, key);
}
public long getLong (String key, long defaultValue)
{
return MapUtils.getAsLong(this.map, key, defaultValue);
}
public int getInt (String key, int defaultValue)
{
return MapUtils.getAsInt(this.map, key, defaultValue);
}
public boolean getBoolean (String key, boolean defaultValue)
{
return MapUtils.getAsBoolean(this.map, key, defaultValue);
}
/**
* Returns the set of keys found in the context
*/
public java.util.Set keySet ()
{
return this.map.keySet();
}
/**
* Returns all the items of a certain class that are bound in this
* application context.
*/
public java.util.List itemsOfClass (final Class theClass)
{
final java.util.List result = new java.util.ArrayList(this.map.size());
final java.util.Iterator it = this.map.values().iterator();
while (it.hasNext())
{
final Object item = it.next();
if (theClass.isAssignableFrom(item.getClass()))
result.add(item);
}
return result;
}
/**
* A shortcut that ensures that the returned value always ends with '/'
*/
public String getApplicationDirectory ()
{
String applicationDirectory = (String)this.map
.get(P_APPLICATION_DIRECTORY);
if (applicationDirectory == null)
{
applicationDirectory = "./";
this.map.put(P_APPLICATION_DIRECTORY, applicationDirectory);
}
else if ( ! applicationDirectory.endsWith(java.io.File.separator))
{
applicationDirectory += java.io.File.separator;
this.map.put(P_APPLICATION_DIRECTORY, applicationDirectory);
}
return applicationDirectory;
}
/**
* Sets this application context's [root|home] directory
*/
public void setApplicationDirectory (final String path)
{
this.map.put(P_APPLICATION_DIRECTORY, path);
}
/**
* Returns the name of the application.
*/
public String getApplicationName ()
{
return this.applicationName;
}
/**
* Returns the name of the application.
*/
public String getName ()
{
return this.applicationName;
}
public java.util.Iterator serviceIterator ()
{
java.util.List result = new java.util.ArrayList(this.map.size());
java.util.Iterator it = this.map.values().iterator();
while (it.hasNext())
{
Object o = it.next();
if (o instanceof Service) result.add(o);
}
return result.iterator();
}
/**
* Returns the parent context of this context or null if it's a root
* or standalone context.
*/
public ApplicationContext getParentContext ()
{
return this.parentContext;
}
/**
* Sets the parent of this application context
*/
public void setParentContext (final ApplicationContext ac)
{
this.parentContext = ac;
}
/**
* This method is used by the StatusService to fill its reply
* with the status of all the services in an ApplicationContext
* (and in its subcontexts).
*/
public void outputStatus (final org.jdom.Element rootElt)
{
//
// iterate on services
java.util.Iterator it = serviceIterator();
while (it.hasNext())
{
final Service s = (Service)it.next();
org.jdom.Element sStatus = s.getStatus();
if (sStatus == null)
//
// service writers may return null...
{
sStatus = new org.jdom.Element("service");
sStatus.setAttribute("name", s.getName());
final org.jdom.Element eNullStatus =
new org.jdom.Element("null-status");
sStatus.addContent(eNullStatus);
}
rootElt.addContent(sStatus);
}
it = this.map.values().iterator();
while (it.hasNext())
{
final Object o = it.next();
if (o instanceof ApplicationContext)
{
final ApplicationContext subContext = (ApplicationContext)o;
final org.jdom.Element subRootElt =
new org.jdom.Element(subContext.getApplicationName());
subContext.outputStatus(subRootElt);
rootElt.addContent(subRootElt);
}
}
//
// add memory numbers
final org.jdom.Element efm = new org.jdom.Element("free-memory");
efm.addContent
(""+(Runtime.getRuntime().freeMemory() / 1000000.0d)+" MB");
final org.jdom.Element emm = new org.jdom.Element("max-memory");
emm.addContent
(""+(Runtime.getRuntime().maxMemory() / 1000000.0d)+" MB");
rootElt.addContent(efm);
rootElt.addContent(emm);
}
//
// METHODS from OwfeRunnable
/**
* Stops the services comprised in this application context
* and stops all the child subcontexts.
*/
public void stop ()
throws ServiceException
{
setState(new StoppedState());
final java.util.Iterator it = this.map.values().iterator();
while (it.hasNext())
{
final Object item = it.next();
if (item instanceof OwfeRunnable)
{
final OwfeRunnable runnable = (OwfeRunnable)item;
try
{
runnable.stop();
}
catch (final ServiceException e)
{
log.info
("stop() had trouble when stopping '"+
runnable.getName()+"'",
e);
}
}
}
log.info("stop() context '"+this.applicationName+"' stopped.");
}
/**
* Will start all the services and subcontext (OwfeRunnable instances in
* general) comprised in this context.
*/
public void play ()
throws ServiceException
{
log.info("play() requested for service '"+getName()+"'");
if ( ! this.isRunning())
setState(new RunningState());
else
return;
final java.util.Iterator it = this.map.values().iterator();
while (it.hasNext())
{
final Object item = it.next();
if (item instanceof OwfeRunnable)
{
final OwfeRunnable runnable = (OwfeRunnable)item;
try
{
runnable.play();
}
catch (ServiceException se)
{
log.info
("play() had trouble when playing '"+
runnable.getName()+"'",
se);
}
}
}
}
/**
* Will pause all the services and subcontext (OwfeRunnable instances in
* general) comprised in this context.
*/
public void pause ()
throws ServiceException
{
log.info("pause() requested for service '"+getName()+"'");
if (this.isRunning())
setState(new PausedState());
else
return;
final java.util.Iterator it = this.map.values().iterator();
while (it.hasNext())
{
final Object item = it.next();
if (item instanceof OwfeRunnable)
{
final OwfeRunnable runnable = (OwfeRunnable)item;
try
{
runnable.pause();
}
catch (final ServiceException e)
{
log.info
("pause() had trouble when pausing '"+
runnable.getName()+"'",
e);
}
}
}
}
public void update ()
throws ServiceException
{
log.info("update() requested for service '"+getName()+"'");
final java.util.Iterator it = this.map.values().iterator();
while (it.hasNext())
{
final Object item = it.next();
if (item instanceof OwfeRunnable)
{
final OwfeRunnable runnable = (OwfeRunnable)item;
try
{
runnable.update();
}
catch (final ServiceException e)
{
log.info
("pause() had trouble when 'updating' '"+
runnable.getName()+"'",
e);
}
}
}
}
/**
* Returns the state in which the context currently is.
*/
public ServiceState getState ()
{
return this.contextState;
}
/**
* Changes the state of the context (but not the state of the OwfeRunnable
* instances it contains).
*/
protected void setState (ServiceState state)
{
this.contextState = state;
}
/**
* Will return true if the context is in RunningState (or any of the
* subclasses of this state class).
*/
public boolean isRunning ()
{
return getState() instanceof RunningState;
}
//
// STATIC METHODS
/**
* A static method for looking up a context just knowing its name.
*/
public static ApplicationContext lookupContext (final String contextName)
{
return (ApplicationContext)contextMap.get(contextName);
}
/**
* The shared context is an empty context that can be filled with stuff
* shared by services and other instances in the same VM.
*/
public static SharedApplicationContext lookupSharedContext ()
{
return (SharedApplicationContext)contextMap.get(SHARED);
}
static
{
SharedApplicationContext sac = new SharedApplicationContext();
contextMap.put(SHARED, sac);
}
/* *
* This method shall be removed as of OpenWFE 1.5.0
* /
public static Object lookup
(final ApplicationContext context,
final String key,
final String oldKey)
{
if (context == null)
{
throw new IllegalArgumentException
("Cannot lookup anything in a null context");
}
final Object o = context.lookup(key);
if (o != null) return o;
return context.lookup(oldKey);
}
*/
}