Package de.danet.an.workflow.domain

Source Code of de.danet.an.workflow.domain.ApplicationDefinition$SAXInitializer

/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* $Id: ApplicationDefinition.java 2942 2009-02-18 23:12:12Z mlipp $
*
* $Log$
* Revision 1.10  2007/02/27 14:34:12  drmlipp
* Some refactoring to reduce cyclic dependencies.
*
* Revision 1.9  2006/10/13 13:59:58  drmlipp
* Fixed NullPointerException.
*
* Revision 1.8  2006/10/13 11:39:46  drmlipp
* Added new attribute suspendActivity to exception mapping
* and ExceptionResultProvider.
*
* Revision 1.7  2006/09/29 12:32:08  drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.6  2006/03/08 14:46:43  drmlipp
* Synchronized with 1.3.3p5.
*
* Revision 1.5  2005/09/05 09:41:48  drmlipp
* Synchronized with 1.3.2.
*
* Revision 1.4  2005/08/25 13:24:22  drmlipp
* Synchronized with 1.3.1p6.
*
* Revision 1.3  2005/04/22 15:11:01  drmlipp
* Merged changes from 1.3 branch up to 1.3p15.
*
* Revision 1.1.1.4.6.2  2005/04/11 14:29:51  drmlipp
* Fixed race-condition.
*
* Revision 1.2  2005/02/04 14:25:26  drmlipp
* Synchronized with 1.3rc2.
*
* Revision 1.1.1.4.6.1  2005/02/03 13:02:45  drmlipp
* Moved warning about indexed formal parameters to process definition
* import.
*
* Revision 1.1.1.4  2004/08/18 15:17:38  drmlipp
* Update to 1.2
*
* Revision 1.74  2004/07/02 09:03:34  lipp
* Removed unused import.
*
* Revision 1.73  2004/06/28 10:58:26  lipp
* Clarified SAX buffer type usage.
*
* Revision 1.72  2004/04/13 14:31:41  lipp
* Added DirectInvocable support as XPDL extension.
*
* Revision 1.71  2004/04/12 19:33:52  lipp
* Clarified application invocation interface.
*
* Revision 1.70  2004/04/01 09:32:07  lipp
* Improved tool agent context implementtaion.
*
* Revision 1.69  2004/03/31 19:36:20  lipp
* Completed implementation of Activity.abandon(String).
*
* Revision 1.67  2004/03/29 11:45:24  lipp
* Made engine context available to tool agents.
*
* Revision 1.66  2004/02/19 13:10:32  lipp
* Clarified start-/endDocument usage in SAXEventBuffers.
*
* Revision 1.65  2003/12/08 14:08:13  lipp
* Execute tool termination in own transaction.
*
* Revision 1.64  2003/11/26 16:14:14  lipp
* Added possibility to declare tool as ResultProvider.
*
* Revision 1.63  2003/10/05 15:34:33  lipp
* Added tool provided execution mode.
*
* Revision 1.62  2003/07/11 14:06:33  montag
* if value is instance of SAXEventBufferImpl,
* first try to call the setter with type SAXEventBuffer.
*
* Revision 1.61  2003/07/10 14:41:33  montag
* Allow the parameter type of the setter to be of type
* SAXEventBuffer.
*
* Revision 1.60  2003/06/27 08:51:45  lipp
* Fixed copyright/license information.
*
* Revision 1.59  2003/06/18 15:44:53  lipp
* Support setting of XML argument type by tool.
*
* Revision 1.58  2003/06/17 15:47:26  lipp
* Prepared XML argument type control be tool implementation.
*
* Revision 1.57  2003/06/10 14:44:20  huaiyang
* use SAXEvent to generate DocumentFragment.
*
* Revision 1.56  2003/06/03 16:38:56  lipp
* Updated to jdom b9.
*
* Revision 1.55  2003/05/15 07:46:42  lipp
* Proper handling of JavaScript default double result.
*
* Revision 1.54  2003/05/06 13:21:30  lipp
* Resolved cyclic dependency.
*
* Revision 1.53  2003/05/02 08:21:54  lipp
* Some fixes handling tool properties specified by subtrees.
*
* Revision 1.52  2003/04/24 19:47:50  lipp
* Removed dependency between general util and workflow api.
*
* Revision 1.51  2003/04/24 19:25:26  lipp
* Storing XML properties as buffered SAX events.
*
* Revision 1.50  2003/04/24 15:08:14  lipp
* Reading ApplicationDefinitiosn from SAX now.
*
* Revision 1.49  2003/04/03 11:44:06  lipp
* Support for W3C DOM arguments.
*
* Revision 1.48  2003/03/31 16:50:28  huaiyang
* Logging using common-logging.
*
* Revision 1.47  2003/03/28 12:44:08  lipp
* Moved XPDL related constants to XPDLUtil.
*
* Revision 1.46  2003/03/28 11:58:18  huaiyang
* refactory the code in invoking method.
*
* Revision 1.45  2003/03/27 16:43:26  huaiyang
* support JDOM and DOM as param for set method.
*
* Revision 1.44  2003/03/27 13:51:37  huaiyang
* use JDOMSerializationWrapper to wrap JDOM element.
*
* Revision 1.43  2003/02/12 11:57:30  lipp
* Improved deadlock (RemoteException) handling for tools. Imroved debug
* information.
*
* Revision 1.42  2002/12/19 21:37:43  lipp
* Reorganized interfaces.
*
* Revision 1.41  2002/11/26 15:06:15  lipp
* Improved exception handling.
*
* Revision 1.40  2002/11/05 12:24:53  lipp
* Simplified access to agent.
*
* Revision 1.39  2002/10/25 14:29:41  lipp
* Detach interesting part of DOM tree from rest.
*
* Revision 1.38  2002/10/25 09:20:23  lipp
* Allow applications definition without tool agent.
*
* Revision 1.37  2002/10/24 14:25:11  lipp
* Added form attribute to submitter.
*
* Revision 1.36  2002/10/06 20:14:38  lipp
* Updated argument handling.
*
* Revision 1.35  2002/10/02 10:58:13  lipp
* Modifications for tool invocation.
*
* Revision 1.34  2002/09/27 15:20:53  lipp
* Get properties verbatim.
*
* Revision 1.33  2002/09/27 11:26:44  huaiyang
* Use FormalParameter.mode.fromString to construct mode object.
*
* Revision 1.32  2002/09/26 20:03:36  lipp
* Reorganized tool invocation.
*
* Revision 1.31  2002/09/26 15:07:37  lipp
* Minor fixes.
*
* Revision 1.30  2002/09/24 15:53:37  lipp
* Better error handling.
*
* Revision 1.29  2002/09/24 07:41:30  lipp
* Improved error message.
*
* Revision 1.28  2002/09/23 20:31:28  lipp
* Implemented async/sync invocation.
*
* Revision 1.27  2002/09/23 10:23:26  lipp
* Lazy instantiation of agent.
*
* Revision 1.26  2002/09/23 09:33:03  huaiyang
* Add formal parameter in application def.
*
* Revision 1.25  2002/09/19 20:09:26  lipp
* Removed methods from Application interface and reorganized
* asynchronous tool invocation.
*
* Revision 1.24  2002/09/19 11:21:06  huaiyang
* New style in defining extended attribute of application.
*
* Revision 1.23  2002/09/18 09:53:34  lipp
* Moved access to application data to process definition.
*
* Revision 1.22  2002/09/17 15:24:24  lipp
* Renamed Tool to Application and copied some functionality to
* ProcessDefintion.
*
* Revision 1.21  2002/09/17 13:53:14  huaiyang
* Invoke method using params from xpdl.
*
* Revision 1.20  2002/09/17 09:20:12  lipp
* Added ApplicationNotStoppedException.
*
* Revision 1.19  2002/09/15 15:13:00  lipp
* Moved code for asynchronous application invocation.
*
* Revision 1.18  2002/09/11 14:17:22  lipp
* Execptions using msgs now.
*
* Revision 1.17  2002/09/11 06:33:32  huaiyang
* Remove the variable of prefix.
*
* Revision 1.16  2002/09/09 13:11:46  huaiyang
* Cleanup the unnecessary code for old style process definition.
*
* Revision 1.15  2002/09/04 08:58:58  huaiyang
* Add exception handling in invoke method.
*
* Revision 1.14  2002/09/03 15:16:29  huaiyang
* Move the call of application class in the constructor.
*
* Revision 1.13  2002/09/03 14:51:54  huaiyang
* Remove unneeded code for old style of process definition spec.
*
* Revision 1.12  2002/08/30 07:58:19  huaiyang
* Separation of Domain class and persistent class more cleaner.
*
* Revision 1.11  2002/08/26 20:23:13  lipp
* Lots of method renames.
*
* Revision 1.10  2002/08/26 14:17:07  lipp
* JavaDoc fixes.
*
* Revision 1.9  2002/08/20 13:46:13  lipp
* Using xpath now to extract additional process information from xpdl.
*
* Revision 1.8  2002/07/24 08:04:42  huaiyang
* doccheck.
*
* Revision 1.7  2002/05/21 13:27:37  huaiyang
* New method of terminate.
*
* Revision 1.6  2002/05/17 12:52:34  lipp
* Cleaned up interface to tools.
*
* Revision 1.5  2002/05/17 08:34:21  lipp
* Renamed aii/Application to aii/ToolAgent.
*
* Revision 1.4  2002/05/16 19:47:48  lipp
* Proper usage of constructingSAXHandler.
*
* Revision 1.3  2002/02/06 18:27:44  huaiyang
* Add the check of application class name.
*
* Revision 1.2  2002/02/04 16:08:15  huaiyang
* Modified the method of runApplication.
*
* Revision 1.1  2002/01/31 15:45:08  huaiyang
* Initial version of the application definition.
*
*
*/
package de.danet.an.workflow.domain;

