Package de.danet.an.workflow.tools.timing

Source Code of de.danet.an.workflow.tools.timing.TimerHandlerEJB

/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2004 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: TimerHandlerEJB.java 2413 2007-06-10 05:55:30Z drmlipp $
*
* $Log$
* Revision 1.13  2006/12/18 13:07:31  drmlipp
* Fixed typo.
*
* Revision 1.12  2006/12/18 12:45:55  drmlipp
* Handle exception to avoid loop.
*
* Revision 1.10  2006/10/11 09:43:11  drmlipp
* Removed not used non-local name.
*
* Revision 1.9  2006/10/11 09:05:54  drmlipp
* Fixed EJB naming.
*
* Revision 1.8  2006/10/10 15:37:17  drmlipp
* Made TimerHandlerEJB local.
*
* Revision 1.7  2006/10/07 21:35:30  mlipp
* Continuing migration to J2EE 1.4.
*
* Revision 1.6  2006/10/07 20:41:34  mlipp
* Merged J2EE 1.4 adaptions from test branch.
*
* Revision 1.5  2006/09/29 12:32:10  drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.4  2005/04/08 11:28:05  drmlipp
* Merged changes from 1.3 branch up to 1.3p6.
*
* Revision 1.3.4.1  2005/04/04 20:09:21  drmlipp
* Changed WLS transaction isolation.
*
* Revision 1.3  2004/10/20 20:40:32  drmlipp
* Made simple WaitTool terminatable.
*
* Revision 1.2  2004/09/10 12:44:30  drmlipp
* Enabled call by reference for weblogic by default.
*
* Revision 1.1.1.1  2004/08/18 15:17:39  drmlipp
* Update to 1.2
*
* Revision 1.4  2004/02/27 12:01:48  lipp
* Fixed permissions.
*
* Revision 1.3  2004/02/23 13:59:31  lipp
* Added simple waittool invocation.
*
* Revision 1.2  2004/02/21 21:31:01  lipp
* Some more refactoring to resolve cyclic dependencies.
*
* Revision 1.1  2004/02/20 18:56:35  lipp
* Renamed package waittool to timing (much better ;-)).
*
* Revision 1.3  2004/02/20 15:58:22  lipp
* Several WaitTool fixes.
*
* Revision 1.2  2004/02/19 21:14:48  lipp
* Several WaitTool fixes.
*
* Revision 1.1  2004/02/19 17:55:55  lipp
* Initial version of waittool.
*
*/
package de.danet.an.workflow.tools.timing;

import java.util.Date;

import java.rmi.RemoteException;

import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.FinderException;
import javax.ejb.NoSuchObjectLocalException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.ejb.TimedObject;
import javax.ejb.Timer;
import javax.ejb.TimerHandle;

import de.danet.an.util.EJBUtil;
import de.danet.an.util.ResourceNotAvailableException;

import de.danet.an.workflow.localapi.ActivityLocal;
import de.danet.an.workflow.omgcore.CannotCompleteException;
import de.danet.an.workflow.omgcore.CannotStopException;
import de.danet.an.workflow.omgcore.InvalidDataException;
import de.danet.an.workflow.omgcore.NotRunningException;
import de.danet.an.workflow.omgcore.ProcessData;
import de.danet.an.workflow.omgcore.WfExecutionObject.State;

import de.danet.an.workflow.api.ActivityUniqueKey;
import de.danet.an.workflow.api.DefaultProcessData;
import de.danet.an.workflow.api.InvalidKeyException;

import de.danet.an.workflow.ejbs.core.WfActivityLocalHome;
import de.danet.an.workflow.tools.util.SimpleApplicationDirectoryLocal;
import de.danet.an.workflow.tools.util.SimpleApplicationDirectoryLocalHome;
import de.danet.an.workflow.tools.util.SimpleApplicationInfo;

/**
* This EJB provides a directory for simple applications. Applications
* are considered simple in this context if their associated
* persistent state information can efficiently be represented (and
* stored) using a single serializable object.<P>
*
* This directory maps a unique id to the activity unique key
* information of the executing activity and an associated state (and
* vice versa). Optionally, the assignment time and the assigned
* resource may be saved in this directory as well.
*
* @author <a href="mailto:lipp@danet.de">Michael Lipp</a>
* @version $Revision: 2413 $
* @ejb.bean name="TimerHandler" display-name="Timer Handler"
* local-jndi-name="ejb/@@@_JNDI_Name_Prefix_@@@TimerHandlerLocal"
* type="Stateless" transaction-type="Container" view-type="local"
* @ejb.transaction type="Required"
* @ejb.permission role-name="WfMOpenAdmin"
* @ejb.security-identity run-as="WfMOpenAdmin"
* sunone-principal="WfMOpenPrincipalForAdmin"
* @weblogic.run-as-identity-principal WfMOpenPrincipalForAdmin
* @ejb.ejb-ref ejb-name="SimpleApplicationDirectory" view-type="local"
* @ejb.ejb-ref ejb-name="ActivityBean" view-type="local"
* @ejb.ejb-external-ref ref-name="ejb/JdbcKeyGenLocal" link="KeyGen"
* type="Session" view-type="local" home="de.danet.an.util.KeyGenLocalHome"
* business="de.danet.an.util.KeyGenLocal"
* @weblogic.enable-call-by-reference True
*/

public class TimerHandlerEJB implements SessionBean, TimedObject {
   
    private static final org.apache.commons.logging.Log logger
  = org.apache.commons.logging.LogFactory
  .getLog(TimerHandlerEJB.class);

    /**
     * The SessionContext interface of the instance.
     */
    private SessionContext ctx;

    /** The cached home interface of the activity. */
    private WfActivityLocalHome activityLocalHomeCache = null;

