0001: /*
0002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
0003: * Distributed under the terms of either:
0004: * - the common development and distribution license (CDDL), v1.0; or
0005: * - the GNU Lesser General Public License, v2.1 or later
0006: * $Id: ElementInfo.java 3701 2007-03-18 12:24:23Z gbevin $
0007: */
0008: package com.uwyn.rife.engine;
0009:
0010: import com.uwyn.rife.engine.exceptions.*;
0011: import java.util.*;
0012:
0013: import com.uwyn.rife.config.RifeConfig;
0014: import com.uwyn.rife.ioc.HierarchicalProperties;
0015: import com.uwyn.rife.ioc.PropertyValue;
0016: import com.uwyn.rife.ioc.PropertyValueObject;
0017: import com.uwyn.rife.ioc.exceptions.PropertyValueException;
0018: import com.uwyn.rife.rep.Rep;
0019: import com.uwyn.rife.resources.ResourceFinder;
0020: import com.uwyn.rife.resources.exceptions.ResourceFinderErrorException;
0021: import com.uwyn.rife.tools.ExceptionUtils;
0022: import java.net.URL;
0023: import java.text.NumberFormat;
0024: import java.util.logging.Level;
0025: import java.util.logging.Logger;
0026:
0027: public class ElementInfo implements Cloneable {
0028: public static final boolean DEFAULT_BOOLEAN = false;
0029: public static final int DEFAULT_INTEGER = 0;
0030: public static final long DEFAULT_LONG = 0l;
0031: public static final double DEFAULT_DOUBLE = 0.0d;
0032: public static final float DEFAULT_FLOAT = 0.0f;
0033:
0034: private Site mSite = null;
0035: private String mUrl = null;
0036: private String mProcessorIdentifier = null;
0037: private String mId = null;
0038: private String mReferenceId = null;
0039: private int mGroupId = -1;
0040: private StateStore mStateStore = null;
0041: private boolean mPathInfoUsed = false;
0042: private String mDeclarationName = null;
0043: private String mImplementation = null;
0044: private Element mImplementationBlueprint = null;
0045: private ElementType mType = null;
0046: private String mContentType = null;
0047: private HierarchicalProperties mStaticProperties = null;
0048: private HierarchicalProperties mProperties = null;
0049: private LinkedHashMap<String, Submission> mSubmissions = null;
0050: private LinkedHashMap<String, String[]> mInputs = null;
0051: private LinkedHashMap<String, String[]> mOutputs = null;
0052: private LinkedHashMap<String, String> mIncookies = null;
0053: private LinkedHashMap<String, String> mOutcookies = null;
0054: private LinkedHashMap<String, BeanDeclaration> mNamedInbeans = null;
0055: private LinkedHashMap<String, BeanDeclaration> mNamedOutbeans = null;
0056: private boolean mHasSubmissionDefaults = false;
0057: private boolean mHasGlobalVarDefaults = false;
0058: private boolean mHasGlobalCookieDefaults = false;
0059: private boolean mHasInputDefaults = false;
0060: private boolean mHasOutputDefaults = false;
0061: private boolean mHasIncookieDefaults = false;
0062: private boolean mHasOutcookieDefaults = false;
0063: private boolean mHasSnapbackFlowLinks = false;
0064: private boolean mHasSnapbackDataLinks = false;
0065: private ArrayList<String> mChildTriggers = null;
0066: private LinkedHashMap<String, FlowLink> mExits = null;
0067: private LinkedHashMap<ElementInfo, ArrayList<DataLink>> mDatalinks = null;
0068: private ArrayList<DataLink> mSnapbackDatalinks = null;
0069: private Stack<ElementInfo> mInheritanceStack = null;
0070: private Stack<ElementInfo> mPrecedenceStack = null;
0071: private LinkedHashMap<String, GlobalExit> mGlobalExits = null;
0072: private LinkedHashMap<String, GlobalVar> mGlobalVars = null;
0073: private LinkedHashMap<String, String> mGlobalCookies = null;
0074: private LinkedHashMap<String, BeanDeclaration> mNamedGlobalBeans = null;
0075: private ArrayList<String> mDepartureVars = null;
0076: private boolean mHasDepartureVars = false;
0077: private ElementDeployer mDeployer = null;
0078: private PathInfoMode mPathInfoMode = PathInfoMode.LOOSE;
0079: private List<PathInfoMapping> mPathInfoMappings = null;
0080:
0081: private static NumberFormat MEMORY_FORMAT = null;
0082:
0083: static {
0084: MEMORY_FORMAT = NumberFormat.getIntegerInstance();
0085: MEMORY_FORMAT.setMinimumIntegerDigits(8);
0086: MEMORY_FORMAT.setMaximumIntegerDigits(8);
0087: MEMORY_FORMAT.setGroupingUsed(false);
0088: }
0089:
0090: ElementInfo() throws EngineException {
0091: mStaticProperties = new HierarchicalProperties().parent(Rep
0092: .getProperties());
0093: mSubmissions = new LinkedHashMap<String, Submission>();
0094: mInputs = new LinkedHashMap<String, String[]>();
0095: mOutputs = new LinkedHashMap<String, String[]>();
0096: mIncookies = new LinkedHashMap<String, String>();
0097: mOutcookies = new LinkedHashMap<String, String>();
0098: mNamedInbeans = new LinkedHashMap<String, BeanDeclaration>();
0099: mNamedOutbeans = new LinkedHashMap<String, BeanDeclaration>();
0100: mChildTriggers = new ArrayList<String>();
0101: mExits = new LinkedHashMap<String, FlowLink>();
0102: mDatalinks = new LinkedHashMap<ElementInfo, ArrayList<DataLink>>();
0103: mSnapbackDatalinks = new ArrayList<DataLink>();
0104: mPathInfoMappings = new ArrayList<PathInfoMapping>();
0105: }
0106:
0107: ElementInfo(String declarationName, String contentType,
0108: String implementation, ElementType type)
0109: throws EngineException {
0110: this ();
0111:
0112: setDeclarationName(declarationName);
0113: setContentType(contentType);
0114: setImplementation(implementation);
0115: setType(type);
0116: }
0117:
0118: void extendFrom(ElementInfo extendedElement) {
0119: mProcessorIdentifier = extendedElement.mProcessorIdentifier;
0120: mImplementation = extendedElement.mImplementation;
0121: mType = extendedElement.mType;
0122: mContentType = extendedElement.mContentType;
0123: mStaticProperties = new HierarchicalProperties().putAll(
0124: extendedElement.mStaticProperties).parent(
0125: Rep.getProperties());
0126: mSubmissions = new LinkedHashMap<String, Submission>(
0127: extendedElement.mSubmissions);
0128: mInputs = new LinkedHashMap<String, String[]>(
0129: extendedElement.mInputs);
0130: mOutputs = new LinkedHashMap<String, String[]>(
0131: extendedElement.mOutputs);
0132: mIncookies = new LinkedHashMap<String, String>(
0133: extendedElement.mIncookies);
0134: mOutcookies = new LinkedHashMap<String, String>(
0135: extendedElement.mOutcookies);
0136: mNamedInbeans = new LinkedHashMap<String, BeanDeclaration>(
0137: extendedElement.mNamedInbeans);
0138: mNamedOutbeans = new LinkedHashMap<String, BeanDeclaration>(
0139: extendedElement.mNamedOutbeans);
0140: mHasSubmissionDefaults = extendedElement.mHasSubmissionDefaults;
0141: mHasGlobalVarDefaults = extendedElement.mHasGlobalVarDefaults;
0142: mHasGlobalCookieDefaults = extendedElement.mHasGlobalCookieDefaults;
0143: mHasInputDefaults = extendedElement.mHasInputDefaults;
0144: mHasOutputDefaults = extendedElement.mHasOutputDefaults;
0145: mHasIncookieDefaults = extendedElement.mHasIncookieDefaults;
0146: mHasOutcookieDefaults = extendedElement.mHasOutcookieDefaults;
0147: mHasSnapbackFlowLinks = false;
0148: mHasSnapbackDataLinks = false;
0149: mChildTriggers = new ArrayList<String>(
0150: extendedElement.mChildTriggers);
0151: mExits = new LinkedHashMap<String, FlowLink>(
0152: extendedElement.mExits);
0153: mDatalinks = new LinkedHashMap<ElementInfo, ArrayList<DataLink>>();
0154: mSnapbackDatalinks = new ArrayList<DataLink>();
0155: mPathInfoMode = extendedElement.mPathInfoMode;
0156: mPathInfoMappings = new ArrayList<PathInfoMapping>(
0157: extendedElement.mPathInfoMappings);
0158:
0159: // clear flowlinks
0160: for (String exit : mExits.keySet()) {
0161: mExits.put(exit, null);
0162: }
0163: }
0164:
0165: void populateFrom(ElementInfo referenceElement) {
0166: mSite = referenceElement.mSite;
0167: mDeclarationName = referenceElement.mDeclarationName;
0168: mProcessorIdentifier = referenceElement.mProcessorIdentifier;
0169: mImplementation = referenceElement.mImplementation;
0170: mType = referenceElement.mType;
0171: mUrl = referenceElement.mUrl;
0172: mId = referenceElement.mId;
0173: mReferenceId = referenceElement.getReferenceId();
0174: mGroupId = referenceElement.mGroupId;
0175: mStateStore = referenceElement.mStateStore;
0176: mPathInfoUsed = referenceElement.mPathInfoUsed;
0177: mContentType = referenceElement.mContentType;
0178: mStaticProperties = referenceElement.mStaticProperties;
0179: mSubmissions = referenceElement.mSubmissions;
0180: mInputs = referenceElement.mInputs;
0181: mOutputs = referenceElement.mOutputs;
0182: mIncookies = referenceElement.mIncookies;
0183: mOutcookies = referenceElement.mOutcookies;
0184: mNamedInbeans = referenceElement.mNamedInbeans;
0185: mNamedOutbeans = referenceElement.mNamedOutbeans;
0186: mHasSubmissionDefaults = referenceElement.mHasSubmissionDefaults;
0187: mHasGlobalVarDefaults = referenceElement.mHasGlobalVarDefaults;
0188: mHasGlobalCookieDefaults = referenceElement.mHasGlobalCookieDefaults;
0189: mHasInputDefaults = referenceElement.mHasInputDefaults;
0190: mHasOutputDefaults = referenceElement.mHasOutputDefaults;
0191: mHasIncookieDefaults = referenceElement.mHasIncookieDefaults;
0192: mHasOutcookieDefaults = referenceElement.mHasOutcookieDefaults;
0193: mHasSnapbackFlowLinks = referenceElement.mHasSnapbackFlowLinks;
0194: mHasSnapbackDataLinks = referenceElement.mHasSnapbackDataLinks;
0195: mChildTriggers = referenceElement.mChildTriggers;
0196: mSnapbackDatalinks = referenceElement.mSnapbackDatalinks;
0197: mInheritanceStack = referenceElement.mInheritanceStack;
0198: mGlobalExits = referenceElement.mGlobalExits;
0199: mGlobalVars = referenceElement.mGlobalVars;
0200: mGlobalCookies = referenceElement.mGlobalCookies;
0201: mNamedGlobalBeans = referenceElement.mNamedGlobalBeans;
0202: mDepartureVars = referenceElement.mDepartureVars;
0203: mHasDepartureVars = referenceElement.mHasDepartureVars;
0204: mDeployer = referenceElement.mDeployer;
0205: mPathInfoMode = referenceElement.mPathInfoMode;
0206: mPathInfoMappings = referenceElement.mPathInfoMappings;
0207:
0208: // Go over all the datalinks and flowlinks and check if their targets
0209: // don't point to the reference element itself.
0210: // If that is the case, they have to be adapted to point to the one
0211: // that's being populated instead.
0212: mExits = new LinkedHashMap<String, FlowLink>(
0213: referenceElement.mExits);
0214: Map<FlowLink, FlowLink> replaced_flowlinks = new HashMap<FlowLink, FlowLink>();
0215: for (Map.Entry<String, FlowLink> exits_entry : mExits
0216: .entrySet()) {
0217: FlowLink flowlink = exits_entry.getValue();
0218: if (flowlink != null
0219: && flowlink.getTarget() == referenceElement) {
0220: FlowLink new_flowlink = new FlowLink(flowlink
0221: .getExitName(), this , flowlink.isSnapback(),
0222: flowlink.cancelInheritance(), flowlink
0223: .cancelEmbedding(), flowlink
0224: .isRedirect(), flowlink
0225: .cancelContinuations());
0226: mExits.put(exits_entry.getKey(), new_flowlink);
0227: replaced_flowlinks.put(flowlink, new_flowlink);
0228: }
0229: }
0230:
0231: mDatalinks = new LinkedHashMap<ElementInfo, ArrayList<DataLink>>(
0232: referenceElement.mDatalinks);
0233: ArrayList<DataLink> reflective_datalinks = mDatalinks
0234: .remove(referenceElement);
0235: if (reflective_datalinks != null) {
0236: ArrayList<DataLink> datalinks = new ArrayList<DataLink>();
0237: for (DataLink datalink : reflective_datalinks) {
0238: DataLink new_datalink = new DataLink(datalink
0239: .getOutput(), this , datalink.isSnapback(),
0240: datalink.getInput(), replaced_flowlinks
0241: .get(datalink.getFlowLink()));
0242: datalinks.add(new_datalink);
0243: }
0244: mDatalinks.put(this , datalinks);
0245: }
0246: }
0247:
0248: void deploy() throws EngineException {
0249: ElementSupport element = null;
0250: Class deployment_class = null;
0251: ElementDeployer deployer = null;
0252:
0253: // iterate over all the registered element infos
0254: element = ElementFactory.INSTANCE.getInstance(this , true);
0255:
0256: // try to instantiate each element for the first time
0257: if (element != null) {
0258: if (ElementType.JAVA_CLASS == getType()) {
0259: // obtain the modification time
0260: if (RifeConfig.Engine.getSiteAutoReload()) {
0261: ResourceFinder resource_finder = ElementFactory.INSTANCE
0262: .getResourceFinder();
0263: URL resource = resource_finder
0264: .getResource(mImplementation.replace('.',
0265: '/')
0266: + ".class");
0267: if (resource != null) {
0268: try {
0269: mSite
0270: .addResourceModificationTime(
0271: new UrlResource(resource,
0272: mImplementation),
0273: resource_finder
0274: .getModificationTime(resource));
0275: } catch (ResourceFinderErrorException e) {
0276: throw new ProcessingErrorException(
0277: "element",
0278: mImplementation,
0279: "Error while retrieving the modification time.",
0280: e);
0281: }
0282: }
0283: }
0284: }
0285:
0286: deployment_class = element.getDeploymentClass();
0287:
0288: // check if a deployer is available
0289: if (deployment_class != null) {
0290: try {
0291: // try to instatiate the deployer
0292: deployer = (ElementDeployer) deployment_class
0293: .newInstance();
0294:
0295: // perform the deployment and register it
0296: deployer.setElementInfo(this );
0297: deployer.deploy();
0298: setDeployer(deployer);
0299: } catch (InstantiationException e) {
0300: throw new DeployerInstantiationException(
0301: getDeclarationName(), e);
0302: } catch (IllegalAccessException e) {
0303: throw new DeployerInstantiationException(
0304: getDeclarationName(), e);
0305: } catch (ClassCastException e) {
0306: throw new DeployerInstantiationException(
0307: getDeclarationName(), e);
0308: }
0309: }
0310: }
0311: }
0312:
0313: void setSite(Site site) {
0314: assert site != null;
0315:
0316: mSite = site;
0317: }
0318:
0319: public Site getSite() {
0320: return mSite;
0321: }
0322:
0323: void setProcessorIdentifier(String identifier) {
0324: assert identifier != null;
0325:
0326: mProcessorIdentifier = identifier;
0327: }
0328:
0329: public String getProcessorIdentifier() {
0330: return mProcessorIdentifier;
0331: }
0332:
0333: void setGroupId(int groupId) {
0334: mGroupId = groupId;
0335: }
0336:
0337: public int getGroupId() {
0338: return mGroupId;
0339: }
0340:
0341: HierarchicalProperties getStaticProperties() {
0342: return mStaticProperties;
0343: }
0344:
0345: void setProperties(HierarchicalProperties properties,
0346: HierarchicalProperties parent) {
0347: mProperties = properties.parent(parent);
0348: if (parent != null && parent != mStaticProperties) {
0349: parent.getRoot().parent(mStaticProperties);
0350: }
0351: }
0352:
0353: void setInheritanceStack(Stack<ElementInfo> inheritanceStack) {
0354: assert inheritanceStack != null;
0355: assert null == mInheritanceStack;
0356:
0357: mInheritanceStack = inheritanceStack;
0358: }
0359:
0360: public Stack<ElementInfo> getInheritanceStack() {
0361: return mInheritanceStack;
0362: }
0363:
0364: void setPrecedenceStack(Stack<ElementInfo> precedenceStack) {
0365: assert precedenceStack != null;
0366: assert null == mPrecedenceStack;
0367:
0368: mPrecedenceStack = precedenceStack;
0369: }
0370:
0371: public Stack<ElementInfo> getPrecedenceStack() {
0372: return mPrecedenceStack;
0373: }
0374:
0375: void setGlobalExits(LinkedHashMap<String, GlobalExit> globalExits)
0376: throws EngineException {
0377: assert globalExits != null;
0378: assert null == mGlobalExits;
0379:
0380: mGlobalExits = globalExits;
0381: }
0382:
0383: void setGlobalVars(LinkedHashMap<String, GlobalVar> globalVars)
0384: throws EngineException {
0385: assert globalVars != null;
0386: assert null == mGlobalVars;
0387:
0388: String globalvar_name = null;
0389: for (Map.Entry<String, GlobalVar> globalvar_entry : globalVars
0390: .entrySet()) {
0391: globalvar_name = globalvar_entry.getKey();
0392:
0393: // check if there's no conflicting input
0394: if (containsInput(globalvar_name)) {
0395: throw new GlobalVarInputConflictException(
0396: getDeclarationName(), globalvar_name);
0397: }
0398:
0399: // check if there's no conflicting output
0400: if (containsOutput(globalvar_name)) {
0401: throw new GlobalVarOutputConflictException(
0402: getDeclarationName(), globalvar_name);
0403: }
0404:
0405: // check if there's no conflicting submission parameter or file
0406: for (Submission submission : mSubmissions.values()) {
0407: if (submission.containsParameter(globalvar_name)) {
0408: throw new GlobalVarParameterConflictException(
0409: getDeclarationName(), globalvar_name,
0410: submission.getName());
0411: }
0412:
0413: if (submission.containsFile(globalvar_name)) {
0414: throw new GlobalVarFileConflictException(
0415: getDeclarationName(), globalvar_name,
0416: submission.getName());
0417: }
0418: }
0419:
0420: if (globalvar_name != null) {
0421: mHasGlobalVarDefaults = true;
0422: }
0423: }
0424:
0425: mGlobalVars = globalVars;
0426: }
0427:
0428: void setGlobalCookies(LinkedHashMap<String, String> globalCookies)
0429: throws EngineException {
0430: assert globalCookies != null;
0431: assert null == mGlobalCookies;
0432:
0433: String globalcookie_name = null;
0434: for (Map.Entry<String, String> globalcookie_entry : globalCookies
0435: .entrySet()) {
0436: globalcookie_name = globalcookie_entry.getKey();
0437:
0438: // check if there's no conflicting incookie
0439: if (containsIncookie(globalcookie_name)) {
0440: throw new GlobalCookieIncookieConflictException(
0441: getDeclarationName(), globalcookie_name);
0442: }
0443:
0444: // check if there's no conflicting outcookie
0445: if (containsOutcookie(globalcookie_name)) {
0446: throw new GlobalCookieOutcookieConflictException(
0447: getDeclarationName(), globalcookie_name);
0448: }
0449:
0450: // check if there's no conflicting submission parameter or file
0451: for (Submission submission : mSubmissions.values()) {
0452: if (submission.containsParameter(globalcookie_name)) {
0453: throw new GlobalCookieParameterConflictException(
0454: getDeclarationName(), globalcookie_name,
0455: submission.getName());
0456: }
0457:
0458: if (submission.containsFile(globalcookie_name)) {
0459: throw new GlobalCookieFileConflictException(
0460: getDeclarationName(), globalcookie_name,
0461: submission.getName());
0462: }
0463: }
0464:
0465: if (globalcookie_name != null) {
0466: mHasGlobalCookieDefaults = true;
0467: }
0468: }
0469:
0470: mGlobalCookies = globalCookies;
0471: }
0472:
0473: void setNamedGlobalBeans(
0474: LinkedHashMap<String, BeanDeclaration> globalBeans)
0475: throws EngineException {
0476: assert globalBeans != null;
0477: assert null == mNamedGlobalBeans;
0478:
0479: String globalbean_name = null;
0480: for (Map.Entry<String, BeanDeclaration> globalbean_entry : globalBeans
0481: .entrySet()) {
0482: globalbean_name = globalbean_entry.getKey();
0483:
0484: if (containsNamedInbean(globalbean_name)) {
0485: throw new NamedInbeanGlobalBeanConflictException(
0486: getDeclarationName(), globalbean_name);
0487: }
0488:
0489: if (containsNamedOutbean(globalbean_name)) {
0490: throw new NamedOutbeanGlobalBeanConflictException(
0491: getDeclarationName(), globalbean_name);
0492: }
0493: }
0494:
0495: mNamedGlobalBeans = globalBeans;
0496: }
0497:
0498: public Collection<String> getGlobalExitNames() {
0499: if (null == mGlobalExits) {
0500: return null;
0501: }
0502:
0503: return mGlobalExits.keySet();
0504: }
0505:
0506: public Collection<String> getGlobalVarNames() {
0507: if (null == mGlobalVars) {
0508: return null;
0509: }
0510:
0511: return mGlobalVars.keySet();
0512: }
0513:
0514: public Collection<String> getGlobalCookieNames() {
0515: if (null == mGlobalCookies) {
0516: return null;
0517: }
0518:
0519: return mGlobalCookies.keySet();
0520: }
0521:
0522: public Collection<String> getNamedGlobalBeanNames() {
0523: if (null == mNamedGlobalBeans) {
0524: return null;
0525: }
0526:
0527: return mNamedGlobalBeans.keySet();
0528: }
0529:
0530: public boolean hasGlobalExits() {
0531: return !(null == mGlobalExits || mGlobalExits.isEmpty());
0532: }
0533:
0534: public boolean hasGlobalVars() {
0535: return !(null == mGlobalVars || mGlobalVars.isEmpty());
0536: }
0537:
0538: public boolean hasGlobalCookies() {
0539: return !(null == mGlobalCookies || mGlobalCookies.isEmpty());
0540: }
0541:
0542: public boolean hasNamedGlobalBeans() {
0543: return !(null == mNamedGlobalBeans || mNamedGlobalBeans
0544: .isEmpty());
0545: }
0546:
0547: public boolean containsGlobalExit(String name) {
0548: if (null == name || 0 == name.length() || null == mGlobalExits) {
0549: return false;
0550: }
0551:
0552: return mGlobalExits.containsKey(name);
0553: }
0554:
0555: public boolean containsGlobalVar(String name) {
0556: if (null == name || 0 == name.length() || null == mGlobalVars) {
0557: return false;
0558: }
0559:
0560: return mGlobalVars.containsKey(name);
0561: }
0562:
0563: public boolean containsGlobalCookie(String name) {
0564: if (null == name || 0 == name.length()
0565: || null == mGlobalCookies) {
0566: return false;
0567: }
0568:
0569: return mGlobalCookies.containsKey(name);
0570: }
0571:
0572: public boolean containsNamedGlobalBean(String name) {
0573: if (null == name || 0 == name.length()
0574: || null == mNamedGlobalBeans) {
0575: return false;
0576: }
0577:
0578: return mNamedGlobalBeans.containsKey(name);
0579: }
0580:
0581: public GlobalExit getGlobalExitInfo(String name) {
0582: if (null == name || 0 == name.length() || null == mGlobalExits) {
0583: return null;
0584: }
0585:
0586: return mGlobalExits.get(name);
0587: }
0588:
0589: public GlobalVar getGlobalVarInfo(String name) {
0590: if (null == name || 0 == name.length() || null == mGlobalVars) {
0591: return null;
0592: }
0593:
0594: return mGlobalVars.get(name);
0595: }
0596:
0597: public String getGlobalCookieInfo(String name) {
0598: if (null == name || 0 == name.length()
0599: || null == mGlobalCookies) {
0600: return null;
0601: }
0602:
0603: return mGlobalCookies.get(name);
0604: }
0605:
0606: public BeanDeclaration getNamedGlobalBeanInfo(String name) {
0607: if (null == name || 0 == name.length()
0608: || null == mNamedGlobalBeans) {
0609: return null;
0610: }
0611:
0612: return mNamedGlobalBeans.get(name);
0613: }
0614:
0615: void setDepartureVars(ArrayList<String> departureVars)
0616: throws EngineException {
0617: assert departureVars != null;
0618: assert null == mDepartureVars;
0619:
0620: for (String departure_var : departureVars) {
0621: if (!containsGlobalVar(departure_var)) {
0622: throw new GlobalVarUnknownException(departure_var);
0623: }
0624: }
0625:
0626: mDepartureVars = departureVars;
0627: mHasDepartureVars = true;
0628: }
0629:
0630: ArrayList<String> getDepartureVars() {
0631: return mDepartureVars;
0632: }
0633:
0634: boolean hasDepartureVars() {
0635: return mHasDepartureVars;
0636: }
0637:
0638: boolean containsDepartureVar(String name) {
0639: assert name != null;
0640: assert name.length() > 0;
0641:
0642: if (!mHasDepartureVars || null == mDepartureVars) {
0643: return false;
0644: }
0645:
0646: return mDepartureVars.contains(name);
0647: }
0648:
0649: void setUrl(String url) throws EngineException {
0650: // ensure that the root url is '/' and not ''
0651: if (url != null) {
0652: if (mUrl != null) {
0653: throw new ElementAlreadyMappedException(
0654: getDeclarationName(), mUrl);
0655: }
0656: if (0 == url.length()) {
0657: mUrl = "/";
0658: return;
0659: }
0660: }
0661:
0662: mUrl = url;
0663: }
0664:
0665: void setId(String id) throws EngineException {
0666: if (null != mId && id != null) {
0667: throw new ElementAlreadyHasIdException(
0668: getDeclarationName(), mId);
0669: }
0670: mId = id;
0671: }
0672:
0673: void setStateStore(StateStore stateStore) {
0674: assert stateStore != null;
0675:
0676: mStateStore = stateStore;
0677: }
0678:
0679: StateStore getStateStore() {
0680: return mStateStore;
0681: }
0682:
0683: void setDeclarationName(String declarationName) {
0684: mDeclarationName = declarationName;
0685: }
0686:
0687: public String getDeclarationName() {
0688: return mDeclarationName;
0689: }
0690:
0691: void setImplementation(String implementation)
0692: throws EngineException {
0693: mImplementation = implementation;
0694: mImplementationBlueprint = null;
0695:
0696: setType(ElementFactory.detectElementType(implementation));
0697: if (null == mType) {
0698: throw new ElementImplementationUnsupportedException(
0699: mDeclarationName, mImplementation, null);
0700: }
0701: }
0702:
0703: void setImplementation(String implementation, Element blueprint)
0704: throws EngineException {
0705: if (null == blueprint) {
0706: setImplementation(implementation);
0707: } else {
0708: mImplementation = implementation;
0709: mImplementationBlueprint = blueprint;
0710:
0711: setType(ElementType.JAVA_INSTANCE);
0712: }
0713: }
0714:
0715: void setType(ElementType type) {
0716: mType = type;
0717: }
0718:
0719: public String getImplementation() {
0720: return mImplementation;
0721: }
0722:
0723: public Element getImplementationBlueprint() {
0724: return mImplementationBlueprint;
0725: }
0726:
0727: public String getAbsoluteUrl(Element currentElement) {
0728: if (null == currentElement)
0729: throw new IllegalArgumentException(
0730: "currentElement can't be null.");
0731:
0732: if (null == mUrl) {
0733: return null;
0734: }
0735:
0736: String gateservlet_path = currentElement.getElementContext()
0737: .getRequestState().getGateUrl();
0738: StringBuilder absolute_url = new StringBuilder(gateservlet_path);
0739: if (!gateservlet_path.endsWith("/") && !mUrl.startsWith("/")) {
0740: absolute_url.append("/");
0741: }
0742:
0743: absolute_url.append(mUrl);
0744:
0745: return absolute_url.toString();
0746: }
0747:
0748: public String getUrl() {
0749: return mUrl;
0750: }
0751:
0752: public String getId() {
0753: return mId;
0754: }
0755:
0756: public String getReferenceId() {
0757: if (null == mReferenceId) {
0758: return mId;
0759: }
0760:
0761: return mReferenceId;
0762: }
0763:
0764: void setPathInfoUsed(boolean state) {
0765: mPathInfoUsed = state;
0766: }
0767:
0768: public boolean isPathInfoUsed() {
0769: return mPathInfoUsed;
0770: }
0771:
0772: void setPathInfoMode(PathInfoMode mode) {
0773: if (null == mode) {
0774: mode = PathInfoMode.LOOSE;
0775: }
0776:
0777: mPathInfoMode = mode;
0778: }
0779:
0780: public PathInfoMode getPathInfoMode() {
0781: return mPathInfoMode;
0782: }
0783:
0784: void setPathInfoMappings(List<PathInfoMapping> mappings) {
0785: mPathInfoMappings = mappings;
0786: }
0787:
0788: public List<PathInfoMapping> getPathInfoMappings() {
0789: return mPathInfoMappings;
0790: }
0791:
0792: public boolean hasPathInfoMappings() {
0793: return mPathInfoMappings != null
0794: && mPathInfoMappings.size() > 0;
0795: }
0796:
0797: void setContentType(String contentType) {
0798: if (contentType != null && 0 == contentType.length()) {
0799: contentType = null;
0800: }
0801: mContentType = contentType;
0802: }
0803:
0804: public String getContentType() {
0805: return mContentType;
0806: }
0807:
0808: public ElementType getType() {
0809: return mType;
0810: }
0811:
0812: ElementSupport getElement() throws EngineException {
0813: return ElementFactory.INSTANCE.getInstance(this , true);
0814: }
0815:
0816: long startTrace() throws EngineException {
0817: if (Logger.getLogger("com.uwyn.rife.engine").isLoggable(
0818: Level.INFO)) {
0819: if (RifeConfig.Engine.getElementDebugTrace()) {
0820: return System.currentTimeMillis();
0821: }
0822: }
0823:
0824: return 0;
0825: }
0826:
0827: void outputTrace(long start, RequestState state)
0828: throws EngineException {
0829: if (start != 0) {
0830: StringBuilder output = new StringBuilder();
0831: if (RifeConfig.Engine.getElementDebugMemory()) {
0832: Runtime runtime = java.lang.Runtime.getRuntime();
0833: long total_memory = runtime.totalMemory();
0834: long free_memory = runtime.freeMemory();
0835: output.append("total (");
0836: output
0837: .append(MEMORY_FORMAT
0838: .format(total_memory / 1024));
0839: output.append("kb) free (");
0840: output.append(MEMORY_FORMAT.format(free_memory / 1024));
0841: output.append("kb) used (");
0842: output.append(MEMORY_FORMAT
0843: .format((total_memory - free_memory) / 1024));
0844: output.append("kb)");
0845:
0846: output.append(" ");
0847: }
0848:
0849: output.append(System.currentTimeMillis() - start);
0850: output.append("ms : ");
0851: output.append(state.getServerName());
0852: output.append(":");
0853: output.append(state.getServerPort());
0854: output.append(" ");
0855:
0856: output.append(getId());
0857: output.append(" ");
0858: if (state.getRequest() != null
0859: && state.getRequest().getHttpServletRequest() != null) {
0860: output.append(state.getRequest()
0861: .getHttpServletRequest().getRequestURI());
0862: String query_string = state.getRequest()
0863: .getHttpServletRequest().getQueryString();
0864: if (query_string != null && query_string.length() > 0) {
0865: output.append("?");
0866: output.append(query_string);
0867: }
0868: }
0869:
0870: Logger.getLogger("com.uwyn.rife.engine").info(
0871: output.toString());
0872: }
0873: }
0874:
0875: public HierarchicalProperties getProperties() {
0876: return mProperties;
0877: }
0878:
0879: public Collection<String> getPropertyNames() {
0880: if (null == mProperties) {
0881: return Collections.EMPTY_LIST;
0882: }
0883:
0884: return mProperties.getNames();
0885: }
0886:
0887: public Collection<String> getInjectablePropertyNames() {
0888: if (null == mProperties) {
0889: return Collections.EMPTY_LIST;
0890: }
0891:
0892: return mProperties.getInjectableNames();
0893: }
0894:
0895: public Collection<String> getInputNames() {
0896: return mInputs.keySet();
0897: }
0898:
0899: public Collection<String> getOutputNames() {
0900: return mOutputs.keySet();
0901: }
0902:
0903: public Set<Map.Entry<String, GlobalExit>> getGlobalExitEntries() {
0904: return mGlobalExits.entrySet();
0905: }
0906:
0907: public Set<Map.Entry<String, GlobalVar>> getGlobalVarEntries() {
0908: return mGlobalVars.entrySet();
0909: }
0910:
0911: public Set<Map.Entry<String, String[]>> getOutputEntries() {
0912: return mOutputs.entrySet();
0913: }
0914:
0915: public Collection<String> getIncookieNames() {
0916: return mIncookies.keySet();
0917: }
0918:
0919: public Collection<String> getOutcookieNames() {
0920: return mOutcookies.keySet();
0921: }
0922:
0923: public Set<Map.Entry<String, String>> getGlobalCookieEntries() {
0924: return mGlobalCookies.entrySet();
0925: }
0926:
0927: public Set<Map.Entry<String, String>> getOutcookieEntries() {
0928: return mOutcookies.entrySet();
0929: }
0930:
0931: public boolean hasIncookies() {
0932: return mIncookies != null && mIncookies.size() > 0;
0933: }
0934:
0935: public boolean hasGlobalcookies() {
0936: return mGlobalCookies != null && mGlobalCookies.size() > 0;
0937: }
0938:
0939: public boolean hasOutcookies() {
0940: return mOutcookies != null && mOutcookies.size() > 0;
0941: }
0942:
0943: public boolean hasNamedInbeans() {
0944: return !(null == mNamedInbeans || mNamedInbeans.isEmpty());
0945: }
0946:
0947: public Collection<String> getNamedInbeanNames() {
0948: return mNamedInbeans.keySet();
0949: }
0950:
0951: public Collection<String> getNamedOutbeanNames() {
0952: return mNamedOutbeans.keySet();
0953: }
0954:
0955: public BeanDeclaration getNamedInbeanInfo(String name)
0956: throws EngineException {
0957: if (null == name || 0 == name.length() || null == mNamedInbeans) {
0958: return null;
0959: }
0960:
0961: return mNamedInbeans.get(name);
0962: }
0963:
0964: public BeanDeclaration getNamedOutbeanInfo(String name)
0965: throws EngineException {
0966: if (null == name || 0 == name.length()
0967: || null == mNamedOutbeans) {
0968: return null;
0969: }
0970:
0971: return mNamedOutbeans.get(name);
0972: }
0973:
0974: public Collection<String> getChildTriggerNames() {
0975: return mChildTriggers;
0976: }
0977:
0978: public Collection<String> getExitNames() {
0979: return mExits.keySet();
0980: }
0981:
0982: public boolean hasProperties() {
0983: if (null == mProperties) {
0984: return false;
0985: }
0986:
0987: return mProperties.size() != 0;
0988: }
0989:
0990: public Object getProperty(String name) {
0991: return getProperty(name, null);
0992: }
0993:
0994: public Object getProperty(String name, Object defaultValue) {
0995: if (null == name || 0 == name.length() || null == mProperties) {
0996: return null;
0997: }
0998:
0999: Object result = null;
1000:
1001: PropertyValue property = mProperties.get(name);
1002: if (property != null) {
1003: try {
1004: result = property.getValue();
1005: } catch (PropertyValueException e) {
1006: throw new PropertyValueRetrievalException(
1007: getDeclarationName(), name, e);
1008: }
1009: }
1010:
1011: if (null == result) {
1012: return defaultValue;
1013: }
1014:
1015: return result;
1016: }
1017:
1018: public <T> T getPropertyTyped(String name, Class<T> type) {
1019: return (T) getPropertyTyped(name, type, null);
1020: }
1021:
1022: public <T> T getPropertyTyped(String name, Class<T> type,
1023: T defaultValue) {
1024: if (null == mProperties) {
1025: return null;
1026: }
1027:
1028: try {
1029: return (T) mProperties.getValueTyped(name, type,
1030: defaultValue);
1031: } catch (PropertyValueException e) {
1032: throw new PropertyValueRetrievalException(
1033: getDeclarationName(), name, e);
1034: }
1035: }
1036:
1037: public String getPropertyString(String name) {
1038: return getPropertyString(name, null);
1039: }
1040:
1041: public String getPropertyString(String name, String defaultValue) {
1042: if (null == name || 0 == name.length() || null == mProperties) {
1043: return null;
1044: }
1045:
1046: try {
1047: return mProperties.getValueString(name, defaultValue);
1048: } catch (PropertyValueException e) {
1049: throw new PropertyValueRetrievalException(
1050: getDeclarationName(), name, e);
1051: }
1052: }
1053:
1054: public boolean isPropertyEmpty(String name) throws EngineException {
1055: if (!containsProperty(name)) {
1056: return true;
1057: }
1058:
1059: if (0 == getPropertyString(name, "").length()) {
1060: return true;
1061: }
1062:
1063: return false;
1064: }
1065:
1066: public Submission getSubmission(String name) {
1067: if (null == name || 0 == name.length()) {
1068: return null;
1069: }
1070:
1071: return mSubmissions.get(name);
1072: }
1073:
1074: public String[] getGlobalVarDefaultValues(String name) {
1075: if (null == name || 0 == name.length()) {
1076: return null;
1077: }
1078:
1079: GlobalVar data = mGlobalVars.get(name);
1080: if (null == data) {
1081: return null;
1082: }
1083:
1084: return data.getDefaultValues();
1085: }
1086:
1087: public String[] getInputDefaultValues(String name) {
1088: if (null == name || 0 == name.length()) {
1089: return null;
1090: }
1091:
1092: return mInputs.get(name);
1093: }
1094:
1095: public String[] getOutputDefaultValues(String name) {
1096: if (null == name || 0 == name.length()) {
1097: return null;
1098: }
1099:
1100: return mOutputs.get(name);
1101: }
1102:
1103: public String getIncookieDefaultValue(String name) {
1104: if (null == name || 0 == name.length()) {
1105: return null;
1106: }
1107:
1108: return mIncookies.get(name);
1109: }
1110:
1111: public String getGlobalCookieDefaultValue(String name) {
1112: if (null == name || 0 == name.length()) {
1113: return null;
1114: }
1115:
1116: return mGlobalCookies.get(name);
1117: }
1118:
1119: public String getOutcookieDefaultValue(String name) {
1120: if (null == name || 0 == name.length()) {
1121: return null;
1122: }
1123:
1124: return mOutcookies.get(name);
1125: }
1126:
1127: public LinkedHashMap<String, String> getDefaultIncookies() {
1128: LinkedHashMap<String, String> default_incookies = new LinkedHashMap<String, String>();
1129:
1130: for (Map.Entry<String, String> incookie_entry : mIncookies
1131: .entrySet()) {
1132: if (incookie_entry.getValue() != null) {
1133: default_incookies.put(incookie_entry.getKey(),
1134: incookie_entry.getValue());
1135: }
1136: }
1137:
1138: return default_incookies;
1139: }
1140:
1141: public LinkedHashMap<String, String> getDefaultOutcookies() {
1142: LinkedHashMap<String, String> default_outcookies = new LinkedHashMap<String, String>();
1143:
1144: for (Map.Entry<String, String> outcookie_entry : mOutcookies
1145: .entrySet()) {
1146: if (outcookie_entry.getValue() != null) {
1147: default_outcookies.put(outcookie_entry.getKey(),
1148: outcookie_entry.getValue());
1149: }
1150: }
1151:
1152: return default_outcookies;
1153: }
1154:
1155: public LinkedHashMap<String, String> getDefaultGlobalCookies() {
1156: LinkedHashMap<String, String> default_globalcookies = new LinkedHashMap<String, String>();
1157:
1158: for (Map.Entry<String, String> globalcookie_entry : mGlobalCookies
1159: .entrySet()) {
1160: if (globalcookie_entry.getValue() != null) {
1161: default_globalcookies.put(globalcookie_entry.getKey(),
1162: globalcookie_entry.getValue());
1163: }
1164: }
1165:
1166: return default_globalcookies;
1167: }
1168:
1169: public String[] getParameterDefaultValues(String submissionName,
1170: String parameterName) {
1171: if (null == submissionName || 0 == submissionName.length()
1172: || null == parameterName || 0 == parameterName.length()) {
1173: return null;
1174: }
1175:
1176: return mSubmissions.get(submissionName)
1177: .getParameterDefaultValues(parameterName);
1178: }
1179:
1180: public Set<Map.Entry<String, FlowLink>> getExitEntries() {
1181: return mExits.entrySet();
1182: }
1183:
1184: public Collection<String> getSubmissionNames() {
1185: return mSubmissions.keySet();
1186: }
1187:
1188: public Collection<Submission> getSubmissions() {
1189: return mSubmissions.values();
1190: }
1191:
1192: public FlowLink getFlowLink(String name) {
1193: if (null == name || 0 == name.length()
1194: || !mExits.containsKey(name)) {
1195: return null;
1196: }
1197:
1198: return mExits.get(name);
1199: }
1200:
1201: public boolean containsProperty(String name) {
1202: if (null == name || 0 == name.length() || null == mProperties) {
1203: return false;
1204: }
1205:
1206: return mProperties.contains(name);
1207: }
1208:
1209: public boolean containsInput(String name) {
1210: if (null == name || 0 == name.length()) {
1211: return false;
1212: }
1213:
1214: return mInputs.containsKey(name);
1215: }
1216:
1217: public boolean containsInputPossibility(String name) {
1218: if (null == name || 0 == name.length()) {
1219: return false;
1220: }
1221:
1222: return mInputs.containsKey(name)
1223: || (mGlobalVars != null && mGlobalVars
1224: .containsKey(name));
1225: }
1226:
1227: public boolean containsOutput(String name) {
1228: if (null == name || 0 == name.length()) {
1229: return false;
1230: }
1231:
1232: return mOutputs.containsKey(name);
1233: }
1234:
1235: public boolean containsOutputPossibility(String name) {
1236: if (null == name || 0 == name.length()) {
1237: return false;
1238: }
1239:
1240: return mOutputs.containsKey(name)
1241: || (mGlobalVars != null && mGlobalVars
1242: .containsKey(name));
1243: }
1244:
1245: public boolean containsIncookie(String name) {
1246: if (null == name || 0 == name.length()) {
1247: return false;
1248: }
1249:
1250: return mIncookies.containsKey(name);
1251: }
1252:
1253: public boolean containsIncookiePossibility(String name) {
1254: if (null == name || 0 == name.length()) {
1255: return false;
1256: }
1257:
1258: return mIncookies.containsKey(name)
1259: || (mGlobalCookies != null && mGlobalCookies
1260: .containsKey(name));
1261: }
1262:
1263: public boolean containsOutcookie(String name) {
1264: if (null == name || 0 == name.length()) {
1265: return false;
1266: }
1267:
1268: return mOutcookies.containsKey(name);
1269: }
1270:
1271: public boolean containsOutcookiePossibility(String name) {
1272: if (null == name || 0 == name.length()) {
1273: return false;
1274: }
1275:
1276: return mOutcookies.containsKey(name)
1277: || (mGlobalCookies != null && mGlobalCookies
1278: .containsKey(name));
1279: }
1280:
1281: public boolean containsNamedInbean(String name) {
1282: if (null == name || 0 == name.length()) {
1283: return false;
1284: }
1285:
1286: return mNamedInbeans.containsKey(name);
1287: }
1288:
1289: public boolean containsNamedOutbean(String name) {
1290: if (null == name || 0 == name.length()) {
1291: return false;
1292: }
1293:
1294: return mNamedOutbeans.containsKey(name);
1295: }
1296:
1297: public boolean containsChildTrigger(String name) {
1298: if (null == name || 0 == name.length()) {
1299: return false;
1300: }
1301:
1302: return mChildTriggers.contains(name);
1303: }
1304:
1305: public boolean containsExit(String name) {
1306: if (null == name || 0 == name.length()) {
1307: return false;
1308: }
1309:
1310: return mExits.containsKey(name);
1311: }
1312:
1313: public boolean containsSubmission(String name) {
1314: if (null == name || 0 == name.length()) {
1315: return false;
1316: }
1317:
1318: return mSubmissions.containsKey(name);
1319: }
1320:
1321: public boolean hasSubmission(String name) {
1322: if (null == name || 0 == name.length()) {
1323: return false;
1324: }
1325:
1326: return mSubmissions.containsKey(name);
1327: }
1328:
1329: public boolean hasGlobalVarDefaults() {
1330: return mHasGlobalVarDefaults;
1331: }
1332:
1333: public boolean hasGlobalCookieDefaults() {
1334: return mHasGlobalCookieDefaults;
1335: }
1336:
1337: public boolean hasInputDefaults() {
1338: return mHasInputDefaults;
1339: }
1340:
1341: public boolean hasOutputDefaults() {
1342: return mHasOutputDefaults;
1343: }
1344:
1345: public boolean hasIncookieDefaults() {
1346: return mHasIncookieDefaults;
1347: }
1348:
1349: public boolean hasOutcookieDefaults() {
1350: return mHasOutcookieDefaults;
1351: }
1352:
1353: public boolean hasParameterDefaults(String name) {
1354: if (null == name || 0 == name.length()) {
1355: return false;
1356: }
1357:
1358: return mHasSubmissionDefaults
1359: && mSubmissions.get(name).hasParameterDefaults();
1360: }
1361:
1362: public boolean hasGlobalVarDefaultValues(String name) {
1363: if (null == name || 0 == name.length()
1364: || !mHasGlobalVarDefaults) {
1365: return false;
1366: }
1367:
1368: GlobalVar data = mGlobalVars.get(name);
1369: if (null == data) {
1370: return false;
1371: }
1372: if (data.getDefaultValues() != null) {
1373: return true;
1374: }
1375:
1376: return false;
1377: }
1378:
1379: public boolean hasGlobalCookieDefaultValue(String name) {
1380: if (null == name || 0 == name.length()
1381: || !mHasGlobalCookieDefaults) {
1382: return false;
1383: }
1384:
1385: String data = mGlobalCookies.get(name);
1386:
1387: if (data != null && data.length() != 0) {
1388: return true;
1389: }
1390:
1391: return false;
1392: }
1393:
1394: public boolean hasInputs() {
1395: return mInputs != null && mInputs.size() > 0;
1396: }
1397:
1398: public boolean hasInputDefaultValues(String name) {
1399: if (null == name || 0 == name.length() || !mHasInputDefaults) {
1400: return false;
1401: }
1402:
1403: if (mInputs.get(name) != null) {
1404: return true;
1405: }
1406:
1407: return false;
1408: }
1409:
1410: public boolean hasOutputDefaultValues(String name) {
1411: if (null == name || 0 == name.length() || !mHasOutputDefaults) {
1412: return false;
1413: }
1414:
1415: if (mOutputs.get(name) != null) {
1416: return true;
1417: }
1418:
1419: return false;
1420: }
1421:
1422: public boolean hasIncookieDefaultValue(String name) {
1423: if (null == name || 0 == name.length() || !mHasIncookieDefaults) {
1424: return false;
1425: }
1426:
1427: if (mIncookies.get(name) != null) {
1428: return true;
1429: }
1430:
1431: return false;
1432: }
1433:
1434: public boolean hasOutcookieDefaultValue(String name) {
1435: if (null == name || 0 == name.length()
1436: || !mHasOutcookieDefaults) {
1437: return false;
1438: }
1439:
1440: if (mOutcookies.get(name) != null) {
1441: return true;
1442: }
1443:
1444: return false;
1445: }
1446:
1447: public boolean hasParameterDefaultValues(String submissionName,
1448: String parameterName) {
1449: if (null == submissionName || 0 == submissionName.length()
1450: || null == parameterName || 0 == parameterName.length()
1451: || !mHasSubmissionDefaults) {
1452: return false;
1453: }
1454:
1455: return mSubmissions.get(submissionName)
1456: .hasParameterDefaultValues(parameterName);
1457: }
1458:
1459: public boolean hasDataLink(ElementInfo target) {
1460: assert target != null;
1461:
1462: return mDatalinks.containsKey(target);
1463: }
1464:
1465: public boolean hasSnapbackDataLinks() {
1466: return mHasSnapbackDataLinks;
1467: }
1468:
1469: public boolean hasFlowLink(ElementInfo target) {
1470: assert target != null;
1471:
1472: if (0 == mExits.size()) {
1473: return false;
1474: }
1475:
1476: for (FlowLink flowlink : mExits.values()) {
1477: if (flowlink != null && flowlink.getTarget() != null
1478: && flowlink.getTarget().equals(target)) {
1479: return true;
1480: }
1481: }
1482:
1483: return false;
1484: }
1485:
1486: public boolean hasSnapbackFlowLinks() {
1487: return mHasSnapbackFlowLinks;
1488: }
1489:
1490: void validatePropertyName(String name) throws EngineException {
1491: assert name != null;
1492: assert name.length() > 0;
1493:
1494: if (!containsProperty(name)) {
1495: throw new PropertyUnknownException(getDeclarationName(),
1496: name);
1497: }
1498: }
1499:
1500: void validateInputName(String name) throws EngineException {
1501: assert name != null;
1502: assert name.length() > 0;
1503:
1504: if (!containsInput(name) && !containsGlobalVar(name)) {
1505: throw new InputUnknownException(getDeclarationName(), name);
1506: }
1507: }
1508:
1509: void validateOutputName(String name) throws EngineException {
1510: assert name != null;
1511: assert name.length() > 0;
1512:
1513: if (!containsOutput(name) && !containsGlobalVar(name)) {
1514: throw new OutputUnknownException(getDeclarationName(), name);
1515: }
1516: }
1517:
1518: void validateIncookieName(String name) throws EngineException {
1519: assert name != null;
1520: assert name.length() > 0;
1521:
1522: if (!containsIncookie(name) && !containsGlobalCookie(name)) {
1523: throw new IncookieUnknownException(getDeclarationName(),
1524: name);
1525: }
1526: }
1527:
1528: void validateOutcookieName(String name) throws EngineException {
1529: assert name != null;
1530: assert name.length() > 0;
1531:
1532: if (!containsOutcookie(name) && !containsGlobalCookie(name)) {
1533: throw new OutcookieUnknownException(getDeclarationName(),
1534: name);
1535: }
1536: }
1537:
1538: void validateInbeanName(String name) throws EngineException {
1539: assert name != null;
1540: assert name.length() > 0;
1541:
1542: if (!containsNamedInbean(name)
1543: && !containsNamedGlobalBean(name)) {
1544: throw new NamedInbeanUnknownException(getDeclarationName(),
1545: name);
1546: }
1547: }
1548:
1549: void validateOutbeanName(String name) throws EngineException {
1550: assert name != null;
1551: assert name.length() > 0;
1552:
1553: if (!containsNamedOutbean(name)
1554: && !containsNamedGlobalBean(name)) {
1555: throw new NamedOutbeanUnknownException(
1556: getDeclarationName(), name);
1557: }
1558: }
1559:
1560: void validateExitName(String name) throws EngineException {
1561: assert name != null;
1562: assert name.length() > 0;
1563:
1564: if (!containsExit(name)) {
1565: throw new ExitUnknownException(getDeclarationName(), name);
1566: }
1567: }
1568:
1569: void validateSubmissionName(String name) throws EngineException {
1570: assert name != null;
1571: assert name.length() > 0;
1572:
1573: if (!containsSubmission(name)) {
1574: throw new SubmissionUnknownException(getDeclarationName(),
1575: name);
1576: }
1577: }
1578:
1579: void addDataLink(DataLink dataLink) throws EngineException {
1580: assert dataLink != null;
1581:
1582: // detect in-lined element declarations and auto-add exits for the flowlinks if they are missing
1583: ElementInfoProcessorFactory factory = ElementInfoProcessorFactory
1584: .getElementInfoProcessorFactory(getProcessorIdentifier());
1585: if (factory != null && factory.generateOutputsFromDatalinks()
1586: && !containsOutputPossibility(dataLink.getOutput())) {
1587: addOutput(dataLink.getOutput(), null);
1588: }
1589:
1590: // ensure the valid output
1591: validateOutputName(dataLink.getOutput());
1592:
1593: if (dataLink.isSnapback()) {
1594: if (!hasSnapbackFlowLinks()) {
1595: throw new SnapbackFlowLinkMissingException(
1596: getDeclarationName());
1597: }
1598: if (!mSnapbackDatalinks.contains(dataLink)) {
1599: mSnapbackDatalinks.add(dataLink);
1600: }
1601: mHasSnapbackDataLinks = true;
1602: } else {
1603: ElementInfo target = dataLink.getTarget();
1604: target.validateInputName(dataLink.getInput());
1605: if (this .equals(target)) {
1606: if (!hasFlowLink(target) && 0 == mSubmissions.size()) {
1607: throw new FlowLinkOrSubmissionMissingException(
1608: getDeclarationName());
1609: }
1610: } else if (!hasFlowLink(target)) {
1611: throw new FlowLinkMissingException(
1612: getDeclarationName(), target
1613: .getDeclarationName());
1614: }
1615:
1616: ArrayList<DataLink> datalinks = mDatalinks.get(target);
1617: if (null == datalinks) {
1618: datalinks = new ArrayList<DataLink>();
1619: mDatalinks.put(target, datalinks);
1620: }
1621: if (!datalinks.contains(dataLink)) {
1622: datalinks.add(dataLink);
1623: }
1624: }
1625: }
1626:
1627: Collection<String> getDataLinkInputs(String outputName,
1628: ElementInfo target, boolean snapback, FlowLink flowLink) {
1629: assert outputName != null;
1630: assert outputName.length() > 0;
1631: assert target != null;
1632:
1633: // retrieve the target specific datalinks
1634: ArrayList<DataLink> datalinks = mDatalinks.get(target);
1635: if (!snapback && null == datalinks) {
1636: return null;
1637: }
1638:
1639: HashSet<String> inputnames_list = new HashSet<String>();
1640:
1641: // process the target specific datalinks
1642: if (datalinks != null) {
1643: for (DataLink datalink : datalinks) {
1644: if (datalink.getOutput().equals(outputName)
1645: && (null == datalink.getFlowLink() || flowLink != null
1646: && datalink.getFlowLink().equals(
1647: flowLink))) {
1648: inputnames_list.add(datalink.getInput());
1649: }
1650: }
1651: }
1652:
1653: // process the snapback datalinks
1654: if (snapback) {
1655: for (DataLink datalink : mSnapbackDatalinks) {
1656: if (datalink.getOutput().equals(outputName)
1657: && (null == datalink.getFlowLink() || flowLink != null
1658: && datalink.getFlowLink().equals(
1659: flowLink))) {
1660: inputnames_list.add(datalink.getInput());
1661: }
1662: }
1663: }
1664:
1665: if (0 == inputnames_list.size()) {
1666: return null;
1667: }
1668:
1669: return inputnames_list;
1670: }
1671:
1672: void setFlowLink(FlowLink flowLink) throws EngineException {
1673: assert flowLink != null;
1674:
1675: // detect in-lined element declarations and auto-add exits for the flowlinks if they are missing
1676: ElementInfoProcessorFactory factory = ElementInfoProcessorFactory
1677: .getElementInfoProcessorFactory(getProcessorIdentifier());
1678: if (factory != null && factory.generateExitsFromFlowlinks()
1679: && !containsExit(flowLink.getExitName())) {
1680: addExit(flowLink.getExitName());
1681: }
1682:
1683: // ensure the valid exit
1684: validateExitName(flowLink.getExitName());
1685:
1686: mExits.put(flowLink.getExitName(), flowLink);
1687: if (flowLink.isSnapback()) {
1688: mHasSnapbackFlowLinks = true;
1689: }
1690: }
1691:
1692: void addStaticProperty(String name, Object value)
1693: throws EngineException {
1694: addStaticProperty(name, new PropertyValueObject(value));
1695: }
1696:
1697: void addStaticProperty(String name, PropertyValue value)
1698: throws EngineException {
1699: assert name != null;
1700: assert name.length() > 0;
1701:
1702: mStaticProperties.put(name, value);
1703: if (null == mProperties) {
1704: setProperties(new HierarchicalProperties(),
1705: mStaticProperties);
1706: }
1707: }
1708:
1709: void addInput(String name, String defaultValues[])
1710: throws EngineException {
1711: assert name != null;
1712: assert name.length() > 0;
1713:
1714: if (defaultValues != null && 0 == defaultValues.length) {
1715: defaultValues = null;
1716: }
1717:
1718: // check that the name isn't reserved
1719: if (ReservedParameters.RESERVED_NAMES_LIST.contains(name)) {
1720: throw new ReservedInputNameException(getDeclarationName(),
1721: name);
1722: }
1723:
1724: // check if the input doesn't exist already
1725: if (mInputs.containsKey(name)) {
1726: throw new InputExistsException(getDeclarationName(), name);
1727: }
1728:
1729: // check if there's no conflicting submission parameter or file
1730: for (Submission submission : mSubmissions.values()) {
1731: if (submission.containsParameter(name)) {
1732: throw new InputParameterConflictException(
1733: getDeclarationName(), name, submission
1734: .getName());
1735: }
1736:
1737: if (submission.containsFile(name)) {
1738: throw new InputFileConflictException(
1739: getDeclarationName(), name, submission
1740: .getName());
1741: }
1742: }
1743:
1744: // check if there's no conflicting global var
1745: if (containsGlobalVar(name)) {
1746: throw new InputGlobalVarConflictException(
1747: getDeclarationName(), name);
1748: }
1749:
1750: if (defaultValues != null) {
1751: mHasInputDefaults = true;
1752: }
1753:
1754: mInputs.put(name, defaultValues);
1755: }
1756:
1757: void addOutput(String name, String[] defaultValues)
1758: throws EngineException {
1759: assert name != null;
1760: assert name.length() > 0;
1761:
1762: if (defaultValues != null && 0 == defaultValues.length) {
1763: defaultValues = null;
1764: }
1765:
1766: // check that the name isn't reserved
1767: if (ReservedParameters.RESERVED_NAMES_LIST.contains(name)) {
1768: throw new ReservedOutputNameException(getDeclarationName(),
1769: name);
1770: }
1771:
1772: // check if the output doesn't exist already
1773: if (mOutputs.containsKey(name)) {
1774: throw new OutputExistsException(getDeclarationName(), name);
1775: }
1776:
1777: // check if there's no conflicting global variable
1778: if (containsGlobalVar(name)) {
1779: throw new OutputGlobalVarConflictException(
1780: getDeclarationName(), name);
1781: }
1782:
1783: if (defaultValues != null) {
1784: mHasOutputDefaults = true;
1785: }
1786:
1787: mOutputs.put(name, defaultValues);
1788: }
1789:
1790: void addIncookie(String name, String defaultValue)
1791: throws EngineException {
1792: assert name != null;
1793: assert name.length() > 0;
1794:
1795: if (defaultValue != null && 0 == defaultValue.length()) {
1796: defaultValue = null;
1797: }
1798:
1799: // check if the incookie doesn't exist already
1800: if (mIncookies.containsKey(name)) {
1801: throw new IncookieExistsException(getDeclarationName(),
1802: name);
1803: }
1804:
1805: // check if there's no conflicting submission parameter or file
1806: for (Submission submission : mSubmissions.values()) {
1807: if (submission.containsParameter(name)) {
1808: throw new IncookieParameterConflictException(
1809: getDeclarationName(), name, submission
1810: .getName());
1811: }
1812:
1813: if (submission.containsFile(name)) {
1814: throw new IncookieFileConflictException(
1815: getDeclarationName(), name, submission
1816: .getName());
1817: }
1818: }
1819:
1820: // check if there's no conflicting global cookie
1821: if (containsGlobalCookie(name)) {
1822: throw new IncookieGlobalCookieConflictException(
1823: getDeclarationName(), name);
1824: }
1825:
1826: if (defaultValue != null) {
1827: mHasIncookieDefaults = true;
1828: }
1829:
1830: mIncookies.put(name, defaultValue);
1831: }
1832:
1833: void addOutcookie(String name, String defaultValue)
1834: throws EngineException {
1835: assert name != null;
1836: assert name.length() > 0;
1837:
1838: if (defaultValue != null && 0 == defaultValue.length()) {
1839: defaultValue = null;
1840: }
1841:
1842: // check if the outcookie doesn't exist already
1843: if (mOutcookies.containsKey(name)) {
1844: throw new OutcookieExistsException(getDeclarationName(),
1845: name);
1846: }
1847:
1848: // check if there's no conflicting global cookie
1849: if (containsGlobalCookie(name)) {
1850: throw new OutcookieGlobalCookieConflictException(
1851: getDeclarationName(), name);
1852: }
1853:
1854: if (defaultValue != null) {
1855: mHasOutcookieDefaults = true;
1856: }
1857:
1858: mOutcookies.put(name, defaultValue);
1859: }
1860:
1861: void addNamedInbean(String name, BeanDeclaration bean)
1862: throws EngineException {
1863: assert name != null;
1864: assert name.length() > 0;
1865: assert bean != null;
1866:
1867: if (containsNamedGlobalBean(name)) {
1868: throw new NamedInbeanGlobalBeanConflictException(
1869: getDeclarationName(), name);
1870: }
1871:
1872: if (mNamedInbeans.containsKey(name)) {
1873: throw new NamedInbeanExistsException(getDeclarationName(),
1874: name);
1875: }
1876:
1877: mNamedInbeans.put(name, bean);
1878: }
1879:
1880: void addNamedOutbean(String name, BeanDeclaration bean)
1881: throws EngineException {
1882: assert name != null;
1883: assert name.length() > 0;
1884: assert bean != null;
1885:
1886: if (containsNamedGlobalBean(name)) {
1887: throw new NamedOutbeanGlobalBeanConflictException(
1888: getDeclarationName(), name);
1889: }
1890:
1891: if (mNamedOutbeans.containsKey(name)) {
1892: throw new NamedOutbeanExistsException(getDeclarationName(),
1893: name);
1894: }
1895:
1896: mNamedOutbeans.put(name, bean);
1897: }
1898:
1899: void addChildTrigger(String name) throws EngineException {
1900: assert name != null;
1901: assert name.length() > 0;
1902:
1903: if (!containsInput(name) && !containsIncookie(name)
1904: && !containsOutput(name) && !containsOutcookie(name)
1905: && !containsGlobalVar(name)
1906: && !containsGlobalCookie(name)) {
1907: throw new ChildTriggerVariableUnknownException(
1908: getDeclarationName(), name);
1909: }
1910:
1911: if (mChildTriggers.contains(name)) {
1912: throw new ChildTriggerExistsException(getDeclarationName(),
1913: name);
1914: }
1915:
1916: mChildTriggers.add(name);
1917: }
1918:
1919: void addExit(String name) throws EngineException {
1920: assert name != null;
1921: assert name.length() > 0;
1922:
1923: if (mExits.containsKey(name)) {
1924: throw new ExitExistsException(getDeclarationName(), name);
1925: }
1926:
1927: mExits.put(name, null);
1928: }
1929:
1930: void addSubmission(String name, Submission submission)
1931: throws EngineException {
1932: assert name != null;
1933: assert name.length() > 0;
1934: assert submission != null;
1935:
1936: if (mSubmissions.containsKey(name)) {
1937: throw new SubmissionExistsException(getDeclarationName(),
1938: name);
1939: }
1940:
1941: mSubmissions.put(name, submission);
1942: submission.setName(name);
1943: submission.setElementInfo(this );
1944:
1945: if (submission.hasParameterDefaults()) {
1946: setHasSubmissionDefaults(true);
1947: }
1948: }
1949:
1950: void setHasSubmissionDefaults(boolean hasSubmissionDefaults) {
1951: mHasSubmissionDefaults = hasSubmissionDefaults;
1952: }
1953:
1954: void setDeployer(ElementDeployer deployer) {
1955: mDeployer = deployer;
1956: }
1957:
1958: public ElementDeployer getDeployer() {
1959: return mDeployer;
1960: }
1961:
1962: public synchronized ElementInfo clone() {
1963: ElementInfo new_elementinfo = null;
1964: try {
1965: new_elementinfo = (ElementInfo) super .clone();
1966: } catch (CloneNotSupportedException e) {
1967: // this should never happen
1968: Logger.getLogger("com.uwyn.rife.engine").severe(
1969: ExceptionUtils.getExceptionStackTrace(e));
1970: }
1971:
1972: if (mStaticProperties != null) {
1973: new_elementinfo.mStaticProperties = new HierarchicalProperties()
1974: .putAll(mStaticProperties).parent(
1975: Rep.getProperties());
1976: }
1977:
1978: if (mProperties != null) {
1979: HierarchicalProperties shadow = mProperties
1980: .createShadow(mStaticProperties);
1981: new_elementinfo.mProperties = new HierarchicalProperties()
1982: .putAll(mProperties);
1983: if (null == shadow.getParent()) {
1984: new_elementinfo.mProperties = new HierarchicalProperties()
1985: .putAll(mProperties).parent(
1986: new_elementinfo.mStaticProperties);
1987: } else {
1988: new_elementinfo.setProperties(
1989: new HierarchicalProperties()
1990: .putAll(mProperties), shadow);
1991: }
1992: }
1993:
1994: if (mSubmissions != null) {
1995: new_elementinfo.mSubmissions = new LinkedHashMap<String, Submission>();
1996:
1997: Submission submission = null;
1998: for (String id : mSubmissions.keySet()) {
1999: submission = mSubmissions.get(id);
2000: if (submission != null) {
2001: submission = submission.clone();
2002: }
2003: submission.setElementInfo(this );
2004: new_elementinfo.mSubmissions.put(id, submission);
2005: }
2006: }
2007:
2008: if (mInputs != null) {
2009: new_elementinfo.mInputs = new LinkedHashMap<String, String[]>(
2010: mInputs);
2011: }
2012:
2013: if (mOutputs != null) {
2014: new_elementinfo.mOutputs = new LinkedHashMap<String, String[]>(
2015: mOutputs);
2016: }
2017:
2018: if (mIncookies != null) {
2019: new_elementinfo.mIncookies = new LinkedHashMap<String, String>(
2020: mIncookies);
2021: }
2022:
2023: if (mOutcookies != null) {
2024: new_elementinfo.mOutcookies = new LinkedHashMap<String, String>(
2025: mOutcookies);
2026: }
2027:
2028: if (mNamedInbeans != null) {
2029: new_elementinfo.mNamedInbeans = new LinkedHashMap<String, BeanDeclaration>(
2030: mNamedInbeans);
2031: }
2032:
2033: if (mNamedOutbeans != null) {
2034: new_elementinfo.mNamedOutbeans = new LinkedHashMap<String, BeanDeclaration>(
2035: mNamedOutbeans);
2036: }
2037:
2038: if (mChildTriggers != null) {
2039: new_elementinfo.mChildTriggers = new ArrayList<String>(
2040: mChildTriggers);
2041: }
2042:
2043: if (mExits != null) {
2044: new_elementinfo.mExits = new LinkedHashMap<String, FlowLink>(
2045: mExits);
2046: }
2047:
2048: if (mDatalinks != null) {
2049: new_elementinfo.mDatalinks = new LinkedHashMap<ElementInfo, ArrayList<DataLink>>();
2050:
2051: ArrayList<DataLink> data_links = null;
2052: for (ElementInfo element_info : mDatalinks.keySet()) {
2053: data_links = mDatalinks.get(element_info);
2054: if (data_links != null) {
2055: data_links = new ArrayList<DataLink>(data_links);
2056: }
2057: new_elementinfo.mDatalinks
2058: .put(element_info, data_links);
2059: }
2060: }
2061:
2062: if (mInheritanceStack != null) {
2063: new_elementinfo.mInheritanceStack = new Stack<ElementInfo>();
2064: new_elementinfo.mInheritanceStack.addAll(mInheritanceStack);
2065: }
2066:
2067: if (mPrecedenceStack != null) {
2068: new_elementinfo.mPrecedenceStack = new Stack<ElementInfo>();
2069: new_elementinfo.mPrecedenceStack.addAll(mPrecedenceStack);
2070: }
2071:
2072: if (mGlobalExits != null) {
2073: new_elementinfo.mGlobalExits = new LinkedHashMap<String, GlobalExit>(
2074: mGlobalExits);
2075: }
2076:
2077: if (mGlobalVars != null) {
2078: new_elementinfo.mGlobalVars = new LinkedHashMap<String, GlobalVar>(
2079: mGlobalVars);
2080: }
2081:
2082: if (mGlobalCookies != null) {
2083: new_elementinfo.mGlobalCookies = new LinkedHashMap<String, String>(
2084: mGlobalCookies);
2085: }
2086:
2087: if (mNamedGlobalBeans != null) {
2088: new_elementinfo.mNamedGlobalBeans = new LinkedHashMap<String, BeanDeclaration>(
2089: mNamedGlobalBeans);
2090: }
2091:
2092: if (mDepartureVars != null) {
2093: new_elementinfo.mDepartureVars = new ArrayList<String>(
2094: mDepartureVars);
2095: }
2096:
2097: if (mPathInfoMappings != null) {
2098: new_elementinfo.mPathInfoMappings = new ArrayList<PathInfoMapping>(
2099: mPathInfoMappings);
2100: }
2101:
2102: return new_elementinfo;
2103: }
2104: }
|