001: /*
002: * JBoss, Home of Professional Open Source
003: * Copyright 2005, JBoss Inc., and individual contributors as indicated
004: * by the @authors tag. See the copyright.txt in the distribution for a
005: * full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jbpm.graph.def;
023:
024: import java.io.Serializable;
025: import java.util.Map;
026:
027: import org.dom4j.Element;
028: import org.jbpm.graph.exe.ExecutionContext;
029: import org.jbpm.instantiation.Delegation;
030: import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
031: import org.jbpm.jpdl.xml.JpdlXmlReader;
032: import org.jbpm.jpdl.xml.Parsable;
033: import org.jbpm.util.EqualsUtil;
034:
035: public class Action implements ActionHandler, Parsable, Serializable {
036:
037: private static final long serialVersionUID = 1L;
038:
039: long id = 0;
040: protected String name = null;
041: protected boolean isPropagationAllowed = true;
042: protected boolean isAsync = false;
043: protected boolean isAsyncExclusive = false;
044: protected Action referencedAction = null;
045: protected Delegation actionDelegation = null;
046: protected String actionExpression = null;
047: protected Event event = null;
048: protected ProcessDefinition processDefinition = null;
049:
050: public Action() {
051: }
052:
053: public Action(Delegation actionDelegate) {
054: this .actionDelegation = actionDelegate;
055: }
056:
057: public String toString() {
058: String toString = null;
059: if (name != null) {
060: toString = "action[" + name + "]";
061: } else if (actionExpression != null) {
062: toString = "action[" + actionExpression + "]";
063: } else {
064: String className = getClass().getName();
065: className = className
066: .substring(className.lastIndexOf('.') + 1);
067: if (name != null) {
068: toString = className + "(" + name + ")";
069: } else {
070: toString = className
071: + "("
072: + Integer.toHexString(System
073: .identityHashCode(this )) + ")";
074: }
075: }
076: return toString;
077: }
078:
079: public void read(Element actionElement, JpdlXmlReader jpdlReader) {
080: String expression = actionElement.attributeValue("expression");
081: if (expression != null) {
082: actionExpression = expression;
083:
084: } else if (actionElement.attribute("ref-name") != null) {
085: jpdlReader
086: .addUnresolvedActionReference(actionElement, this );
087:
088: } else if (actionElement.attribute("class") != null) {
089: actionDelegation = new Delegation();
090: actionDelegation.read(actionElement, jpdlReader);
091:
092: } else {
093: jpdlReader
094: .addWarning("action does not have class nor ref-name attribute "
095: + actionElement.asXML());
096: }
097:
098: String acceptPropagatedEvents = actionElement
099: .attributeValue("accept-propagated-events");
100: if ("false".equalsIgnoreCase(acceptPropagatedEvents)
101: || "no".equalsIgnoreCase(acceptPropagatedEvents)
102: || "off".equalsIgnoreCase(acceptPropagatedEvents)) {
103: isPropagationAllowed = false;
104: }
105:
106: String asyncText = actionElement.attributeValue("async");
107: if ("true".equalsIgnoreCase(asyncText)) {
108: isAsync = true;
109: } else if ("exclusive".equalsIgnoreCase(asyncText)) {
110: isAsync = true;
111: isAsyncExclusive = true;
112: }
113: }
114:
115: public void write(Element actionElement) {
116: if (actionDelegation != null) {
117: actionDelegation.write(actionElement);
118: }
119: }
120:
121: public void execute(ExecutionContext executionContext)
122: throws Exception {
123: if (referencedAction != null) {
124: referencedAction.execute(executionContext);
125:
126: } else if (actionExpression != null) {
127: JbpmExpressionEvaluator.evaluate(actionExpression,
128: executionContext);
129:
130: } else if (actionDelegation != null) {
131: ActionHandler actionHandler = (ActionHandler) actionDelegation
132: .getInstance();
133: actionHandler.execute(executionContext);
134: }
135: }
136:
137: public void setName(String name) {
138: // if the process definition is already set
139: if (processDefinition != null) {
140: // update the process definition action map
141: Map actionMap = processDefinition.getActions();
142: // the != string comparison is to avoid null pointer checks. it is no problem if the body is executed a few times too much :-)
143: if ((this .name != name) && (actionMap != null)) {
144: actionMap.remove(this .name);
145: actionMap.put(name, this );
146: }
147: }
148:
149: // then update the name
150: this .name = name;
151: }
152:
153: // equals ///////////////////////////////////////////////////////////////////
154: // hack to support comparing hibernate proxies against the real objects
155: // since this always falls back to ==, we don't need to overwrite the hashcode
156: public boolean equals(Object o) {
157: return EqualsUtil.equals(this , o);
158: }
159:
160: // getters and setters //////////////////////////////////////////////////////
161:
162: public boolean acceptsPropagatedEvents() {
163: return isPropagationAllowed;
164: }
165:
166: public boolean isPropagationAllowed() {
167: return isPropagationAllowed;
168: }
169:
170: public void setPropagationAllowed(boolean isPropagationAllowed) {
171: this .isPropagationAllowed = isPropagationAllowed;
172: }
173:
174: public long getId() {
175: return id;
176: }
177:
178: public String getName() {
179: return name;
180: }
181:
182: public Event getEvent() {
183: return event;
184: }
185:
186: public ProcessDefinition getProcessDefinition() {
187: return processDefinition;
188: }
189:
190: public void setProcessDefinition(ProcessDefinition processDefinition) {
191: this .processDefinition = processDefinition;
192: }
193:
194: public Delegation getActionDelegation() {
195: return actionDelegation;
196: }
197:
198: public void setActionDelegation(Delegation instantiatableDelegate) {
199: this .actionDelegation = instantiatableDelegate;
200: }
201:
202: public Action getReferencedAction() {
203: return referencedAction;
204: }
205:
206: public void setReferencedAction(Action referencedAction) {
207: this .referencedAction = referencedAction;
208: }
209:
210: public boolean isAsync() {
211: return isAsync;
212: }
213:
214: public boolean isAsyncExclusive() {
215: return isAsyncExclusive;
216: }
217:
218: public String getActionExpression() {
219: return actionExpression;
220: }
221:
222: public void setActionExpression(String actionExpression) {
223: this .actionExpression = actionExpression;
224: }
225:
226: public void setEvent(Event event) {
227: this .event = event;
228: }
229:
230: public void setAsync(boolean isAsync) {
231: this.isAsync = isAsync;
232: }
233: }
|