    /** Application directory. */
    private SimpleApplicationDirectoryLocal applDirCache = null;

    /**
     * Creates an instance of <code>TimerHandlerEJB</code>
     * with all attributes initialized to default values.
     */
    public TimerHandlerEJB () {
    }

    /**
     * The application directory.
     * @return the application directory
     */
    private SimpleApplicationDirectoryLocal applicationDirectory()
  throws ResourceNotAvailableException {
  if (applDirCache == null) {
      applDirCache = (SimpleApplicationDirectoryLocal)
    EJBUtil.createSession
    (SimpleApplicationDirectoryLocalHome.class,
     "java:comp/env/ejb/SimpleApplicationDirectoryLocal");
  }
  return applDirCache;
    }

    /**
     * The home interface of the WfActivityBean.
     * @return home interface of the WfActivityBean
     */
    private WfActivityLocalHome activityLocalHome()
        throws ResourceNotAvailableException {
        if (activityLocalHomeCache == null) {
            activityLocalHomeCache = (WfActivityLocalHome)
                EJBUtil.retrieveEJBLocalHome
                (WfActivityLocalHome.class,
                 "java:comp/env/ejb/ActivityBeanLocal");
        }
        return activityLocalHomeCache;
    }

    /**
     * Save the session context asigned by the container.
     * @param context the context
     */
    public void setSessionContext(SessionContext context) {     
        ctx = context;
    }

    /**
     * Create a new EJB.
     * @throws CreateException if creation fails
     */
    public void ejbCreate() throws CreateException {
    }
   
    /**
     * Remove this EJB.
     */
    public void ejbRemove() {
  ctx = null;
    }

    /**
     * Not called for stateless session beans.
     * @see javax.ejb.SessionBean
     */
    public void ejbActivate() throws EJBException {
    }

    /**
     * Not called for stateless session beans.
     * @see javax.ejb.SessionBean
     */
    public void ejbPassivate() throws EJBException {
    }

    /**
     * Create the timer for a waiting application.
     *
     * @param applId the application id
     * @param waitUntil the time to wait for
     * @return the timer
     * @ejb.interface-method view-type="local"
     */
    public Object createTimer (long applId, Date waitUntil) {
  return ctx.getTimerService().createTimer(waitUntil, new Long (applId))
      .getHandle ();
    }   

    /**
     * Create a timer for a an activity
     *
     * @param auk the activity's unique key
     * the result
     * @param waitUntil the time to wait for
     * @ejb.interface-method view-type="local"
     */
    public void createTimer (ActivityUniqueKey auk, Date waitUntil) {
  ctx.getTimerService().createTimer (waitUntil, auk);
    }   

    /**
     * Remove a previously created timer.
     *
     * @param timer the timer
     * @ejb.interface-method view-type="local"
     */
    public void removeTimer (Object timer) {
        try {
            ((TimerHandle)timer).getTimer().cancel ();
        } catch (NoSuchObjectLocalException e) {
            logger.warn ("Trying to cancel no longer existing timer "
                         + "(may be due to a race condition): "
                         + e.getMessage(), e);
        }
    }

    /**
     * Handle the timeout of a timer.
     * @param timer the timer that has expired.
     */
    public void ejbTimeout (Timer timer) {
  // Note that a RemoteException will lead to a rollback and an
  // automatic re-invocation of this method.
  Object info = timer.getInfo();
  ActivityUniqueKey auk = null;
  String resParam = null;
  long applId = ((Long)info).longValue ();
  SimpleApplicationInfo applInfo = null;
        try {
            try {
                applInfo = applicationDirectory().instanceInfo(applId);
            } catch (InvalidKeyException e) {
                logger.warn ("Application " + applId + " removed without removing "
                        + "associated timer (may be race condition).");
                return;
            }
            auk = applInfo.activityUniqueKey();
            if (logger.isDebugEnabled ()) {
                logger.debug
                ("Handling timeout for application " + applId
                        + (auk == null ? "" : (", " + auk)));
            }
            applicationDirectory().removeInstance (applId);
            if (auk == null) {
                if (logger.isDebugEnabled ()) {
                    logger.debug ("Nothing to do for application " + applId
                            + " (no associated activity)");
                }
                return;
            }
            resParam = (String)((Object[])applInfo.state())[1];
            ActivityLocal act = null;
            try {
                Long pk = Long.valueOf (auk.activityKey());
                act = activityLocalHome().findByPrimaryKey(pk);
            } catch (FinderException nex) {
                logger.warn (auk + " has disappeared (doing nothing)");
                return;
            }
            if (logger.isDebugEnabled ()) {
                logger.debug ("Setting result for " + auk);
            }
            try {
                if (resParam != null) {
                    ProcessData res = new DefaultProcessData ();
                    res.put (resParam, "EXPIRED");
                    act.setResult (res);
                }
                act.complete ();
                if (logger.isDebugEnabled ()) {
                    logger.debug ("Result set for " + auk + " and completed");
                }
                return;
            } catch (InvalidDataException e) {
                logger.error
                ("Cannot set result of wait tool ("
                        + auk + " will be terminated): " + e.getMessage ());
            } catch (CannotCompleteException e) {
                logger.error ("Cannot complete " + auk
                        + " (will be terminated): " + e.getMessage ());
            }
            if (act.typedState().workflowState() == State.OPEN) {
                try {
                    act.terminate ();
                } catch (CannotStopException e) {
                    logger.error
                    ("Cannot terminate " + auk + ": " + e.getMessage ());
                } catch (NotRunningException e) {
                    logger.warn (auk + " not running although state is open?");
                }
            }
        } catch (RemoteException e) {
            throw new EJBException (e);
        }
    }

}
TOP

Related Classes of de.danet.an.workflow.tools.timing.TimerHandlerEJB

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.