import java.io.Serializable;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;

import org.jdom.Element;
import org.jdom.input.SAXHandler;
import org.jdom.output.DOMOutputter;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import de.danet.an.util.sax.BodyFilter;
import de.danet.an.util.sax.StackedHandler;

import de.danet.an.workflow.util.SAXEventBufferImpl;
import de.danet.an.workflow.util.XPDLUtil;

import de.danet.an.workflow.api.Activity;
import de.danet.an.workflow.api.FormalParameter;
import de.danet.an.workflow.api.SAXEventBuffer;

import de.danet.an.workflow.internalapi.ExtApplication;
import de.danet.an.workflow.internalapi.ToolInvocationException;
import de.danet.an.workflow.localapi.ActivityLocal;
import de.danet.an.workflow.spis.aii.ApplicationNotStoppedException;
import de.danet.an.workflow.spis.aii.CannotExecuteException;
import de.danet.an.workflow.spis.aii.ContextRequester;
import de.danet.an.workflow.spis.aii.ExceptionMappingProvider;
import de.danet.an.workflow.spis.aii.ResultProvider;
import de.danet.an.workflow.spis.aii.ExceptionMappingProvider.ExceptionMapping;
import de.danet.an.workflow.spis.aii.ResultProvider.ExceptionResult;
import de.danet.an.workflow.spis.aii.ToolAgent;
import de.danet.an.workflow.spis.aii.ToolAgentContext;
import de.danet.an.workflow.spis.aii.XMLArgumentTypeProvider;
import de.danet.an.workflow.tools.util.DirectInvocable;

