/*
* Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
* $Id: ElementInfo.java 3928 2008-04-22 16:25:18Z gbevin $
*/
package com.uwyn.rife.engine;
import com.uwyn.rife.config.RifeConfig;
import com.uwyn.rife.engine.exceptions.*;
import com.uwyn.rife.ioc.HierarchicalProperties;
import com.uwyn.rife.ioc.PropertyValue;
import com.uwyn.rife.ioc.PropertyValueObject;
import com.uwyn.rife.ioc.exceptions.PropertyValueException;
import com.uwyn.rife.rep.Rep;
import com.uwyn.rife.resources.ResourceFinder;
import com.uwyn.rife.resources.exceptions.ResourceFinderErrorException;
import com.uwyn.rife.tools.ExceptionUtils;
import java.net.URL;
import java.text.NumberFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ElementInfo implements Cloneable
{
public static final boolean DEFAULT_BOOLEAN = false;
public static final int DEFAULT_INTEGER = 0;
public static final long DEFAULT_LONG = 0l;
public static final double DEFAULT_DOUBLE = 0.0d;
public static final float DEFAULT_FLOAT = 0.0f;
private Site mSite = null;
private String mUrl = null;
private String mProcessorIdentifier = null;
private String mId = null;
private String mReferenceId = null;
private int mGroupId = -1;
private StateStore mStateStore = null;
private boolean mPathInfoUsed = false;
private String mDeclarationName = null;
private String mImplementation = null;
private Element mImplementationBlueprint = null;
private ElementType mType = null;
private String mContentType = null;
private HierarchicalProperties mStaticProperties = null;
private HierarchicalProperties mProperties = null;
private Map<String, Submission> mSubmissions = null;
private Map<String, String[]> mInputs = null;
private Map<String, String[]> mOutputs = null;
private Map<String, String> mIncookies = null;
private Map<String, String> mOutcookies = null;
private Map<String, BeanDeclaration> mNamedInbeans = null;
private Map<String, BeanDeclaration> mNamedOutbeans = null;
private boolean mHasSubmissionDefaults = false;
private boolean mHasGlobalVarDefaults = false;
private boolean mHasGlobalCookieDefaults = false;
private boolean mHasInputDefaults = false;
private boolean mHasOutputDefaults = false;
private boolean mHasIncookieDefaults = false;
private boolean mHasOutcookieDefaults = false;
private boolean mHasSnapbackFlowLinks = false;
private boolean mHasSnapbackDataLinks = false;
private List<String> mChildTriggers = null;
private Map<String, FlowLink> mExits = null;
private Map<ElementInfo, List<DataLink>> mDatalinks = null;
private List<DataLink> mSnapbackDatalinks = null;
private Stack<ElementInfo> mInheritanceStack = null;
private Stack<ElementInfo> mPrecedenceStack = null;
private Map<String, GlobalExit> mGlobalExits = null;
private Map<String, GlobalVar> mGlobalVars = null;
private Map<String, String> mGlobalCookies = null;
private Map<String, BeanDeclaration> mNamedGlobalBeans = null;
private List<String> mDepartureVars = null;
private boolean mHasDepartureVars = false;
private ElementDeployer mDeployer = null;
private PathInfoMode mPathInfoMode = PathInfoMode.LOOSE;
private List<PathInfoMapping> mPathInfoMappings = null;
private List<ErrorHandler> mErrorHandlers = null;
private static NumberFormat MEMORY_FORMAT = null;
static
{
MEMORY_FORMAT = NumberFormat.getIntegerInstance();
MEMORY_FORMAT.setMinimumIntegerDigits(8);
MEMORY_FORMAT.setMaximumIntegerDigits(8);
MEMORY_FORMAT.setGroupingUsed(false);
}
ElementInfo()
throws EngineException
{
mStaticProperties = new HierarchicalProperties().parent(Rep.getProperties());
mSubmissions = new LinkedHashMap<String, Submission>();
mInputs = new LinkedHashMap<String, String[]>();
mOutputs = new LinkedHashMap<String, String[]>();
mIncookies = new LinkedHashMap<String, String>();
mOutcookies = new LinkedHashMap<String, String>();
mNamedInbeans = new LinkedHashMap<String, BeanDeclaration>();
mNamedOutbeans = new LinkedHashMap<String, BeanDeclaration>();
mChildTriggers = new ArrayList<String>();
mExits = new LinkedHashMap<String, FlowLink>();
mDatalinks = new LinkedHashMap<ElementInfo, List<DataLink>>();
mSnapbackDatalinks = new ArrayList<DataLink>();
mPathInfoMappings = new ArrayList<PathInfoMapping>();
}
ElementInfo(String declarationName, String contentType, String implementation, ElementType type)
throws EngineException
{
this();
setDeclarationName(declarationName);
setContentType(contentType);
setImplementation(implementation);
setType(type);
}
void extendFrom(ElementInfo extendedElement)
{
mProcessorIdentifier = extendedElement.mProcessorIdentifier;
mImplementation = extendedElement.mImplementation;
mType = extendedElement.mType;
mContentType = extendedElement.mContentType;
mStaticProperties = new HierarchicalProperties().putAll(extendedElement.mStaticProperties).parent(Rep.getProperties());
mSubmissions = new LinkedHashMap<String, Submission>(extendedElement.mSubmissions);
mInputs = new LinkedHashMap<String, String[]>(extendedElement.mInputs);
mOutputs = new LinkedHashMap<String, String[]>(extendedElement.mOutputs);
mIncookies = new LinkedHashMap<String, String>(extendedElement.mIncookies);
mOutcookies = new LinkedHashMap<String, String>(extendedElement.mOutcookies);
mNamedInbeans = new LinkedHashMap<String, BeanDeclaration>(extendedElement.mNamedInbeans);
mNamedOutbeans = new LinkedHashMap<String, BeanDeclaration>(extendedElement.mNamedOutbeans);
mHasSubmissionDefaults = extendedElement.mHasSubmissionDefaults;
mHasInputDefaults = extendedElement.mHasInputDefaults;
mHasOutputDefaults = extendedElement.mHasOutputDefaults;
mHasIncookieDefaults = extendedElement.mHasIncookieDefaults;
mHasOutcookieDefaults = extendedElement.mHasOutcookieDefaults;
mHasSnapbackFlowLinks = false;
mHasSnapbackDataLinks = false;
mChildTriggers = new ArrayList<String>(extendedElement.mChildTriggers);
mExits = new LinkedHashMap<String, FlowLink>(extendedElement.mExits);
mDatalinks = new LinkedHashMap<ElementInfo, List<DataLink>>();
mSnapbackDatalinks = new ArrayList<DataLink>();
mPathInfoMode = extendedElement.mPathInfoMode;
mPathInfoMappings = new ArrayList<PathInfoMapping>(extendedElement.mPathInfoMappings);
// clear flowlinks
for (String exit : mExits.keySet())
{
mExits.put(exit, null);
}
}
void populateFrom(ElementInfo referenceElement)
{
mSite = referenceElement.mSite;
mDeclarationName = referenceElement.mDeclarationName;
mProcessorIdentifier = referenceElement.mProcessorIdentifier;
mImplementation = referenceElement.mImplementation;
mType = referenceElement.mType;
mUrl = referenceElement.mUrl;
mId = referenceElement.mId;
mReferenceId = referenceElement.getReferenceId();
mGroupId = referenceElement.mGroupId;
mStateStore = referenceElement.mStateStore;
mPathInfoUsed = referenceElement.mPathInfoUsed;
mContentType = referenceElement.mContentType;
mStaticProperties = referenceElement.mStaticProperties;
mSubmissions = referenceElement.mSubmissions;
mInputs = referenceElement.mInputs;
mOutputs = referenceElement.mOutputs;
mIncookies = referenceElement.mIncookies;
mOutcookies = referenceElement.mOutcookies;
mNamedInbeans = referenceElement.mNamedInbeans;
mNamedOutbeans = referenceElement.mNamedOutbeans;
mHasSubmissionDefaults = referenceElement.mHasSubmissionDefaults;
mHasGlobalVarDefaults = referenceElement.mHasGlobalVarDefaults;
mHasGlobalCookieDefaults = referenceElement.mHasGlobalCookieDefaults;
mHasInputDefaults = referenceElement.mHasInputDefaults;
mHasOutputDefaults = referenceElement.mHasOutputDefaults;
mHasIncookieDefaults = referenceElement.mHasIncookieDefaults;
mHasOutcookieDefaults = referenceElement.mHasOutcookieDefaults;
mHasSnapbackFlowLinks = referenceElement.mHasSnapbackFlowLinks;
mHasSnapbackDataLinks = referenceElement.mHasSnapbackDataLinks;
mChildTriggers = referenceElement.mChildTriggers;
mSnapbackDatalinks = referenceElement.mSnapbackDatalinks;
mInheritanceStack = referenceElement.mInheritanceStack;
mGlobalExits = referenceElement.mGlobalExits;
mGlobalVars = referenceElement.mGlobalVars;
mGlobalCookies = referenceElement.mGlobalCookies;
mNamedGlobalBeans = referenceElement.mNamedGlobalBeans;
mDepartureVars = referenceElement.mDepartureVars;
mHasDepartureVars = referenceElement.mHasDepartureVars;
mDeployer = referenceElement.mDeployer;
mPathInfoMode = referenceElement.mPathInfoMode;
mPathInfoMappings = referenceElement.mPathInfoMappings;
mErrorHandlers = referenceElement.mErrorHandlers;
// Go over all the datalinks and flowlinks and check if their targets
// don't point to the reference element itself.
// If that is the case, they have to be adapted to point to the one
// that's being populated instead.
mExits = new LinkedHashMap<String, FlowLink>(referenceElement.mExits);
Map<FlowLink, FlowLink> replaced_flowlinks = new HashMap<FlowLink, FlowLink>();
for (Map.Entry<String, FlowLink> exits_entry : mExits.entrySet())
{
FlowLink flowlink = exits_entry.getValue();
if (flowlink != null &&
flowlink.getTarget() == referenceElement)
{
FlowLink new_flowlink = new FlowLink(flowlink.getExitName(), this, flowlink.isSnapback(), flowlink.cancelInheritance(), flowlink.cancelEmbedding(), flowlink.isRedirect(), flowlink.cancelContinuations());
mExits.put(exits_entry.getKey(), new_flowlink);
replaced_flowlinks.put(flowlink, new_flowlink);
}
}
mDatalinks = new LinkedHashMap<ElementInfo, List<DataLink>>(referenceElement.mDatalinks);
List<DataLink> reflective_datalinks = mDatalinks.remove(referenceElement);
if (reflective_datalinks != null)
{
List<DataLink> datalinks = new ArrayList<DataLink>();
for (DataLink datalink : reflective_datalinks)
{
DataLink new_datalink = new DataLink(datalink.getOutput(), this, datalink.isSnapback(), datalink.getInput(), replaced_flowlinks.get(datalink.getFlowLink()));
datalinks.add(new_datalink);
}
mDatalinks.put(this, datalinks);
}
}
void deploy()
throws EngineException
{
ElementSupport element = null;
Class deployment_class = null;
ElementDeployer deployer = null;
// iterate over all the registered element infos
element = ElementFactory.INSTANCE.getInstance(this, true);
// try to instantiate each element for the first time
if (element != null)
{
if (ElementType.JAVA_CLASS == getType())
{
// obtain the modification time
if (RifeConfig.Engine.getSiteAutoReload())
{
ResourceFinder resource_finder = ElementFactory.INSTANCE.getResourceFinder();
URL resource = resource_finder.getResource(mImplementation.replace('.', '/')+".class");
if (resource != null)
{
try
{
mSite.addResourceModificationTime(new UrlResource(resource, mImplementation), resource_finder.getModificationTime(resource));
}
catch (ResourceFinderErrorException e)
{
throw new ProcessingErrorException("element", mImplementation, "Error while retrieving the modification time.", e);
}
}
}
}
deployment_class = element.getDeploymentClass();
// check if a deployer is available
if (deployment_class != null)
{
try
{
// try to instatiate the deployer
deployer = (ElementDeployer)deployment_class.newInstance();
// perform the deployment and register it
deployer.setElementInfo(this);
deployer.deploy();
setDeployer(deployer);
}
catch (InstantiationException e)
{
throw new DeployerInstantiationException(getDeclarationName(), e);
}
catch (IllegalAccessException e)
{
throw new DeployerInstantiationException(getDeclarationName(), e);
}
catch (ClassCastException e)
{
throw new DeployerInstantiationException(getDeclarationName(), e);
}
}
}
}
void setSite(Site site)
{
assert site != null;
mSite = site;
}
public Site getSite()
{
return mSite;
}
void setProcessorIdentifier(String identifier)
{
assert identifier != null;
mProcessorIdentifier = identifier;
}
public String getProcessorIdentifier()
{
return mProcessorIdentifier;
}
void setGroupId(int groupId)
{
mGroupId = groupId;
}
public int getGroupId()
{
return mGroupId;
}
HierarchicalProperties getStaticProperties()
{
return mStaticProperties;
}
void setProperties(HierarchicalProperties properties, HierarchicalProperties parent)
{
mProperties = properties.parent(parent);
if (parent != null &&
parent != mStaticProperties)
{
parent.getRoot().parent(mStaticProperties);
}
}
void setInheritanceStack(Stack<ElementInfo> inheritanceStack)
{
assert inheritanceStack != null;
assert null == mInheritanceStack;
mInheritanceStack = inheritanceStack;
}
public Stack<ElementInfo> getInheritanceStack()
{
return mInheritanceStack;
}
void setPrecedenceStack(Stack<ElementInfo> precedenceStack)
{
assert precedenceStack != null;
assert null == mPrecedenceStack;
mPrecedenceStack = precedenceStack;
}
public Stack<ElementInfo> getPrecedenceStack()
{
return mPrecedenceStack;
}
void setGlobalExits(Map<String, GlobalExit> globalExits)
throws EngineException
{
assert globalExits != null;
assert null == mGlobalExits;
mGlobalExits = globalExits;
}
void setGlobalVars(Map<String, GlobalVar> globalVars)
throws EngineException
{
assert globalVars != null;
assert null == mGlobalVars;
String globalvar_name = null;
for (Map.Entry<String, GlobalVar> globalvar_entry : globalVars.entrySet())
{
globalvar_name = globalvar_entry.getKey();
// check if there's no conflicting input
if (containsInput(globalvar_name))
{
throw new GlobalVarInputConflictException(getDeclarationName(), globalvar_name);
}
// check if there's no conflicting output
if (containsOutput(globalvar_name))
{
throw new GlobalVarOutputConflictException(getDeclarationName(), globalvar_name);
}
// check if there's no conflicting submission parameter or file
for (Submission submission : mSubmissions.values())
{
if (submission.containsParameter(globalvar_name))
{
throw new GlobalVarParameterConflictException(getDeclarationName(), globalvar_name, submission.getName());
}
if (submission.containsFile(globalvar_name))
{
throw new GlobalVarFileConflictException(getDeclarationName(), globalvar_name, submission.getName());
}
}
if (globalvar_name != null)
{
mHasGlobalVarDefaults = true;
}
}
mGlobalVars = globalVars;
}
void setGlobalCookies(Map<String, String> globalCookies)
throws EngineException
{
assert globalCookies != null;
assert null == mGlobalCookies;
String globalcookie_name = null;
for (Map.Entry<String, String> globalcookie_entry : globalCookies.entrySet())
{
globalcookie_name = globalcookie_entry.getKey();
// check if there's no conflicting incookie
if (containsIncookie(globalcookie_name))
{
throw new GlobalCookieIncookieConflictException(getDeclarationName(), globalcookie_name);
}
// check if there's no conflicting outcookie
if (containsOutcookie(globalcookie_name))
{
throw new GlobalCookieOutcookieConflictException(getDeclarationName(), globalcookie_name);
}
// check if there's no conflicting submission parameter or file
for (Submission submission : mSubmissions.values())
{
if (submission.containsParameter(globalcookie_name))
{
throw new GlobalCookieParameterConflictException(getDeclarationName(), globalcookie_name, submission.getName());
}
if (submission.containsFile(globalcookie_name))
{
throw new GlobalCookieFileConflictException(getDeclarationName(), globalcookie_name, submission.getName());
}
}
if (globalcookie_name != null)
{
mHasGlobalCookieDefaults = true;
}
}
mGlobalCookies = globalCookies;
}
void setNamedGlobalBeans(Map<String, BeanDeclaration> globalBeans)
throws EngineException
{
assert globalBeans != null;
assert null == mNamedGlobalBeans;
String globalbean_name = null;
for (Map.Entry<String, BeanDeclaration> globalbean_entry : globalBeans.entrySet())
{
globalbean_name = globalbean_entry.getKey();
if (containsNamedInbean(globalbean_name))
{
throw new NamedInbeanGlobalBeanConflictException(getDeclarationName(), globalbean_name);
}
if (containsNamedOutbean(globalbean_name))
{
throw new NamedOutbeanGlobalBeanConflictException(getDeclarationName(), globalbean_name);
}
}
mNamedGlobalBeans = globalBeans;
}
public Collection<String> getGlobalExitNames()
{
if (null == mGlobalExits)
{
return null;
}
return mGlobalExits.keySet();
}
public Collection<String> getGlobalVarNames()
{
if (null == mGlobalVars)
{
return null;
}
return mGlobalVars.keySet();
}
public Collection<String> getGlobalCookieNames()
{
if (null == mGlobalCookies)
{
return null;
}
return mGlobalCookies.keySet();
}
public Collection<String> getNamedGlobalBeanNames()
{
if (null == mNamedGlobalBeans)
{
return null;
}
return mNamedGlobalBeans.keySet();
}
public boolean hasGlobalExits()
{
return !(null == mGlobalExits || mGlobalExits.isEmpty());
}
public boolean hasGlobalVars()
{
return !(null == mGlobalVars || mGlobalVars.isEmpty());
}
public boolean hasGlobalCookies()
{
return !(null == mGlobalCookies || mGlobalCookies.isEmpty());
}
public boolean hasNamedGlobalBeans()
{
return !(null == mNamedGlobalBeans || mNamedGlobalBeans.isEmpty());
}
public boolean containsGlobalExit(String name)
{
if (null == name ||
0 == name.length() ||
null == mGlobalExits)
{
return false;
}
return mGlobalExits.containsKey(name);
}
public boolean containsGlobalVar(String name)
{
if (null == name ||
0 == name.length() ||
null == mGlobalVars)
{
return false;
}
return mGlobalVars.containsKey(name);
}
public boolean containsGlobalCookie(String name)
{
if (null == name ||
0 == name.length() ||
null == mGlobalCookies)
{
return false;
}
return mGlobalCookies.containsKey(name);
}
public boolean containsNamedGlobalBean(String name)
{
if (null == name ||
0 == name.length() ||
null == mNamedGlobalBeans)
{
return false;
}
return mNamedGlobalBeans.containsKey(name);
}
public GlobalExit getGlobalExitInfo(String name)
{
if (null == name ||
0 == name.length() ||
null == mGlobalExits)
{
return null;
}
return mGlobalExits.get(name);
}
public GlobalVar getGlobalVarInfo(String name)
{
if (null == name ||
0 == name.length() ||
null == mGlobalVars)
{
return null;
}
return mGlobalVars.get(name);
}
public String getGlobalCookieInfo(String name)
{
if (null == name ||
0 == name.length() ||
null == mGlobalCookies)
{
return null;
}
return mGlobalCookies.get(name);
}
public BeanDeclaration getNamedGlobalBeanInfo(String name)
{
if (null == name ||
0 == name.length() ||
null == mNamedGlobalBeans)
{
return null;
}
return mNamedGlobalBeans.get(name);
}
void setDepartureVars(ArrayList<String> departureVars)
throws EngineException
{
assert departureVars != null;
assert null == mDepartureVars;
for (String departure_var : departureVars)
{
if (!containsGlobalVar(departure_var))
{
throw new GlobalVarUnknownException(departure_var);
}
}
mDepartureVars = departureVars;
mHasDepartureVars = true;
}
List<String> getDepartureVars()
{
return mDepartureVars;
}
boolean hasDepartureVars()
{
return mHasDepartureVars;
}
boolean containsDepartureVar(String name)
{
assert name != null;
assert name.length() > 0;
if (!mHasDepartureVars ||
null == mDepartureVars)
{
return false;
}
return mDepartureVars.contains(name);
}
void setUrl(String url)
throws EngineException
{
// ensure that the root url is '/' and not ''
if (url != null)
{
if (mUrl != null)
{
throw new ElementAlreadyMappedException(getDeclarationName(), mUrl);
}
if (0 == url.length())
{
mUrl = "/";
return;
}
}
mUrl = url;
}
void setId(String id)
throws EngineException
{
if (null != mId &&
id != null)
{
throw new ElementAlreadyHasIdException(getDeclarationName(), mId);
}
mId = id;
}
void setStateStore(StateStore stateStore)
{
assert stateStore != null;
mStateStore = stateStore;
}
StateStore getStateStore()
{
return mStateStore;
}
void setDeclarationName(String declarationName)
{
mDeclarationName = declarationName;
}
public String getDeclarationName()
{
return mDeclarationName;
}
void setImplementation(String implementation)
throws EngineException
{
mImplementation = implementation;
mImplementationBlueprint = null;
setType(ElementFactory.detectElementType(implementation));
if (null == mType)
{
throw new ElementImplementationUnsupportedException(mDeclarationName, mImplementation, null);
}
}
void setImplementation(String implementation, Element blueprint)
throws EngineException
{
if (null == blueprint)
{
setImplementation(implementation);
}
else
{
mImplementation = implementation;
mImplementationBlueprint = blueprint;
setType(ElementType.JAVA_INSTANCE);
}
}
void setType(ElementType type)
{
mType = type;
}
public String getImplementation()
{
return mImplementation;
}
public Element getImplementationBlueprint()
{
return mImplementationBlueprint;
}
public String getAbsoluteUrl(Element currentElement)
{
if (null == currentElement) throw new IllegalArgumentException("currentElement can't be null.");
if (null == mUrl)
{
return null;
}
String gateservlet_path = currentElement.getElementContext().getRequestState().getGateUrl();
StringBuilder absolute_url = new StringBuilder(gateservlet_path);
if (!gateservlet_path.endsWith("/") &&
!mUrl.startsWith("/"))
{
absolute_url.append("/");
}
absolute_url.append(mUrl);
return absolute_url.toString();
}
public String getUrl()
{
return mUrl;
}
public String getId()
{
return mId;
}
public String getReferenceId()
{
if (null == mReferenceId)
{
return mId;
}
return mReferenceId;
}
void setPathInfoUsed(boolean state)
{
mPathInfoUsed = state;
}
public boolean isPathInfoUsed()
{
return mPathInfoUsed;
}
void setPathInfoMode(PathInfoMode mode)
{
if (null == mode)
{
mode = PathInfoMode.LOOSE;
}
mPathInfoMode = mode;
}
public PathInfoMode getPathInfoMode()
{
return mPathInfoMode;
}
void setPathInfoMappings(List<PathInfoMapping> mappings)
{
mPathInfoMappings = mappings;
}
public List<PathInfoMapping> getPathInfoMappings()
{
return mPathInfoMappings;
}
public boolean hasPathInfoMappings()
{
return mPathInfoMappings != null && mPathInfoMappings.size() > 0;
}
void setErrorHandlers(List<ErrorHandler> handlers)
{
mErrorHandlers = handlers;
}
public List<ErrorHandler> getErrorHandlers()
{
return mErrorHandlers;
}
public boolean hasErrorHandlers()
{
return mErrorHandlers != null && mErrorHandlers.size() > 0;
}
void setContentType(String contentType)
{
if (contentType != null &&
0 == contentType.length())
{
contentType = null;
}
mContentType = contentType;
}
public String getContentType()
{
return mContentType;
}
public ElementType getType()
{
return mType;
}
ElementSupport getElement()
throws EngineException
{
return ElementFactory.INSTANCE.getInstance(this, true);
}
long startTrace()
throws EngineException
{
if (Logger.getLogger("com.uwyn.rife.engine").isLoggable(Level.INFO))
{
if (RifeConfig.Engine.getElementDebugTrace())
{
return System.currentTimeMillis();
}
}
return 0;
}
void outputTrace(long start, RequestState state)
throws EngineException
{
if (start != 0)
{
StringBuilder output = new StringBuilder();
if (RifeConfig.Engine.getElementDebugMemory())
{
Runtime runtime = java.lang.Runtime.getRuntime();
long total_memory = runtime.totalMemory();
long free_memory = runtime.freeMemory();
output.append("total (");
output.append(MEMORY_FORMAT.format(total_memory/1024));
output.append("kb) free (");
output.append(MEMORY_FORMAT.format(free_memory/1024));
output.append("kb) used (");
output.append(MEMORY_FORMAT.format((total_memory-free_memory)/1024));
output.append("kb)");
output.append(" ");
}
output.append(System.currentTimeMillis()-start);
output.append("ms : ");
output.append(state.getServerName());
output.append(":");
output.append(state.getServerPort());
output.append(" ");
output.append(getId());
output.append(" ");
if (state.getRequest() != null &&
state.getRequest().getHttpServletRequest() != null)
{
output.append(state.getRequest().getHttpServletRequest().getRequestURI());
String query_string = state.getRequest().getHttpServletRequest().getQueryString();
if (query_string != null &&
query_string.length() > 0)
{
output.append("?");
output.append(query_string);
}
}
Logger.getLogger("com.uwyn.rife.engine").info(output.toString());
}
}
public HierarchicalProperties getProperties()
{
return mProperties;
}
public Collection<String> getPropertyNames()
{
if (null == mProperties)
{
return Collections.EMPTY_LIST;
}
return mProperties.getNames();
}
public Collection<String> getInjectablePropertyNames()
{
if (null == mProperties)
{
return Collections.EMPTY_LIST;
}
return mProperties.getInjectableNames();
}
public Collection<String> getInputNames()
{
return mInputs.keySet();
}
public Collection<String> getOutputNames()
{
return mOutputs.keySet();
}
public Set<Map.Entry<String, GlobalExit>> getGlobalExitEntries()
{
return mGlobalExits.entrySet();
}
public Set<Map.Entry<String, GlobalVar>> getGlobalVarEntries()
{
return mGlobalVars.entrySet();
}
public Set<Map.Entry<String, String[]>> getOutputEntries()
{
return mOutputs.entrySet();
}
public Collection<String> getIncookieNames()
{
return mIncookies.keySet();
}
public Collection<String> getOutcookieNames()
{
return mOutcookies.keySet();
}
public Set<Map.Entry<String, String>> getGlobalCookieEntries()
{
return mGlobalCookies.entrySet();
}
public Set<Map.Entry<String, String>> getOutcookieEntries()
{
return mOutcookies.entrySet();
}
public boolean hasIncookies()
{
return mIncookies != null && mIncookies.size() > 0;
}
public boolean hasGlobalcookies()
{
return mGlobalCookies != null && mGlobalCookies.size() > 0;
}
public boolean hasOutcookies()
{
return mOutcookies != null && mOutcookies.size() > 0;
}
public boolean hasNamedInbeans()
{
return !(null == mNamedInbeans || mNamedInbeans.isEmpty());
}
public Collection<String> getNamedInbeanNames()
{
return mNamedInbeans.keySet();
}
public Collection<String> getNamedOutbeanNames()
{
return mNamedOutbeans.keySet();
}
public BeanDeclaration getNamedInbeanInfo(String name)
throws EngineException
{
if (null == name ||
0 == name.length() ||
null == mNamedInbeans)
{
return null;
}
return mNamedInbeans.get(name);
}
public BeanDeclaration getNamedOutbeanInfo(String name)
throws EngineException
{
if (null == name ||
0 == name.length() ||
null == mNamedOutbeans)
{
return null;
}
return mNamedOutbeans.get(name);
}
public Collection<String> getChildTriggerNames()
{
return mChildTriggers;
}
public Collection<String> getExitNames()
{
return mExits.keySet();
}
public boolean hasProperties()
{
if (null == mProperties)
{
return false;
}
return mProperties.size() != 0;
}
public Object getProperty(String name)
{
return getProperty(name, null);
}
public Object getProperty(String name, Object defaultValue)
{
if (null == name ||
0 == name.length() ||
null == mProperties)
{
return null;
}
Object result = null;
PropertyValue property = mProperties.get(name);
if (property != null)
{
try
{
result = property.getValue();
}
catch (PropertyValueException e)
{
throw new PropertyValueRetrievalException(getDeclarationName(), name, e);
}
}
if (null == result)
{
return defaultValue;
}
return result;
}
public <T> T getPropertyTyped(String name, Class<T> type)
{
return (T)getPropertyTyped(name, type, null);
}
public <T> T getPropertyTyped(String name, Class<T> type, T defaultValue)
{
if (null == mProperties)
{
return null;
}
try
{
return (T)mProperties.getValueTyped(name, type, defaultValue);
}
catch (PropertyValueException e)
{
throw new PropertyValueRetrievalException(getDeclarationName(), name, e);
}
}
public String getPropertyString(String name)
{
return getPropertyString(name, null);
}
public String getPropertyString(String name, String defaultValue)
{
if (null == name ||
0 == name.length() ||
null == mProperties)
{
return null;
}
try
{
return mProperties.getValueString(name, defaultValue);
}
catch (PropertyValueException e)
{
throw new PropertyValueRetrievalException(getDeclarationName(), name, e);
}
}
public boolean isPropertyEmpty(String name)
throws EngineException
{
if (!containsProperty(name))
{
return true;
}
if (0 == getPropertyString(name, "").length())
{
return true;
}
return false;
}
public Submission getSubmission(String name)
{
if (null == name ||
0 == name.length())
{
return null;
}
return mSubmissions.get(name);
}
public String[] getGlobalVarDefaultValues(String name)
{
if (null == name ||
0 == name.length())
{
return null;
}
GlobalVar data = mGlobalVars.get(name);
if (null == data)
{
return null;
}
return data.getDefaultValues();
}
public String[] getInputDefaultValues(String name)
{
if (null == name ||
0 == name.length())
{
return null;
}
return mInputs.get(name);
}
public String[] getOutputDefaultValues(String name)
{
if (null == name ||
0 == name.length())
{
return null;
}
return mOutputs.get(name);
}
public String getIncookieDefaultValue(String name)
{
if (null == name ||
0 == name.length())
{
return null;
}
return mIncookies.get(name);
}
public String getGlobalCookieDefaultValue(String name)
{
if (null == name ||
0 == name.length())
{
return null;
}
return mGlobalCookies.get(name);
}
public String getOutcookieDefaultValue(String name)
{
if (null == name ||
0 == name.length())
{
return null;
}
return mOutcookies.get(name);
}
public Map<String, String> getDefaultIncookies()
{
Map<String, String> default_incookies = new LinkedHashMap<String, String>();
for (Map.Entry<String, String> incookie_entry : mIncookies.entrySet())
{
if (incookie_entry.getValue() != null)
{
default_incookies.put(incookie_entry.getKey(), incookie_entry.getValue());
}
}
return default_incookies;
}
public Map<String, String> getDefaultOutcookies()
{
Map<String, String> default_outcookies = new LinkedHashMap<String, String>();
for (Map.Entry<String, String> outcookie_entry : mOutcookies.entrySet())
{
if (outcookie_entry.getValue() != null)
{
default_outcookies.put(outcookie_entry.getKey(), outcookie_entry.getValue());
}
}
return default_outcookies;
}
public Map<String, String> getDefaultGlobalCookies()
{
Map<String, String> default_globalcookies = new LinkedHashMap<String, String>();
for (Map.Entry<String, String> globalcookie_entry : mGlobalCookies.entrySet())
{
if (globalcookie_entry.getValue() != null)
{
default_globalcookies.put(globalcookie_entry.getKey(), globalcookie_entry.getValue());
}
}
return default_globalcookies;
}
public String[] getParameterDefaultValues(String submissionName, String parameterName)
{
if (null == submissionName ||
0 == submissionName.length() ||
null == parameterName ||
0 == parameterName.length())
{
return null;
}
return mSubmissions.get(submissionName).getParameterDefaultValues(parameterName);
}
public Set<Map.Entry<String, FlowLink>> getExitEntries()
{
return mExits.entrySet();
}
public Collection<String> getSubmissionNames()
{
return mSubmissions.keySet();
}
public Collection<Submission> getSubmissions()
{
return mSubmissions.values();
}
public FlowLink getFlowLink(String name)
{
if (null == name ||
0 == name.length() ||
!mExits.containsKey(name))
{
return null;
}
return mExits.get(name);
}
public boolean containsProperty(String name)
{
if (null == name ||
0 == name.length() ||
null == mProperties)
{
return false;
}
return mProperties.contains(name);
}
public boolean containsInput(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mInputs.containsKey(name);
}
public boolean containsInputPossibility(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mInputs.containsKey(name) || (mGlobalVars != null && mGlobalVars.containsKey(name));
}
public boolean containsOutput(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mOutputs.containsKey(name);
}
public boolean containsOutputPossibility(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mOutputs.containsKey(name) || (mGlobalVars != null && mGlobalVars.containsKey(name));
}
public boolean containsIncookie(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mIncookies.containsKey(name);
}
public boolean containsIncookiePossibility(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mIncookies.containsKey(name) || (mGlobalCookies != null && mGlobalCookies.containsKey(name));
}
public boolean containsOutcookie(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mOutcookies.containsKey(name);
}
public boolean containsOutcookiePossibility(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mOutcookies.containsKey(name) || (mGlobalCookies != null && mGlobalCookies.containsKey(name));
}
public boolean containsNamedInbean(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mNamedInbeans.containsKey(name);
}
public boolean containsNamedOutbean(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mNamedOutbeans.containsKey(name);
}
public boolean containsChildTrigger(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mChildTriggers.contains(name);
}
public boolean containsExit(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mExits.containsKey(name);
}
public boolean containsSubmission(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mSubmissions.containsKey(name);
}
public boolean hasSubmission(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mSubmissions.containsKey(name);
}
public boolean hasGlobalVarDefaults()
{
return mHasGlobalVarDefaults;
}
public boolean hasGlobalCookieDefaults()
{
return mHasGlobalCookieDefaults;
}
public boolean hasInputDefaults()
{
return mHasInputDefaults;
}
public boolean hasOutputDefaults()
{
return mHasOutputDefaults;
}
public boolean hasIncookieDefaults()
{
return mHasIncookieDefaults;
}
public boolean hasOutcookieDefaults()
{
return mHasOutcookieDefaults;
}
public boolean hasParameterDefaults(String name)
{
if (null == name ||
0 == name.length())
{
return false;
}
return mHasSubmissionDefaults && mSubmissions.get(name).hasParameterDefaults();
}
public boolean hasGlobalVarDefaultValues(String name)
{
if (null == name ||
0 == name.length() ||
!mHasGlobalVarDefaults)
{
return false;
}
GlobalVar data = mGlobalVars.get(name);
if (null == data)
{
return false;
}
if (data.getDefaultValues() != null)
{
return true;
}
return false;
}
public boolean hasGlobalCookieDefaultValue(String name)
{
if (null == name ||
0 == name.length() ||
!mHasGlobalCookieDefaults)
{
return false;
}
String data = mGlobalCookies.get(name);
if (data != null && data.length() != 0)
{
return true;
}
return false;
}
public boolean hasInputs()
{
return mInputs != null && mInputs.size() > 0;
}
public boolean hasInputDefaultValues(String name)
{
if (null == name ||
0 == name.length() ||
!mHasInputDefaults)
{
return false;
}
if (mInputs.get(name) != null)
{
return true;
}
return false;
}
public boolean hasOutputDefaultValues(String name)
{
if (null == name ||
0 == name.length() ||
!mHasOutputDefaults)
{
return false;
}
if (mOutputs.get(name) != null)
{
return true;
}
return false;
}
public boolean hasIncookieDefaultValue(String name)
{
if (null == name ||
0 == name.length() ||
!mHasIncookieDefaults)
{
return false;
}
if (mIncookies.get(name) != null)
{
return true;
}
return false;
}
public boolean hasOutcookieDefaultValue(String name)
{
if (null == name ||
0 == name.length() ||
!mHasOutcookieDefaults)
{
return false;
}
if (mOutcookies.get(name) != null)
{
return true;
}
return false;
}
public boolean hasParameterDefaultValues(String submissionName, String parameterName)
{
if (null == submissionName ||
0 == submissionName.length() ||
null == parameterName ||
0 == parameterName.length() ||
!mHasSubmissionDefaults)
{
return false;
}
return mSubmissions.get(submissionName).hasParameterDefaultValues(parameterName);
}
public boolean hasDataLink(ElementInfo target)
{
assert target != null;
return mDatalinks.containsKey(target);
}
public boolean hasSnapbackDataLinks()
{
return mHasSnapbackDataLinks;
}
public boolean hasFlowLink(ElementInfo target)
{
assert target != null;
if (0 == mExits.size())
{
return false;
}
for (FlowLink flowlink : mExits.values())
{
if (flowlink != null &&
flowlink.getTarget() != null &&
flowlink.getTarget().equals(target))
{
return true;
}
}
return false;
}
public boolean hasSnapbackFlowLinks()
{
return mHasSnapbackFlowLinks;
}
void validatePropertyName(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (!containsProperty(name))
{
throw new PropertyUnknownException(getDeclarationName(), name);
}
}
void validateInputName(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (!containsInput(name) &&
!containsGlobalVar(name))
{
throw new InputUnknownException(getDeclarationName(), name);
}
}
void validateOutputName(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (!containsOutput(name) &&
!containsGlobalVar(name))
{
throw new OutputUnknownException(getDeclarationName(), name);
}
}
void validateIncookieName(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (!containsIncookie(name) &&
!containsGlobalCookie(name))
{
throw new IncookieUnknownException(getDeclarationName(), name);
}
}
void validateOutcookieName(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (!containsOutcookie(name) &&
!containsGlobalCookie(name))
{
throw new OutcookieUnknownException(getDeclarationName(), name);
}
}
void validateInbeanName(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (!containsNamedInbean(name) &&
!containsNamedGlobalBean(name))
{
throw new NamedInbeanUnknownException(getDeclarationName(), name);
}
}
void validateOutbeanName(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (!containsNamedOutbean(name) &&
!containsNamedGlobalBean(name))
{
throw new NamedOutbeanUnknownException(getDeclarationName(), name);
}
}
void validateExitName(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (!containsExit(name))
{
throw new ExitUnknownException(getDeclarationName(), name);
}
}
FlowLink validateAndRetrieveFlowLink(String exitName)
throws EngineException
{
validateExitName(exitName);
FlowLink flowlink = null;
flowlink = getFlowLink(exitName);
if (null == flowlink)
{
throw new ExitNotAttachedException(getDeclarationName(), exitName);
}
return flowlink;
}
void validateSubmissionName(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (!containsSubmission(name))
{
throw new SubmissionUnknownException(getDeclarationName(), name);
}
}
void addDataLink(DataLink dataLink)
throws EngineException
{
assert dataLink != null;
// detect in-lined element declarations and auto-add exits for the flowlinks if they are missing
ElementInfoProcessorFactory factory = ElementInfoProcessorFactory.getElementInfoProcessorFactory(getProcessorIdentifier());
if (factory != null &&
factory.generateOutputsFromDatalinks() &&
!containsOutputPossibility(dataLink.getOutput()))
{
addOutput(dataLink.getOutput(), null);
}
// ensure the valid output
validateOutputName(dataLink.getOutput());
if (dataLink.isSnapback())
{
if (!hasSnapbackFlowLinks())
{
throw new SnapbackFlowLinkMissingException(getDeclarationName());
}
if (!mSnapbackDatalinks.contains(dataLink))
{
mSnapbackDatalinks.add(dataLink);
}
mHasSnapbackDataLinks = true;
}
else
{
ElementInfo target = dataLink.getTarget();
target.validateInputName(dataLink.getInput());
if (this.equals(target))
{
if (!hasFlowLink(target) &&
0 == mSubmissions.size())
{
throw new FlowLinkOrSubmissionMissingException(getDeclarationName());
}
}
else if (!hasFlowLink(target))
{
throw new FlowLinkMissingException(getDeclarationName(), target.getDeclarationName());
}
List<DataLink> datalinks = mDatalinks.get(target);
if (null == datalinks)
{
datalinks = new ArrayList<DataLink>();
mDatalinks.put(target, datalinks);
}
if (!datalinks.contains(dataLink))
{
datalinks.add(dataLink);
}
}
}
Collection<String> getDataLinkInputs(String outputName, ElementInfo target, boolean snapback, FlowLink flowLink)
{
assert outputName != null;
assert outputName.length() > 0;
assert target != null;
// retrieve the target specific datalinks
List<DataLink> datalinks = mDatalinks.get(target);
if (!snapback && null == datalinks)
{
return null;
}
HashSet<String> inputnames_list = new HashSet<String>();
// process the target specific datalinks
if (datalinks != null)
{
for (DataLink datalink : datalinks)
{
if (datalink.getOutput().equals(outputName) &&
(null == datalink.getFlowLink() ||
flowLink != null && datalink.getFlowLink().equals(flowLink)))
{
inputnames_list.add(datalink.getInput());
}
}
}
// process the snapback datalinks
if (snapback)
{
for (DataLink datalink : mSnapbackDatalinks)
{
if (datalink.getOutput().equals(outputName) &&
(null == datalink.getFlowLink() ||
flowLink != null && datalink.getFlowLink().equals(flowLink)))
{
inputnames_list.add(datalink.getInput());
}
}
}
if (0 == inputnames_list.size())
{
return null;
}
return inputnames_list;
}
void setFlowLink(FlowLink flowLink)
throws EngineException
{
assert flowLink != null;
// detect in-lined element declarations and auto-add exits for the flowlinks if they are missing
ElementInfoProcessorFactory factory = ElementInfoProcessorFactory.getElementInfoProcessorFactory(getProcessorIdentifier());
if (factory != null &&
factory.generateExitsFromFlowlinks() &&
!containsExit(flowLink.getExitName()))
{
addExit(flowLink.getExitName());
}
// ensure the valid exit
validateExitName(flowLink.getExitName());
mExits.put(flowLink.getExitName(), flowLink);
if (flowLink.isSnapback())
{
mHasSnapbackFlowLinks = true;
}
}
void addStaticProperty(String name, Object value)
throws EngineException
{
addStaticProperty(name, new PropertyValueObject(value));
}
void addStaticProperty(String name, PropertyValue value)
throws EngineException
{
assert name != null;
assert name.length() > 0;
mStaticProperties.put(name, value);
if (null == mProperties)
{
setProperties(new HierarchicalProperties(), mStaticProperties);
}
}
void addInput(String name, String defaultValues[])
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (defaultValues != null && 0 == defaultValues.length)
{
defaultValues = null;
}
// check that the name isn't reserved
if (ReservedParameters.RESERVED_NAMES_LIST.contains(name))
{
throw new ReservedInputNameException(getDeclarationName(), name);
}
// check if the input doesn't exist already
if (mInputs.containsKey(name))
{
throw new InputExistsException(getDeclarationName(), name);
}
// check if there's no conflicting submission parameter or file
for (Submission submission : mSubmissions.values())
{
if (submission.containsParameter(name))
{
throw new InputParameterConflictException(getDeclarationName(), name, submission.getName());
}
if (submission.containsFile(name))
{
throw new InputFileConflictException(getDeclarationName(), name, submission.getName());
}
}
// check if there's no conflicting global var
if (containsGlobalVar(name))
{
throw new InputGlobalVarConflictException(getDeclarationName(), name);
}
if (defaultValues != null)
{
mHasInputDefaults = true;
}
mInputs.put(name, defaultValues);
}
void addOutput(String name, String[] defaultValues)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (defaultValues != null && 0 == defaultValues.length)
{
defaultValues = null;
}
// check that the name isn't reserved
if (ReservedParameters.RESERVED_NAMES_LIST.contains(name))
{
throw new ReservedOutputNameException(getDeclarationName(), name);
}
// check if the output doesn't exist already
if (mOutputs.containsKey(name))
{
throw new OutputExistsException(getDeclarationName(), name);
}
// check if there's no conflicting global variable
if (containsGlobalVar(name))
{
throw new OutputGlobalVarConflictException(getDeclarationName(), name);
}
if (defaultValues != null)
{
mHasOutputDefaults = true;
}
mOutputs.put(name, defaultValues);
}
void addIncookie(String name, String defaultValue)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (defaultValue != null && 0 == defaultValue.length())
{
defaultValue = null;
}
// check if the incookie doesn't exist already
if (mIncookies.containsKey(name))
{
throw new IncookieExistsException(getDeclarationName(), name);
}
// check if there's no conflicting submission parameter or file
for (Submission submission : mSubmissions.values())
{
if (submission.containsParameter(name))
{
throw new IncookieParameterConflictException(getDeclarationName(), name, submission.getName());
}
if (submission.containsFile(name))
{
throw new IncookieFileConflictException(getDeclarationName(), name, submission.getName());
}
}
// check if there's no conflicting global cookie
if (containsGlobalCookie(name))
{
throw new IncookieGlobalCookieConflictException(getDeclarationName(), name);
}
if (defaultValue != null)
{
mHasIncookieDefaults = true;
}
mIncookies.put(name, defaultValue);
}
void addOutcookie(String name, String defaultValue)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (defaultValue != null && 0 == defaultValue.length())
{
defaultValue = null;
}
// check if the outcookie doesn't exist already
if (mOutcookies.containsKey(name))
{
throw new OutcookieExistsException(getDeclarationName(), name);
}
// check if there's no conflicting global cookie
if (containsGlobalCookie(name))
{
throw new OutcookieGlobalCookieConflictException(getDeclarationName(), name);
}
if (defaultValue != null)
{
mHasOutcookieDefaults = true;
}
mOutcookies.put(name, defaultValue);
}
void addNamedInbean(String name, BeanDeclaration bean)
throws EngineException
{
assert name != null;
assert name.length() > 0;
assert bean != null;
if (containsNamedGlobalBean(name))
{
throw new NamedInbeanGlobalBeanConflictException(getDeclarationName(), name);
}
if (mNamedInbeans.containsKey(name))
{
throw new NamedInbeanExistsException(getDeclarationName(), name);
}
mNamedInbeans.put(name, bean);
}
void addNamedOutbean(String name, BeanDeclaration bean)
throws EngineException
{
assert name != null;
assert name.length() > 0;
assert bean != null;
if (containsNamedGlobalBean(name))
{
throw new NamedOutbeanGlobalBeanConflictException(getDeclarationName(), name);
}
if (mNamedOutbeans.containsKey(name))
{
throw new NamedOutbeanExistsException(getDeclarationName(), name);
}
mNamedOutbeans.put(name, bean);
}
void addChildTrigger(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (!containsInput(name) &&
!containsIncookie(name) &&
!containsOutput(name) &&
!containsOutcookie(name) &&
!containsGlobalVar(name) &&
!containsGlobalCookie(name))
{
throw new ChildTriggerVariableUnknownException(getDeclarationName(), name);
}
if (mChildTriggers.contains(name))
{
throw new ChildTriggerExistsException(getDeclarationName(), name);
}
mChildTriggers.add(name);
}
void addExit(String name)
throws EngineException
{
assert name != null;
assert name.length() > 0;
if (mExits.containsKey(name))
{
throw new ExitExistsException(getDeclarationName(), name);
}
mExits.put(name, null);
}
void addSubmission(String name, Submission submission)
throws EngineException
{
assert name != null;
assert name.length() > 0;
assert submission != null;
if (mSubmissions.containsKey(name))
{
throw new SubmissionExistsException(getDeclarationName(), name);
}
mSubmissions.put(name, submission);
submission.setName(name);
submission.setElementInfo(this);
if (submission.hasParameterDefaults())
{
setHasSubmissionDefaults(true);
}
}
void setHasSubmissionDefaults(boolean hasSubmissionDefaults)
{
mHasSubmissionDefaults = hasSubmissionDefaults;
}
void setDeployer(ElementDeployer deployer)
{
mDeployer = deployer;
}
public ElementDeployer getDeployer()
{
return mDeployer;
}
public synchronized ElementInfo clone()
{
ElementInfo new_elementinfo = null;
try
{
new_elementinfo = (ElementInfo)super.clone();
}
catch (CloneNotSupportedException e)
{
// this should never happen
Logger.getLogger("com.uwyn.rife.engine").severe(ExceptionUtils.getExceptionStackTrace(e));
}
if (mStaticProperties != null)
{
new_elementinfo.mStaticProperties = new HierarchicalProperties()
.putAll(mStaticProperties)
.parent(Rep.getProperties());
}
if (mProperties != null)
{
HierarchicalProperties shadow = mProperties.createShadow(mStaticProperties);
new_elementinfo.mProperties = new HierarchicalProperties().putAll(mProperties);
if (null == shadow.getParent())
{
new_elementinfo.mProperties = new HierarchicalProperties().putAll(mProperties).parent(new_elementinfo.mStaticProperties);
}
else
{
new_elementinfo.setProperties(new HierarchicalProperties().putAll(mProperties), shadow);
}
}
if (mSubmissions != null)
{
new_elementinfo.mSubmissions = new LinkedHashMap<String, Submission>();
Submission submission = null;
for (String id : mSubmissions.keySet())
{
submission = mSubmissions.get(id);
if (submission != null)
{
submission = submission.clone();
}
submission.setElementInfo(this);
new_elementinfo.mSubmissions.put(id, submission);
}
}
if (mInputs != null)
{
new_elementinfo.mInputs = new LinkedHashMap<String, String[]>(mInputs);
}
if (mOutputs != null)
{
new_elementinfo.mOutputs = new LinkedHashMap<String, String[]>(mOutputs);
}
if (mIncookies != null)
{
new_elementinfo.mIncookies = new LinkedHashMap<String, String>(mIncookies);
}
if (mOutcookies != null)
{
new_elementinfo.mOutcookies = new LinkedHashMap<String, String>(mOutcookies);
}
if (mNamedInbeans != null)
{
new_elementinfo.mNamedInbeans = new LinkedHashMap<String, BeanDeclaration>(mNamedInbeans);
}
if (mNamedOutbeans != null)
{
new_elementinfo.mNamedOutbeans = new LinkedHashMap<String, BeanDeclaration>(mNamedOutbeans);
}
if (mChildTriggers != null)
{
new_elementinfo.mChildTriggers = new ArrayList<String>(mChildTriggers);
}
if (mExits != null)
{
new_elementinfo.mExits = new LinkedHashMap<String, FlowLink>(mExits);
}
if (mDatalinks != null)
{
new_elementinfo.mDatalinks = new LinkedHashMap<ElementInfo, List<DataLink>>();
List<DataLink> data_links = null;
for (ElementInfo element_info : mDatalinks.keySet())
{
data_links = mDatalinks.get(element_info);
if (data_links != null)
{
data_links = new ArrayList<DataLink>(data_links);
}
new_elementinfo.mDatalinks.put(element_info, data_links);
}
}
if (mInheritanceStack != null)
{
new_elementinfo.mInheritanceStack = new Stack<ElementInfo>();
new_elementinfo.mInheritanceStack.addAll(mInheritanceStack);
}
if (mPrecedenceStack != null)
{
new_elementinfo.mPrecedenceStack = new Stack<ElementInfo>();
new_elementinfo.mPrecedenceStack.addAll(mPrecedenceStack);
}
if (mGlobalExits != null)
{
new_elementinfo.mGlobalExits = new LinkedHashMap<String, GlobalExit>(mGlobalExits);
}
if (mGlobalVars != null)
{
new_elementinfo.mGlobalVars = new LinkedHashMap<String, GlobalVar>(mGlobalVars);
}
if (mGlobalCookies != null)
{
new_elementinfo.mGlobalCookies = new LinkedHashMap<String, String>(mGlobalCookies);
}
if (mNamedGlobalBeans != null)
{
new_elementinfo.mNamedGlobalBeans = new LinkedHashMap<String, BeanDeclaration>(mNamedGlobalBeans);
}
if (mDepartureVars != null)
{
new_elementinfo.mDepartureVars = new ArrayList<String>(mDepartureVars);
}
if (mPathInfoMappings != null)
{
new_elementinfo.mPathInfoMappings = new ArrayList<PathInfoMapping>(mPathInfoMappings);
}
if (mErrorHandlers != null)
{
new_elementinfo.mErrorHandlers = new ArrayList<ErrorHandler>(mErrorHandlers);
}
return new_elementinfo;
}
}