Package de.danet.an.workflow.domain

Source Code of de.danet.an.workflow.domain.Deadline

/*
* 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: Deadline.java 2368 2007-05-03 21:58:25Z mlipp $
*
* $Log$
* Revision 1.3  2006/09/29 12:32:08  drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.2  2005/01/09 21:32:42  mlipp
* Added support for debugging exceptions and deadlines.
*
* Revision 1.1.1.2  2004/08/18 15:17:38  drmlipp
* Update to 1.2
*
* Revision 1.10  2004/03/12 12:19:53  lipp
* Javadoc fixes.
*
* Revision 1.9  2003/09/25 12:00:05  lipp
* Avoid client dependency on rhino.
*
* Revision 1.8  2003/09/25 11:01:20  lipp
* Fixed usage of jsScope (may not be used remotely).
*
* Revision 1.7  2003/09/24 20:28:42  lipp
* Reorganized deadline/suspend handling.
*
* Revision 1.6  2003/09/24 13:46:27  lipp
* Fixed JavaScript evaluation with Date result.
*
* Revision 1.5  2003/09/23 17:04:41  lipp
* Fixed retrieval of Date return type.
*
* Revision 1.4  2003/09/22 14:56:47  lipp
* Moved code to Deadline.
*
* Revision 1.3  2003/09/15 15:43:40  lipp
* Initial version of handling exceptions in transition manager.
*
* Revision 1.2  2003/09/09 13:40:23  lipp
* Added state to deadline.
*
* Revision 1.1  2003/09/08 15:37:18  lipp
* Introduced deadline definition and suspend tracking.
*
*/
package de.danet.an.workflow.domain;

import java.io.Serializable;

import java.util.Date;
import java.util.Iterator;
import java.util.List;

import java.text.ParseException;

import org.mozilla.javascript.Context;

import de.danet.an.util.Duration;

import de.danet.an.workflow.api.Activity.DeadlineInfo;
import de.danet.an.workflow.internalapi.ExtProcessLocal;
import de.danet.an.workflow.internalapi.ScriptException;
import de.danet.an.workflow.localapi.ActivityLocal;
import de.danet.an.workflow.util.XPDLUtil;



/**
* This class represents a defined deadline with all its attributes.
*
* @author <a href="mailto:lipp@danet.de">Michael Lipp</a>
* @version $Revision: 2368 $
*/

public class Deadline implements Serializable {

    private static final org.apache.commons.logging.Log logger
  = org.apache.commons.logging.LogFactory.getLog(Deadline.class);
   
    /**
     * Denotes asynchronous execution of the deadline.
     */
    public static final int ASYNCHR = DeadlineInfo.ASYNCHR;

    /**
     * Denotes synchronous execution of the deadline.
     */
    public static final int SYNCHR = DeadlineInfo.SYNCHR;

    /**
     * Deadline is in initial state.
     */
    public static final int STATE_INITIAL = DeadlineInfo.STATE_INITIAL;

    /**
     * Deadline has been reached.
     */
    public static final int STATE_REACHED = DeadlineInfo.STATE_REACHED;

    private int execution;
    private String condition;
    private String exceptionName;
    private int state = STATE_INITIAL;

    /**
     * Creates an instance of <code>Deadline</code>
     * with all attributes initialized to the given values.
     * @param execMode the execution mode
     * @param cond the condition
     * @param exception the exception to be thrown
     */
    public Deadline (int execMode, String cond, String exception) {
  execution = execMode;
  condition = cond;
  exceptionName = exception;
    }
   
    /**
     * Get the value of execution.
     * @return value of execution.
     */
    public int getExecution() {
  return execution;
    }
   
    /**
     * Get the value of Condition.
     * @return value of Condition.
     */
    public String getCondition() {
  return condition;
    }
   
    /**
     * Get the value of ExceptionName.
     * @return value of ExceptionName.
     */
    public String getExceptionName() {
  return exceptionName;
    }

    /**
     * Get the value of state.
     * @return value of state.
     * @see #setState
     */
    public int getState() {
  return state;
    }
   
    /**
     * Set the value of state.
     * @param v value to assign to state.
     * @see #getState
     */
    public void setState(int v) {
  this.state = v;
    }