/**
* This class defines the application. Setting the log level to debug
* will generate additional messages about the tool invocation. 
*/
public class ApplicationDefinition implements ExtApplication, Serializable {

    /**
     * logger of this class.
     */
    static final org.apache.commons.logging.Log logger
  = org.apache.commons.logging.LogFactory
  .getLog(ApplicationDefinition.class);

    private static final String XMLNS = "http://www.w3.org/2000/xmlns/";

    /** Id of the application. */
    private String id;
 
    /** Description of the application. */
    private String description = null;

    /** Agent implementing class. */
    private String agentClassName = null;

    /** Handler */
    private String invocationHandler = null;
   
    /** Direct invocable? */
    private boolean directInvocableAttr = false;

    /** Convert parameters? */
    private int xmlParameterMode = XMLArgumentTypeProvider.XML_AS_W3C_DOM;

    /** Exception mappings? */
    private List exceptionMappings = null;
   
    /** Agent configuration. */
    private Map agentProps = new HashMap();
 
    /** Formal parameters of this application. */
    private FormalParameter[] formalParameters = new FormalParameter[] {};

    /** Tool agent for this application. Tool agents are not serializable. */
    private transient ToolAgent agentCache = null;

    /**
     * Creates a new <code>ApplicationDefinition</code>.
     */
    public ApplicationDefinition () {
    }

