src.openwfe.org.engine.expressions.Environment Maven / Gradle / Ivy
/*
* Copyright (c) 2005-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: Environment.java 2852 2006-06-22 07:04:12Z jmettraux $
*/
//
// Environment.java
//
// [email protected]
//
// generated with
// jtmpl 1.1.01 2004/05/19 ([email protected])
//
package openwfe.org.engine.expressions;
import openwfe.org.engine.Definitions;
import openwfe.org.engine.expool.PoolException;
import openwfe.org.engine.expool.ExpressionPool;
import openwfe.org.engine.workitem.InFlowWorkItem;
import openwfe.org.engine.expressions.BuildException;
/**
* Either a temporary storage for definitions, either an engine level
* variable container.
*
* CVS Info :
*
$Author: jmettraux $
*
$Id: Environment.java 2852 2006-06-22 07:04:12Z jmettraux $
*
* @author [email protected]
*/
public class Environment
extends ZeroChildExpression
implements ExpressionToUnbind
{
private final static org.apache.log4j.Logger log = org.apache.log4j.Logger
.getLogger(Environment.class.getName());
//
// CONSTANTS & co
/**
* The FlowExpressionId of an Environment instance will always have
* '__env__' as expression name.
*/
public final static String EXPRESSION_NAME
= "__env__";
//
// FIELDS
private java.util.Map variables = null;
private java.util.List cachedKeySet = null;
//
// CONSTRUCTORS
public Environment ()
{
super();
this.variables = new java.util.LinkedHashMap();
}
/**
* Generates a new environment
*/
public static Environment generateEnvironment
(final FlowExpression generatingExpression)
throws
BuildException, PoolException
{
if (log.isDebugEnabled())
{
log.debug
("generateEnvironment() for "+generatingExpression.getId()+
" ("+generatingExpression.getClass().getName()+")");
}
//log.debug
// ("generateEnvironment() parent is "+
// generatingExpression.getParent());
//log.debug
// ("generateEnvironment() parent.env is "+
// Definitions.getExpressionPool(generatingExpression.context())
// .getEnvironmentId(generatingExpression.getParent()));
final Environment env = new Environment();
final FlowExpressionId id = generatingExpression.getId().copy();
id.setExpressionId(id.getExpressionId()+"e");
id.setExpressionName(EXPRESSION_NAME);
env.setApplicationContext(generatingExpression.context());
env.setEnvironmentId(generatingExpression.getEnvironmentId());
if (log.isDebugEnabled())
{
log.debug
("generateEnvironment() -1 env.id = "+env.getId());
log.debug
("generateEnvironment() -1 env.parent = "+env.getParent());
log.debug
("generateEnvironment() -1 env.envId = "+env.getEnvironmentId());
}
if (generatingExpression.getParent() != null)
{
final ExpressionPool expool = Definitions
.getExpressionPool(generatingExpression.context());
env.setEnvironmentId
(expool.getEnvironmentId(generatingExpression.getParent()));
}
env.setId(id);
if (log.isDebugEnabled())
{
log.debug
("generateEnvironment() 0 env.id = "+env.getId());
log.debug
("generateEnvironment() 0 env.envId = "+env.getEnvironmentId());
}
env.getExpressionPool().add(env);
generatingExpression.setEnvironmentId(env.getId());
//
// but the env is still pointing to the former env of the
// generating expression
if (log.isDebugEnabled())
{
log.debug
("generateEnvironment() 1 env.id = "+env.getId());
log.debug
("generateEnvironment() 1 env.envId = "+env.getEnvironmentId());
}
return env;
}
//
// METHODS from ExpressionToUnbind
/**
* The environment will iterate through all its stored values that are
* implementing the ExpressionToUnbind interface and trigger their
* unbind() method.
*/
public synchronized void unbind ()
throws PoolException
{
final java.util.Iterator it = this.variables.values().iterator();
while (it.hasNext())
{
final Object v = it.next();
if (v instanceof ExpressionToUnbind)
{
try
{
((FlowExpression)v).setApplicationContext(context());
((ExpressionToUnbind)v).unbind();
}
catch (final PoolException pe)
{
log.warn("unbind() problem. Resuming anyway.", pe);
}
}
else if (v instanceof FlowExpressionId)
//
// remove templates
{
getExpressionPool().removeExpression((FlowExpressionId)v);
}
}
//log.debug("unbind() done.");
}
//
// METHODS
/**
* This is similar to a Map's get() method.
*/
public synchronized Object get (final String variableName)
{
if (log.isDebugEnabled())
log.debug("get() in "+getId()+" for '"+variableName+"'");
if (this.cachedKeySet == null)
{
this.cachedKeySet =
new java.util.ArrayList(this.variables.keySet());
java.util.Collections.reverse(this.cachedKeySet);
}
final java.util.Iterator it = this.cachedKeySet.iterator();
while (it.hasNext())
{
final String key = (String)it.next();
/*
log.debug
("get() key >"+key+"<");
log.debug
("get() \n>"+key+"<\n matches\n>"+variableName+"< ? "+
key.matches(variableName)+" ("+key.equals(variableName)+")");
*/
if (key.matches(variableName))
{
//log.debug("get() match for key >"+key+"<");
//log.debug("get() return class : "+this.variables.get(key));
return this.variables.get(key);
}
}
if (this.getId().equals(EngineEnvironmentId.ID))
//
// special lookups...
{
//
// participant lookup
/*
final Participant p = Definitions.getParticipantMap(context())
.get(variableName);
if (p != null) return p;
*/
//
// expression lookup
final Class c = Definitions.getExpressionMap(context())
.getClass(variableName);
if (c != null) return c;
}
if (log.isDebugEnabled())
log.debug("get() for '"+variableName+"'. Not found in "+getId());
return null;
}
/**
* A get() is local whereas this method will lookup locally then, if
* nothing was found, will lookup in the parent environments (culminating
* with the engine environment).
*/
public Object lookup (final String variableName)
{
if (log.isDebugEnabled())
log.debug("lookup() in "+getId()+" for '"+variableName+"'");
//openwfe.org.Utils.logStackTrace(log, "lookup()");
final Object result = this.get(variableName);
if (result != null) return result;
if (getEnvironmentId() == null)
{
//log.debug("lookup() having to lookup in engine env...");
return getExpressionPool().fetchEngineEnvironment()
.get(variableName);
}
final Environment env = (Environment)getExpressionPool()
.fetch(getEnvironmentId());
if (env == null)
{
log.warn("lookup() didn't find an env at "+getEnvironmentId());
//return null;
return getExpressionPool().fetchEngineEnvironment()
.get(variableName);
}
return env.lookup(variableName);
}
/**
* A recursive method : recurses until the environment is the one
* containing the variable, it then returns this environment.
*/
public Environment lookupContainingEnvironment (final String variableName)
{
if (this.variables.containsKey(variableName)) return this;
if (this.getId().equals(EngineEnvironmentId.ID)) return null;
final Environment env = (Environment)getExpressionPool()
.fetch(getEnvironmentId());
if (env == null)
{
if (log.isDebugEnabled())
{
log.debug
("lookupContainingEnvironment() did not find env "+
getEnvironmentId());
}
return null;
}
return env.lookupContainingEnvironment(variableName);
}
/**
* Similar to the method with the same name in a Map.
*/
public synchronized void put
(final String variableName, final Object value)
{
this.cachedKeySet = null;
doPut(variableName, value);
this.storeItself();
}
/**
* Similar to the method with the same name in a Map.
*/
public synchronized void putAll (final java.util.Map m)
{
if (log.isDebugEnabled())
log.debug("putAll() in env "+getId());
this.cachedKeySet = null;
final java.util.Iterator it = m.keySet().iterator();
while (it.hasNext())
{
final String key = (String)it.next();
final Object value = m.get(key);
//this.put(key, value);
//
// for each put() there was one storeItself()
// it was not very efficient
doPut(key, value);
}
this.storeItself();
}
/*
* the put() but with some debug output
*/
private void doPut
(final String variableName, final Object value)
{
this.variables.put(variableName, value);
if (log.isDebugEnabled())
{
log.debug("put() '"+variableName+"' in "+this.getId());
if (value != null)
{
String s = value.toString();
if (s.length() > 80) s = s.substring(0, 77) + "...";
log.debug("put() '"+variableName+"' -> >"+s+"<");
}
}
}
/**
* Reattaches this environment to another [owning] expression.
* This method takes care of removing the environment from the expool
* and to readd it (under the new id).
*/
public void reattach (final FlowExpressionId newOwnerId)
{
//log.debug("reattach() from "+this.getId()+" to owner "+newOwnerId);
getExpressionPool().removeExpression(this.getId());
this.setId(newOwnerId.copy());
this.getId().setExpressionName(EXPRESSION_NAME);
if ( ! this.getId().getExpressionId().endsWith("e"))
this.getId().setExpressionId(this.getId().getExpressionId()+"e");
if (log.isDebugEnabled())
log.debug("reattach() new id "+this.getId());
this.storeItself();
}
//
// BEAN METHODS
/**
* getVariables() and setVariables() are used when this environment is
* serialized (it's a bean after all).
*/
public java.util.Map getVariables ()
{
return this.variables;
}
/**
* @see #getVariables
*/
public void setVariables (java.util.Map m)
{
this.variables = (java.util.LinkedHashMap)m;
}
//
// METHODS from FlowExpression
/**
* Never called, thus it is empty.
*/
public void apply (final InFlowWorkItem wi)
throws ApplyException
{
// nothing to do
}
//
// STATIC METHODS
/**
* Returns true if the environment of the given expression has been
* generated specifically for the expression.
*/
public static boolean ownsEnvironment (final FlowExpression fe)
{
final FlowExpressionId expId = fe.getId().copy();
final FlowExpressionId envId = fe.getEnvironmentId();
expId.setExpressionId(expId.getExpressionId()+"e");
expId.setExpressionName(EXPRESSION_NAME);
return expId.equals(envId);
}
}