    /**
     * Evaluate the expiration date for the given deadline.
     *
     * @param baseTime the point in time used to resolve relative time
     * specifications in the condition
     * @param process used for evaluation of the deadline expiration time
     * @return the expiration date
     * @throws ParseException if the condition cannot be evaluated
     */
    public Date expirationDate (Date baseTime, ExtProcessLocal process)
  throws ParseException {
  Object cond = null;
  final ExtProcessLocal proc = process;
  try {
      cond = XPDLUtil.parseDuration
    (getCondition(),
     new Duration.ValueEvaluator () {
         public float evaluate(String s)
       throws ParseException {
       try {
           return Float.parseFloat (s);
       } catch (NumberFormatException e) {
           return evalDurationValue (proc, s);
       }
         }
     });
  } catch (ParseException ee) {
      Context cx = Context.enter();
      try {
    Object res = process.evalScript (getCondition ());
    if (res instanceof Date) {
        cond = (Date)res;
    } else if (res instanceof Number) {
        cond = new Duration ();
        ((Duration)cond).setSeconds
      (((Number)res).floatValue ());
    } else {
        throw new ParseException
      ("Evaluating duration \"" + getCondition()
       + "\" yields neither number nor date.", 0);
    }
      } catch (ScriptException e) {
    throw new ParseException
        ("Problem evaluating duration value \""
         + getCondition() + "\": " + e.getMessage(), 0);
      } finally {
    cx.exit();
      }
  }
  Date end = null;
  if (cond instanceof Date) {
      end = (Date)cond;
  } else {
      Duration dur = (Duration)cond;
      end = dur.addTo (baseTime);
  }
  return end;
    }

    private float evalDurationValue (ExtProcessLocal process, String value)
  throws ParseException {
  try {
      Object res = process.evalScript (value);
      if (!(res instanceof Number)) {
    throw new IllegalArgumentException
        ("Evaluating duration value \"" + value
         + "\" does not yield number.");
      }
      return ((Number)res).floatValue();
  } catch (ScriptException e) {
      throw new ParseException
    ("Problem evaluating duration value \""
     + value + "\": " + e.getMessage(), 0);
  }
    }

    /**
     * Set a timer for the given timed object as specified by this
     * deadline for the given date. This method may be used if the
     * expiration date has been evaluated already.
     *
     * @param to the <code>TimedObject</code>
     * @param expirationDate the expiration date
     * @param info the information to be delivered to the timed object
     * on timeout
     */
    public void arm (TimedObject to, Date expirationDate, Serializable info) {
  if (getState() != Deadline.STATE_INITIAL) {
      return;
  }
  if (logger.isDebugEnabled ()) {
      logger.debug ("Starting timer for " + to.toString() + ", "
        + toString () + ", ends " + expirationDate + " (in "
        + ((expirationDate.getTime() - (new Date()).getTime())
           / 1000.0) + "sec).");
  }
  to.startTimer (expirationDate, info);
    }

    /**
     * Set a timer for the given timed object as specified by this deadline.
     *
     * @param to the <code>TimedObject</code>
     * @param baseTime the point in time used to resolve relative time
     * specifications in the condition
     * @param process used for evaluation of the deadline expiration time
     * @param info the information to be delivered to the timed object
     * on timeout
     */
    public void arm (TimedObject to, Date baseTime,
         ExtProcessLocal process, Serializable info) {
  if (getState() != Deadline.STATE_INITIAL) {
      return;
  }
  try {
      Date end = expirationDate (baseTime, process);
      arm (to, end, info);
  } catch (ParseException e) {
      logger.error (e.getMessage ());
  }
    }

    /**
     * Arms the given list of deadlines on the given object, providing
     * the index in the list as info to be delivered.
     *
     * @param to the <code>TimedObject</code>
     * @param baseTime the point in time used to resolve relative time
     * specifications in the condition
     * @param proc used for evaluation of the deadline expiration time
     * @param dls the deadlines
     */
    public static void armDeadlines
  (TimedObject to, Date baseTime, ExtProcessLocal proc, List dls) {
  int dlIndex = 0;
  for (Iterator dli = dls.iterator (); dli.hasNext ();
       dlIndex += 1) {
      Deadline dl = (Deadline)dli.next ();
      if (dl.getState() != Deadline.STATE_INITIAL) {
    continue;
      }
      dl.arm (to, baseTime, proc, new Integer (dlIndex));
  }
    }

    /**
     * Return string representation for debugging purposes.
     * @return a string representation.
     */
    public String toString() {
  return "Deadline[execution=" + execution
      + ",condition=" + condition.replace('\n', (char)0x00B6)
      + ",execeptionName=" + exceptionName + "]";
    }

}
TOP

Related Classes of de.danet.an.workflow.domain.Deadline

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.