    /**
     * Construct agent instance.
     * @return agent instance
     */
    private ToolAgent agent() {
  if (agentCache != null) {
      return agentCache;
  }
  Class appClass = null;
  try {
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      appClass = cl.loadClass(agentClassName);
        } catch (ClassNotFoundException e) {
            if (invocationHandler == null) {
                logger.error (e.getMessage(), e);
                throw new IllegalStateException
                    ("Cannot find application class " + agentClassName
                     + " from ApplicationDefinition with Id = " + id + ".");
            }
            agentCache = new ToolAgent () {
                public void invoke
                    (Activity activity,
                     FormalParameter[] formalParameters, Map actualParameters)
                    throws RemoteException, CannotExecuteException {
                    throw new IllegalStateException
                    ("Application class " + agentClassName
                     + " from ApplicationDefinition with Id = " + id
                     + " is not locally available.");
                }

                public void terminate(Activity activity)
                        throws ApplicationNotStoppedException, RemoteException {
                    throw new ApplicationNotStoppedException
                        ("Cannot stop tool agent in other deployment unit.");
                }
            };
            return agentCache;
        }
        try {
      // initialize agent before putting it in cache as we do
      // not synchronize here (and creating the agent twice
      // doesn't really hurt)
      ToolAgent agent = (ToolAgent)appClass.newInstance();
      // set properties
      for (Iterator itr = agentProps.keySet().iterator();
     itr.hasNext();) {
    String param = (String)itr.next();
    Object value = agentProps.get(param);
    Method method = null;
    Object[] args = new Object[] { value };
    if (value instanceof SAXEventBufferImpl) {
        // check for setter with type SAXEventBuffer
        try {
      Class[] argTypes = { SAXEventBuffer.class };
      method = appClass.getMethod ("set" + param, argTypes);
        } catch (NoSuchMethodException e) {
      // method is null
        }
    }
    if (method == null) {
        try {
      Class[] argTypes = { value.getClass() };
      method = appClass.getMethod ("set" + param, argTypes);
        } catch (NoSuchMethodException e) {
      if (!(value instanceof SAXEventBufferImpl)) {
          throw e;
      }
      // if value is XML, try converting to JDOM
      try {
          Class[] argTypes = { Element.class };
          method = appClass.getMethod
        ("set" + param, argTypes);
          SAXHandler sh = new SAXHandler ();
          ((SAXEventBufferImpl)value).emit(sh, sh);
          args[0] = sh.getDocument().getRootElement();
      } catch (NoSuchMethodException eee) {
          // finally try converting to W3C DOM
          Class[] argTypes
        = { org.w3c.dom.Element.class };
          method = appClass.getMethod
        ("set" + param, argTypes);
          TransformerHandler th = newTransformerHandler ();
          DOMResult out = new DOMResult ();
          th.setResult (out);
          ((SAXEventBufferImpl)value).emit(th, th);
          args[0] = out.getNode();
          if (args[0] instanceof org.w3c.dom.Document) {
        args[0] = ((org.w3c.dom.Document)args[0])
            .getDocumentElement();
          }
      }
        }
    }
    method.invoke(agent, args);
      }
      // agent may override XML parameter type setting
      if (agent instanceof XMLArgumentTypeProvider) {
    xmlParameterMode = ((XMLArgumentTypeProvider)agent)
        .requestedXMLArgumentType ();
      }
      // update exception mappings
      if (agent instanceof ExceptionMappingProvider) {
          if (exceptionMappings == null) {
              exceptionMappings = new ArrayList ();
          }
          // appending the mapping from the tool ensures that they
          // have lower precedence
          exceptionMappings.addAll
              (((ExceptionMappingProvider)agent).exceptionMappings());
      }     
      // save created agent
      agentCache = agent;
  } catch (IllegalAccessException ia) {
      logger.error (ia.getMessage(), ia);
      throw new IllegalStateException
    ("Cannot access application class " + agentClassName
     + " from ApplicationDefinition with Id = " + id + ".");
  } catch (InstantiationException ie) {
      logger.error (ie.getMessage(), ie);
      throw new IllegalStateException
    ("Cannot instantiate application class " + agentClassName
     + " from ApplicationDefinition with Id = " + id + ".");
  } catch (NoSuchMethodException nsme) {
      logger.error (nsme.getMessage(), nsme);
      throw new IllegalStateException (nsme.getMessage());
  } catch (InvocationTargetException ite) {
      logger.error (ite.getMessage(), ite);
      throw new IllegalArgumentException (ite.getMessage());
  } catch (TransformerConfigurationException je) {
      logger.error (je.getMessage(), je);
      throw new IllegalArgumentException (je.getMessage());
  } catch (SAXException je) {
      logger.error (je.getMessage(), je);
      throw new IllegalArgumentException (je.getMessage());
  }
  return agentCache;
    }

