001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * $Id: ToolBasedImpl.java,v 1.5.2.1 2007/11/02 16:00:33 drmlipp Exp $
021: *
022: * $Log: ToolBasedImpl.java,v $
023: * Revision 1.5.2.1 2007/11/02 16:00:33 drmlipp
024: * Merged bug fixes from HEAD.
025: *
026: * Revision 1.6 2007/09/20 21:27:20 mlipp
027: * Removed superfluous import.
028: *
029: * Revision 1.5 2007/05/03 21:58:19 mlipp
030: * Internal refactoring for making better use of local EJBs.
031: *
032: * Revision 1.4 2007/03/27 21:59:43 mlipp
033: * Fixed lots of checkstyle warnings.
034: *
035: * Revision 1.3 2006/09/29 12:32:08 drmlipp
036: * Consistently using WfMOpen as projct name now.
037: *
038: * Revision 1.2 2005/08/25 13:24:22 drmlipp
039: * Synchronized with 1.3.1p6.
040: *
041: * Revision 1.1.1.2.6.1 2005/08/24 14:14:52 drmlipp
042: * Started implementation of exception mapping.
043: *
044: * Revision 1.1.1.2 2004/08/18 15:17:38 drmlipp
045: * Update to 1.2
046: *
047: * Revision 1.21 2004/05/07 15:02:27 lipp
048: * Removed legacy initialization code.
049: *
050: * Revision 1.20 2004/05/03 15:38:11 lipp
051: * Getting on with SAX based process creation.
052: *
053: * Revision 1.19 2004/04/30 13:46:19 lipp
054: * Getting on with SAX based initialization.
055: *
056: * Revision 1.18 2004/03/25 15:52:45 lipp
057: * Ensure backward compatibility of serialzed instances.
058: *
059: * Revision 1.17 2004/03/25 14:41:47 lipp
060: * Added possibility to specify actual parameters as XML.
061: *
062: * Revision 1.16 2003/06/27 08:51:45 lipp
063: * Fixed copyright/license information.
064: *
065: * Revision 1.15 2003/05/07 14:45:50 lipp
066: * Implemented synchronous subflow.
067: *
068: * Revision 1.14 2003/05/06 13:21:30 lipp
069: * Resolved cyclic dependency.
070: *
071: * Revision 1.13 2003/05/06 09:43:14 lipp
072: * Moved tool/sub-process invocation.
073: *
074: * Revision 1.12 2003/05/05 07:04:51 lipp
075: * Handling parameters for sub-flow now.
076: *
077: * Revision 1.11 2003/04/26 18:56:24 lipp
078: * Moved extended interfaces to own package.
079: *
080: * Revision 1.10 2003/04/26 16:11:14 lipp
081: * Moved some classes to reduce package dependencies.
082: *
083: * Revision 1.9 2003/04/25 14:50:59 lipp
084: * Fixed javadoc errors and warnings.
085: *
086: * Revision 1.8 2003/04/19 19:46:52 lipp
087: * Fixed parameter evaluation error.
088: *
089: * Revision 1.7 2003/04/16 21:06:38 lipp
090: * Improved placement of debug statement.
091: *
092: * Revision 1.6 2003/04/16 16:19:31 lipp
093: * Fixed null pointer bug
094: *
095: * Revision 1.5 2003/04/02 09:30:05 lipp
096: * Supporting more data types.
097: *
098: * Revision 1.4 2003/03/31 16:50:28 huaiyang
099: * Logging using common-logging.
100: *
101: * Revision 1.3 2003/03/28 12:44:08 lipp
102: * Moved XPDL related constants to XPDLUtil.
103: *
104: * Revision 1.2 2003/03/27 12:58:55 lipp
105: * Removed redundant check.
106: *
107: * Revision 1.1 2003/03/27 10:45:37 lipp
108: * Renamed activity implementation classes for clarity.
109: *
110: * Revision 1.10 2003/03/26 09:21:39 lipp
111: * Added support for evaluating actual IN parameters.
112: *
113: * Revision 1.9 2003/03/24 12:31:37 lipp
114: * Minor improvements.
115: *
116: * Revision 1.8 2002/12/19 21:37:43 lipp
117: * Reorganized interfaces.
118: *
119: * Revision 1.7 2002/11/26 11:23:30 lipp
120: * Modified RemoteException comment.
121: *
122: * Revision 1.6 2002/10/09 07:31:22 lipp
123: * Fixed logger category.
124: *
125: * Revision 1.5 2002/10/06 20:14:38 lipp
126: * Updated argument handling.
127: *
128: * Revision 1.4 2002/09/27 10:48:35 lipp
129: * Fixed bug in parameter mode access.
130: *
131: * Revision 1.3 2002/09/24 12:31:44 lipp
132: * Reestablished method.
133: *
134: * Revision 1.2 2002/09/24 12:25:19 lipp
135: * setResult implemented.
136: *
137: * Revision 1.1 2002/09/23 15:12:39 lipp
138: * Extended tool implementation definition and usage.
139: *
140: */
141: package de.danet.an.workflow.domain;
142:
143: import java.util.ArrayList;
144: import java.util.List;
145: import java.util.Map;
146:
147: import org.xml.sax.Attributes;
148: import org.xml.sax.SAXException;
149:
150: import de.danet.an.util.sax.StackedHandler;
151:
152: import de.danet.an.workflow.internalapi.ExtActivityLocal;
153: import de.danet.an.workflow.internalapi.ExtProcessLocal;
154: import de.danet.an.workflow.localapi.ActivityLocal;
155: import de.danet.an.workflow.localapi.ProcessLocal;
156: import de.danet.an.workflow.omgcore.InvalidDataException;
157:
158: import de.danet.an.workflow.api.FormalParameter;
159: import de.danet.an.workflow.api.InvalidIdException;
160: import de.danet.an.workflow.api.Activity.ToolImplementation;
161:
162: /**
163: * This class represents (an item of) a tool based activity
164: * implementation, i.e. it implements {@link
165: * de.danet.an.workflow.localapi.ActivityLocal.ToolImplementation
166: * <code>ToolImplementation</code>}.
167: *
168: * @author <a href="mailto:lipp@danet.de"></a>
169: * @version $Revision: 1.5.2.1 $
170: */
171: public final class ToolBasedImpl extends ActImplBase implements
172: ToolImplementation {
173:
174: /** Unique id. */
175: static final long serialVersionUID = -4198678919987230490L;
176:
177: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
178: .getLog(ToolBasedImpl.class);
179:
180: /** The tool id. */
181: private String id = null;
182:
183: /** The implementation description. */
184: private String description = null;
185:
186: /** The actual parmeters. */
187: private Object[] actualParams = null;
188:
189: /**
190: * Creates an instance of <code>ToolImplementation</code>
191: * with all attributes initialized to default values.
192: */
193: private ToolBasedImpl() {
194: }
195:
196: /**
197: * Return the tool id.
198: * @return value of id.
199: */
200: public String id() {
201: return id;
202: }
203:
204: /**
205: * Return the implementation description.
206: * @return value of description.
207: */
208: public String description() {
209: return description;
210: }
211:
212: /**
213: * Return the actual parameters.
214: * @return actualParameters.
215: */
216: public Object[] actualParameters() {
217: return actualParams;
218: }
219:
220: /**
221: * Triggers the execution of the current tool for the given activity.
222: * @param act the activity
223: */
224: public void invoke(ExtActivityLocal act) {
225: try {
226: ExtProcessLocal process = (ExtProcessLocal) act
227: .containerLocal();
228: ApplicationDefinition appl = (ApplicationDefinition) process
229: .processDefinition().applicationById(id());
230: Map params = parameterMap(process, act, appl);
231: act.invokeTool(appl, params);
232: return;
233: } catch (InvalidIdException e) {
234: // cannot happen since procdef is initially verified
235: logger.error(e.getMessage(), e);
236: throw new IllegalStateException(e.getMessage());
237: }
238: }
239:
240: /**
241: * Create the parameter map for a tool invocation based on the
242: * given activity, its container and application definition. This
243: * method is intended for callers that have retrieved the
244: * <code>ApplicationDefinition</code> and <code>Process</code>
245: * from the <code>Activity</code> anyway, so calling {@link
246: * #parameterMap(ActivityLocal) <code>ParameterMap(Activity)</code>}
247: * would be a duplication of efforts.
248: *
249: * @param process the process which the activity belongs to.
250: * @param act the activity to which this tool implementation description
251: * is to be applied.
252: * @param appl the application definition.
253: * @return the parameter map.
254: * @see #parameterMap(ActivityLocal)
255: */
256: private Map parameterMap(ExtProcessLocal process,
257: ActivityLocal act, ApplicationDefinition appl) {
258: if (!appl.id().equals(id())) {
259: throw new IllegalArgumentException("Application-id \""
260: + appl.id() + "\" does not match"
261: + " actual parameterlist tool reference \"" + id()
262: + "\"");
263: }
264: return super
265: .parameterMap(process, act, appl.formalParameters());
266: }
267:
268: /**
269: * Merge the result returned by an implementation into the process
270: * data. The names of the result data items must be formal parameter
271: * names which are mapped to process data items as defined by the
272: * actual parameters.
273: *
274: * @param act the activity related with the implementation invocation.
275: * @param result the result data.
276: * @throws InvalidDataException if the entries in the result do not
277: * match formal parameter names or excessive entries exist.
278: */
279: public void mergeResult(ActivityLocal act, Map result)
280: throws InvalidDataException {
281: try {
282: ProcessLocal process = (ProcessLocal) act.containerLocal();
283: ApplicationDefinition appl = (ApplicationDefinition) process
284: .processDefinition().applicationById(id());
285: FormalParameter[] fps = appl.formalParameters();
286: mergeResult(process, fps, result);
287: } catch (InvalidIdException e) {
288: // cannot happen since procdef is initially verified
289: logger.error(e.getMessage(), e);
290: throw new IllegalStateException(e.getMessage());
291: }
292: }
293:
294: /**
295: * Return a string representation of this object.
296: * @return the representation
297: */
298: public String toString() {
299: return "Tool[id=" + id() + "]";
300: }
301:
302: /**
303: * Helper class for retrieving the tool based implementation from
304: * the process definition.
305: */
306: public class SAXInitializer extends StackedHandler {
307:
308: private List apList = new ArrayList();
309:
310: /**
311: * Receive notification of the beginning of an element.
312: *
313: * @param uri the Namespace URI, or the empty string if the
314: * element has no Namespace URI or if Namespace processing is not
315: * being performed.
316: * @param loc the local name (without prefix), or the empty string
317: * if Namespace processing is not being performed.
318: * @param raw the raw XML 1.0 name (with prefix), or the empty
319: * string if raw names are not available.
320: * @param a the attributes attached to the element. If there are
321: * no attributes, it shall be an empty Attributes object.
322: * @throws SAXException not thrown.
323: */
324: public void startElement(String uri, String loc, String raw,
325: Attributes a) throws SAXException {
326: if (loc.equals("Tool")) {
327: setContextData("implementation", ToolBasedImpl.this );
328: id = a.getValue("Id");
329: }
330: }
331:
332: /**
333: * Receive notification of the end of an element.
334: *
335: * @param uri the Namespace URI, or the empty string if the
336: * element has no Namespace URI or if Namespace processing is not
337: * being performed.
338: * @param loc the local name (without prefix), or the empty string
339: * if Namespace processing is not being performed.
340: * @param raw the raw XML 1.0 name (with prefix), or the empty
341: * string if raw names are not available.
342: * @throws SAXException not thrown.
343: */
344: public void endElement(String uri, String loc, String raw)
345: throws SAXException {
346: if (loc.equals("Description")) {
347: description = text().trim();
348: } else if (loc.equals("ActualParameter")) {
349: apList.add(text().trim());
350: } else if (loc.equals("Tool")) {
351: actualParams = (String[]) apList
352: .toArray(new String[apList.size()]);
353: }
354: }
355: }
356:
357: /**
358: * Return a handler that can be used to initialize an object from
359: * SAX events. The instance created is returned in the
360: * HandlerStack's context data as "implementation".
361: * @return the handler.
362: */
363: public static StackedHandler saxConstructor() {
364: return (new ToolBasedImpl()).newSaxInitializer();
365: }
366:
367: private StackedHandler newSaxInitializer() {
368: return new SAXInitializer();
369: }
370: }
|