    /**
     * Return an array of the object of <code>FormalParameter</code>.
     *
     * @return an array of <code>FormalParameter</code> defined in this
     * application. If no formal parameter is defined in this application, it
     * returns an empty array.
     */
    public FormalParameter[] formalParameters() {
  return formalParameters;
    }
    /**
     * Return id of this application definition.
     * @return id of this application definition.
     */
    public String id() {
  return id;
    }
   
    /**
     * Return description of this application definition.
     * @return description of this application definition.
     */
    public String description() {
  return description;
    }

    /**
     * Invokes the application for the specific activity.
     *
     * @param activity the activity to be executed
     * @param params the invocation parameters
     * @param agentContext the context to pass to the tool agent
     * @return the invocation result if the tool agent provides one
     * (i.e. implements <code>ResultProvider</code>), else <code>null</code>
     * @throws ToolInvocationException if execution is not possible
     * @throws RemoteException if a temporary problem occurs and we
     * should retry the tool invocation. (Usually thrown when a
     * deadlock situation occurs while accessing the activity.)
     */
    public InvocationResult invoke
            (ToolAgentContext agentContext,
             de.danet.an.workflow.api.Activity activity, Map params)
  throws ToolInvocationException, RemoteException {
  ToolAgent agent = agent();
  if (agent == null) {
      return null;
  }
  // maybe convert DOM trees
  if (xmlParameterMode == XMLArgumentTypeProvider.XML_AS_W3C_DOM) {
      DOMOutputter domOutputter = new DOMOutputter();
      for (Iterator i = params.keySet().iterator(); i.hasNext();) {
    String pn = (String)i.next();
    Object v = params.get (pn);
    if (v instanceof SAXEventBuffer) {
        try {
      DOMResult domResult = new DOMResult();
      TransformerHandler th = newTransformerHandler();
      th.setResult(domResult);
      convertWithTempRoot(th, (SAXEventBuffer)v);
      org.w3c.dom.Document w3cDoc
          = (org.w3c.dom.Document)domResult.getNode();
      org.w3c.dom.DocumentFragment frag
          = w3cDoc.createDocumentFragment();
      org.w3c.dom.Element w3cTempRoot
          = w3cDoc.getDocumentElement();
      while (true) {
          org.w3c.dom.Node n = w3cTempRoot.getFirstChild();
          if (n == null) {
        break;
          }
          frag.appendChild(n);
      }
      params.put (pn, frag);
        } catch (SAXException e) {
      String m = "Cannot convert JDOM to W3C DOM: "
          + e.getMessage ();
      logger.error (m, e);
      throw new ToolInvocationException (m);
        } catch (TransformerConfigurationException e) {
      String m = "Cannot convert JDOM to W3C DOM: "
          + e.getMessage ();
      logger.error (m, e);
      throw new ToolInvocationException (m);
        }
    }
      }
  } else if (xmlParameterMode == XMLArgumentTypeProvider.XML_AS_JDOM) {
      for (Iterator i = params.keySet().iterator(); i.hasNext();) {
    String pn = (String)i.next();
    Object v = params.get (pn);
    if (v instanceof SAXEventBuffer) {
        try {
      SAXHandler sh = new SAXHandler ();
      convertWithTempRoot(sh, (SAXEventBuffer)v);
      Element temporaryRoot
          = sh.getDocument().getRootElement();
      params.put (pn, temporaryRoot.getChildren());
        } catch (SAXException e) {
      logger.error (e.getMessage(), e);
      throw new ToolInvocationException (e.getMessage());
        }
    }
      }
  }
  // invoke
  if (agent instanceof ContextRequester) {
      ((ContextRequester)agent).setToolAgentContext (agentContext);
  }
  if (logger.isDebugEnabled()) {
      logger.debug ("Invoking " + this.toString()
                    + " with " + formalParameters
                    + " and " + params);
  }
  try {
      agent.invoke(activity, formalParameters, params);
  } catch (CannotExecuteException e) {
      if (logger.isDebugEnabled()) {
          logger.debug ("Invocation resulted in: " + e.toString());
      }
      // try to find mapping
      if (e.getCause() != null && exceptionMappings != null) {
          for (Iterator i = exceptionMappings.iterator(); i.hasNext();) {
              ExceptionMapping m = (ExceptionMapping)i.next ();
              if (m.getJavaException().isInstance(e.getCause())) {
                  if (m.getProcessException() == null) {
                      break;
                  }
                  ResultProvider.ExceptionResult eres
                      = new ResultProvider.ExceptionResult
                            (m.getProcessException(), m.getSuspendActivity());
                        if (logger.isDebugEnabled()) {
                            logger.debug
                                ("Exception mapped to: " + eres.toString());
                        }
                  return new InvocationResult (eres);
              }
          }
      }
      throw new ToolInvocationException
        ("Cannot invoke tool, tool reports: " + e.getMessage(), e);
  }
  // maybe get result
  if (agent instanceof ResultProvider) {
      Object res = ((ResultProvider)agent).result ();
      if (res != null
    && !(res instanceof Map)
    && !(res instanceof ExceptionResult)) {
    throw new ToolInvocationException
        (toString() + " returns result that is neither"
         + " Map nor ExceptionResult");
      }
      if (logger.isDebugEnabled()) {
          logger.debug("Invocation result is: " + res);
      }
      return new InvocationResult (res);
  }
  return null;
    }

    // emits the SAX events in the given SAXContentBuffer in the content
    // handler.
    private void convertWithTempRoot (ContentHandler ch, SAXEventBuffer cb)
  throws SAXException {
  ch.startDocument();
  ch.startElement
      ("", "temporary-root", "temporary-root", new AttributesImpl());
  cb.emit(new BodyFilter (ch));
  ch.endElement ("", "temporary-root", "temporary-root");
  ch.endDocument();
    }

    /**
     * Terminates the application for the specific activity.
     *
     * @param activity the activity to be terminated
     * @throws ApplicationNotStoppedException if the application can not be
     * terminated.
     * @throws RemoteException if a temporary problem occurs and we
     * should retry the tool invocation (usually thrown when a
     * deadlock situation occurs while accessing the activity)
     */
    public void terminate (de.danet.an.workflow.api.Activity activity)
  throws ApplicationNotStoppedException, RemoteException {
  agent().terminate(activity);
    }

    /* Comment copied from interface. */
    public boolean isDirectInvocable () {
  return (agent() instanceof DirectInvocable) || directInvocableAttr;
    }

    /* (non-Javadoc)
     * Comment copied from interface or superclass.
     */
    public String handler() {
        return invocationHandler;
    }

    /**
     * Update the invocation handler.
     *
     * @param handler the new handler
     */
    public void updateHandler (String handler) {
        invocationHandler = handler;
    }
   
    /**
     * @return Returns the agentClassName.
     */
    public String agentClassName() {
        return agentClassName;
    }

    /**
     * Update the agent's class.
     *
     * @param className the new class name
     */
    public void updateAgentClassName (String className) {
        agentClassName = className;
    }
   
    /**
     * Provide a representation for debugging purposes.
     * @return descriptive string.
     */
    public String toString() {
  return "Application[Id=" + id + "]";
    }

    /**
     * Helper class for retrieving the applications from the process
     * definition.
     */
    public class SAXInitializer extends StackedHandler {

  private List fpList = null;
  private String fpId = null;
  private FormalParameter.Mode fpMode = null;
  private int fpIndex = 0;

  private String propName = null;
  private SAXEventBufferImpl propBuffer = null;

  /**
   * Receive notification of the beginning of an element.
   *
   * @param uri the Namespace URI, or the empty string if the
   * element has no Namespace URI or if Namespace processing is not
   * being performed.
   * @param loc the local name (without prefix), or the empty string
   * if Namespace processing is not being performed.
   * @param raw the raw XML 1.0 name (with prefix), or the empty
   * string if raw names are not available.
   * @param a the attributes attached to the element. If there are
   * no attributes, it shall be an empty Attributes object.
   * @throws SAXException not thrown.
   */
  public void startElement
      (String uri, String loc, String raw, Attributes a)
      throws SAXException {
      if (propName != null) {
    propBuffer = new SAXEventBufferImpl ();
    propBuffer.startDocument ();
    getStack().startAllPrefixMappings (propBuffer);
    getStack().push (propBuffer);
      } else if (loc.equals ("Application")) {
    id = a.getValue("Id");
      } else if (loc.equals ("FormalParameters")) {
    fpList = new ArrayList ();
      } else if (loc.equals ("FormalParameter")) {
    fpId = a.getValue("Id");
    fpMode = FormalParameter.Mode.fromString(a.getValue("Mode"));
      } else if (loc.equals ("DataType")) {
    getStack().push (new XPDLUtil.SAXDataTypeHandler());
      } else if (XPDLUtil.isXpdlExtNs(uri)
           && loc.equals ("ToolAgent")) {
    agentClassName = a.getValue("Class");
    if (agentClassName == null || agentClassName.length() == 0) {
        throw new SAXException
      ("Tool agent class must be specified in "
       + "ApplicationDefinition with Id = " + id + ".");
    }
    invocationHandler = a.getValue("Handler");
    String paramMode = a.getValue("XMLParameterMode");
    if (paramMode != null) {
        if (paramMode.equals ("USE_JDOM")) {
      xmlParameterMode = XMLArgumentTypeProvider.XML_AS_JDOM;
        } else if (paramMode.equals ("USE_SAX")) {
      xmlParameterMode = XMLArgumentTypeProvider.XML_AS_SAX;
        }
    }
    String directInvoc = a.getValue("DirectInvocable");
    directInvocableAttr = (directInvoc != null
               && (directInvoc.equals ("true")
             || directInvoc.equals("1")));
      } else if (uri.equals (XPDLUtil.XPDL_EXTN_NS)
           && loc.equals ("ExceptionMappings")) {
    exceptionMappings = new ArrayList ();
      } else if (XPDLUtil.isXpdlExtNs(uri)
           && loc.equals ("ExceptionMapping")) {
          try {
              Class t = Thread.currentThread().getContextClassLoader()
                .loadClass(a.getValue("JavaException"));
                    String suspAttr = a.getValue("SuspendActivity");
                    boolean suspAct = (suspAttr != null)
                        && (suspAttr.equals("true") || suspAttr.equals("1"));
              ExceptionMapping em = new ExceptionMapping
          (t, a.getValue("ProcessException"), suspAct);
              exceptionMappings.add (em);
          } catch (ClassNotFoundException e) {
              throw new SAXException (e);
          }
            } else if (XPDLUtil.isXpdlExtNs(uri)
                       && loc.equals ("Property")) {
                propName = a.getValue ("Name");
      }
  }

  /**
   * Receive notification of the end of an element.
   *
   * @param uri the Namespace URI, or the empty string if the
   * element has no Namespace URI or if Namespace processing is not
   * being performed.
   * @param loc the local name (without prefix), or the empty string
   * if Namespace processing is not being performed.
   * @param raw the raw XML 1.0 name (with prefix), or the empty
   * string if raw names are not available.
   * @throws SAXException not thrown.
   */
  public void endElement(String uri, String loc, String raw)
      throws SAXException {
      if (loc.equals ("Description")) {
    description = text();
      } else if (loc.equals ("FormalParameter")) {
    Object dtc = removeContextData ("DataType");
    String index = (new Integer(fpIndex++)).toString();
    fpList.add (new FormalParameter(fpId, index, fpMode, dtc));
      } else if (loc.equals ("FormalParameters")) {
    formalParameters = (FormalParameter[])fpList
        .toArray(new FormalParameter[fpList.size()]);
    fpList = null;
      } else if (XPDLUtil.isXpdlExtNs(uri)
           && loc.equals ("Property")) {
    if (propBuffer != null) {
        getStack().endAllPrefixMappings (propBuffer);
        propBuffer.endDocument ();
        propBuffer.pack ();
        agentProps.put (propName, propBuffer);
    } else {
        agentProps.put (propName, text());
    }
    propName = null;
    propBuffer = null;
      }
  }
    }

    /**
     * Return a handler that can be used to initialize an object
     * from SAX events.
     * @return the handler.
     */
    public StackedHandler saxInitializer () {
  return new SAXInitializer ();
    }

    private TransformerHandler newTransformerHandler()
  throws TransformerConfigurationException {
  TransformerFactory tf = TransformerFactory.newInstance();
  if (!tf.getFeature(SAXTransformerFactory.FEATURE)) {
      String s = "JAXP transformer factory does not"
    + " support a SAX transformer!";
      logger.fatal (s);
      throw new IllegalStateException (s);
  }
  TransformerHandler th = ((SAXTransformerFactory)tf)
      .newTransformerHandler ();
  return th;
    }

}
TOP

Related Classes of de.danet.an.workflow.domain.ApplicationDefinition$SAXInitializer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.