Package de.danet.an.workflow.tools.util

Source Code of de.danet.an.workflow.tools.util.SimpleApplicationDirectoryEJB

/*
* 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: SimpleApplicationDirectoryEJB.java 2738 2008-04-04 09:16:34Z drmlipp $
*
* $Log$
* Revision 1.14  2007/01/31 12:24:07  drmlipp
* Design revisited.
*
* Revision 1.13  2006/12/12 10:54:38  drmlipp
* Added method for retrieving infos by application.
*
* Revision 1.11  2006/10/25 21:42:34  mlipp
* Handling duplicate keys.
*
* Revision 1.10  2006/10/25 15:46:04  drmlipp
* Added support for looking up entries by key.
*
* Revision 1.9  2006/10/11 09:05:54  drmlipp
* Fixed EJB naming.
*
* Revision 1.8  2006/10/07 20:41:34  mlipp
* Merged J2EE 1.4 adaptions from test branch.
*
* Revision 1.7  2006/09/29 12:32:09  drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.6  2006/09/22 08:17:14  drmlipp
* Removed strange import.
*
* Revision 1.5  2006/09/21 12:20:38  drmlipp
* Added lookup by resource.
*
* Revision 1.4  2005/04/22 15:11:05  drmlipp
* Merged changes from 1.3 branch up to 1.3p15.
*
* Revision 1.2.6.2  2005/04/13 16:14:08  drmlipp
* Optimized db access.
*
* Revision 1.3  2005/04/08 11:28:05  drmlipp
* Merged changes from 1.3 branch up to 1.3p6.
*
* Revision 1.2.6.1  2005/04/04 20:09:22  drmlipp
* Changed WLS transaction isolation.
*
* Revision 1.2  2004/09/10 12:44:31  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.6  2004/07/04 17:36:03  lipp
* Added JOnAS support.
*
* Revision 1.5  2004/04/08 09:34:54  lipp
* Clarified documentation of package structure.
*
* Revision 1.4  2004/02/27 12:01:48  lipp
* Fixed permissions.
*
* Revision 1.3  2004/02/20 15:58:22  lipp
* Several WaitTool fixes.
*
* Revision 1.2  2004/02/19 18:06:42  lipp
* Fixed application name handling.
*
* Revision 1.1  2004/02/19 17:55:54  lipp
* Initial version of waittool.
*
*/
package de.danet.an.workflow.tools.util;

import java.io.IOException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;

import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import de.danet.an.util.EJBUtil;
import de.danet.an.util.JDBCUtil;
import de.danet.an.util.UniversalPrepStmt;

import de.danet.an.workflow.omgcore.WfAssignment;

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

/**
* This EJB provides a directory for simple applications. Applications
* are considered simple in this context if their state 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 an assigned
* resource may be saved in this directory as well.
*
* @see de.danet.an.workflow.util
*
* @author <a href="mailto:lipp@danet.de">Michael Lipp</a>
* @version $Revision: 2738 $
* @ejb.bean name="SimpleApplicationDirectory"
* jndi-name="ejb/@@@_JNDI_Name_Prefix_@@@SimpleApplicationDirectory"
* local-jndi-name="ejb/@@@_JNDI_Name_Prefix_@@@SimpleApplicationDirectoryLocal"
* display-name="Simple Application Directory EJB"
* type="Stateless" transaction-type="Container" view-type="both"
* @jonas.bean ejb-name="SimpleApplicationDirectory"
* @ejb.transaction type="Required"
* @ejb.permission role-name="WfMOpenAdmin"
* @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"
* @ejb.resource-ref res-ref-name="jdbc/WfEngine"
* res-type="javax.sql.DataSource" res-auth="Container"
* @jonas.resource res-ref-name="jdbc/WfEngine" jndi-name="jdbc_1"
* @weblogic.enable-call-by-reference True
* @weblogic.resource-description
* res-ref-name="jdbc/WfEngine" jndi-name="DefaultDS"
* @weblogic.transaction-isolation TRANSACTION_READ_COMMITTED
*/

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

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

    /**
     * The data source of the database.
     * @see javax.sql.DataSource
     */
    private DataSource ds = null;

    /** Database name. */
    private static final String DB_NAME = "java:comp/env/jdbc/WfEngine";

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

    /**
     * Save the session context asigned by the container.
     * @param context the context
     */
    public void setSessionContext(SessionContext context) {     
        ctx = context;
  // getting new data source
  try {
      ds = JDBCUtil.refreshDS(null, DB_NAME);
  } catch (NamingException ne) {
      throw new EJBException(ne);
  }
    }

    /**
     * Create a new EJB.
     * @throws CreateException if creation fails
     */
    public void ejbCreate() throws CreateException {
    }
   
    /**
     * Remove this EJB.
     */
    public void ejbRemove() {
  ds = null;
  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 {
    }

    /**
     * Register a new application instance. This method returns a unique
     * key that can be used to {@link #instanceInfo(long) retrieve},
     * {@link #updateState(long, Object) update} and
     * {@link #removeInstance(long)} remove the instance information.<P>
     *
     * @param applName the application name
     * @param activity the invoking activity
     * @param state the application state
     * @param saveAssignment if <code>true</code> the assigned
     * resource will be saved to allow searching application instances
     * with a particular assignee
     * @return the instance id
     * @ejb.interface-method view-type="both"
     */
    public long registerInstance (String applName, Activity activity,
                                  Object state, boolean saveAssignment) {
        return registerInstance
            (applName, null, activity, state, saveAssignment);
    }
   
    /**
     * Register a new application instance. This method returns a unique
     * key that may be used to
     *
     * @param applName the application name
     * @param applInstKey an arbitrary key for this instance, up to 1000
     * characters long
     * @param activity the invoking activity
     * @param state the application state
     * @param saveAssignment if <code>true</code> the assigned
     * resource will be saved to allow searching application instances
     * with a particular assignee
     * @return the instance id
     * @ejb.interface-method view-type="both"
     */
    public long registerInstance
        (String applName, String applInstKey,
         Activity activity, Object state, boolean saveAssignment) {
  try {
      Connection con = null;
      UniversalPrepStmt prepStmt = null;
      try {
    ActivityUniqueKey auk = activity.uniqueKey();
    con = ds.getConnection();
    long instId = EJBUtil.newPrimaryKey
        ("SimpleApplicationDirectory");
    prepStmt = new UniversalPrepStmt
        (ds, con, "INSERT INTO SimpleAppl (DBId, ApplName, "
         + "InstKey, ActivityKey, ProcessKey, ProcessMgr"
         + (saveAssignment ? ", ResourceKey" : "")
         + ", AssignedAt, InstData) VALUES (?, ?, ?, ?, ?, ?"
         + (saveAssignment ? ", ?" : "")
         + ", ?, ?)");
    int offset = 1;
    prepStmt.setLong (offset++, instId);
    prepStmt.setString (offset++, applName);
                prepStmt.setString (offset++, applInstKey);
    prepStmt.setString (offset++, auk.activityKey());
    prepStmt.setString (offset++, auk.processKey());
    prepStmt.setString (offset++, auk.managerName());
    if (saveAssignment) {
        String resourceKey = null;
        Iterator i = activity.assignments().iterator();
        if (i.hasNext ()) {
      WfAssignment assignment = (WfAssignment)i.next();
      resourceKey = assignment.assignee().resourceKey();
        }
        prepStmt.setString (offset++, resourceKey);
    }
    prepStmt.setTimestamp
        (offset++, new Timestamp (System.currentTimeMillis()));
    prepStmt.setBinary(offset++, state);
    prepStmt.executeUpdate();
    if (logger.isDebugEnabled()) {
        logger.debug
      ("Created application " + instId + " for " + auk);
    }
    return instId;
      } finally {
    JDBCUtil.closeAll (null, prepStmt, con);
      }
  } catch (SQLException e) {
      throw new EJBException(e);
  } catch (IOException e) {
      throw new EJBException(e);
  }
    }   

    /**
     * Remove an application instance.
     *
     * @param instId the application instance id previously assigned
     * by {@link #registerInstance <code>registerInstance</code>}
     * @ejb.interface-method view-type="both"
     */
    public void removeInstance (long instId) {
  try {
      Connection con = null;
      UniversalPrepStmt prepStmt = null;
      try {
    con = ds.getConnection();
    prepStmt = new UniversalPrepStmt
        (ds, con, "DELETE FROM SimpleAppl WHERE DBId = ?");
    prepStmt.setLong (1, instId);
    prepStmt.executeUpdate();
    if (logger.isDebugEnabled()) {
        logger.debug ("Removed application " + instId);
    }
      } finally {
    JDBCUtil.closeAll (null, prepStmt, con);
      }
  } catch (SQLException e) {
      throw new EJBException(e);
  }
    }   

    /**
     * Return the information associated with the application instance.
     *
     * @param instId the application instance id previously assigned
     * by {@link #registerInstance <code>registerInstance</code>}
     * @throws InvalidKeyException if there is no data available for
     * the given id
     * @return the info
     * @ejb.interface-method view-type="both"
     */
    public SimpleApplicationInfo instanceInfo (long instId)
  throws InvalidKeyException {
  try {
      Connection con = null;
      UniversalPrepStmt prepStmt = null;
      ResultSet rs = null;
      try {
    con = ds.getConnection();
    prepStmt = new UniversalPrepStmt
        (ds, con, "SELECT ActivityKey, ProcessKey, ProcessMgr, "
         + "ResourceKey, AssignedAt, InstData "
         + "FROM SimpleAppl WHERE DBId = ?");
    prepStmt.setLong (1, instId);
    rs = prepStmt.executeQuery();
    if (! rs.next()) {
        throw new InvalidKeyException
      ("No application instance with key = " + instId);
    }
    String actKey = rs.getString (1);
    String prcKey = rs.getString (2);
    String mgrKey = rs.getString (3);
    String resKey = rs.getString (4);
    Date asndAt = rs.getTimestamp(5);
    Object state = JDBCUtil.getBinary(rs, 6);
    return new SimpleApplicationInfo
        (instId, actKey == null? null
         : new ActivityUniqueKey (mgrKey, prcKey, actKey),
         asndAt, resKey, state);
      } finally {
    JDBCUtil.closeAll (rs, prepStmt, con);
      }
  } catch (ClassNotFoundException e) {
      throw new EJBException(e);
  } catch (IOException e) {
      throw new EJBException(e);
  } catch (SQLException e) {
      throw new EJBException(e);
  }
    }   

    /**
     * Return the information associated with the activity.
     *
     * @param auk the unique key of the activity an application
     * instance is expected to be registered for.
     * @throws InvalidKeyException if there is no data available for
     * the given activity
     * @return the info
     * @ejb.interface-method view-type="both"
     */
    public SimpleApplicationInfo infoByActivity (ActivityUniqueKey auk)
  throws InvalidKeyException {
  try {
      Connection con = null;
      UniversalPrepStmt prepStmt = null;
      ResultSet rs = null;
      try {
    con = ds.getConnection();
    prepStmt = new UniversalPrepStmt
        (ds, con, "SELECT DBId, ResourceKey, AssignedAt, InstData "
         + "FROM SimpleAppl WHERE ActivityKey = ? "
         + "AND ProcessKey = ? AND ProcessMgr = ?");
    prepStmt.setString (1, auk.activityKey());
    prepStmt.setString (2, auk.processKey());
    prepStmt.setString (3, auk.managerName());
    rs = prepStmt.executeQuery();
    if (! rs.next()) {
        throw new InvalidKeyException
      ("No application instance for activity = " + auk);
    }
    long instId = rs.getLong(1);
    String resKey = rs.getString (2);
    Date asndAt = rs.getTimestamp (3);
    Object state = JDBCUtil.getBinary(rs, 4);
    return new SimpleApplicationInfo
        (instId, auk, asndAt, resKey, state);
      } finally {
    JDBCUtil.closeAll (rs, prepStmt, con);
      }
  } catch (ClassNotFoundException e) {
      throw new EJBException(e);
  } catch (IOException e) {
      throw new EJBException(e);
  } catch (SQLException e) {
      throw new EJBException(e);
  }
    }   

    /**
     * Return infos associated with a given application.
     *
     * @param applName the application name
     * @return the infos as collection
     * @ejb.interface-method view-type="both"
     */
    public Collection infosByApplication (String applName) {
        Collection res = new ArrayList ();
        try {
            Connection con = null;
            UniversalPrepStmt prepStmt = null;
            ResultSet rs = null;
            try {
                con = ds.getConnection();
                prepStmt = new UniversalPrepStmt
                    (ds, con, "SELECT DBId, ActivityKey, ProcessKey, "
                     + "ProcessMgr, ResourceKey, AssignedAt, InstData "
                     + "FROM SimpleAppl WHERE ApplName = ? ");
                prepStmt.setString (1, applName);
                rs = prepStmt.executeQuery();
                while (rs.next()) {
                    int pos = 1;
                    long instId = rs.getLong(pos++);
                    String actKey = rs.getString(pos++);
                    String procKey = rs.getString(pos++);
                    String procMgr = rs.getString(pos++);
                    String resourceKey = rs.getString(pos++);
                    Date asndAt = rs.getTimestamp (pos++);
                    Object state = JDBCUtil.getBinary(rs, pos++);
                    ActivityUniqueKey auk
                        = new ActivityUniqueKey(procMgr, procKey, actKey);
                    res.add(new SimpleApplicationInfo
                            (instId, auk, asndAt, resourceKey, state));
                }
                return res;
            } finally {
                JDBCUtil.closeAll (rs, prepStmt, con);
            }
        } catch (ClassNotFoundException e) {
            throw new EJBException(e);
        } catch (IOException e) {
            throw new EJBException(e);
        } catch (SQLException e) {
            throw new EJBException(e);
        }
    }   

    /**
     * Return the infos associated with the given application name and key.
     *
     * @param applName the application name
     * @param applInstKey the key associated with the instance
     * @return the infos or an empty collection if no infos
     * with the given application name and key exist
     * @ejb.interface-method view-type="both"
     */
    public Collection infosByKey (String applName, String applInstKey)
        throws InvalidKeyException {
        try {
            Collection res = new ArrayList ();
            Connection con = null;
            UniversalPrepStmt prepStmt = null;
            ResultSet rs = null;
            try {
                con = ds.getConnection();
                prepStmt = new UniversalPrepStmt
                    (ds, con, "SELECT DBId, ActivityKey, ProcessKey, "
                     + "ProcessMgr, ResourceKey, AssignedAt, InstData "
                     + "FROM SimpleAppl WHERE ApplName = ? AND InstKey = ?");
                prepStmt.setString (1, applName);
                prepStmt.setString (2, applInstKey);
                rs = prepStmt.executeQuery();
                while (rs.next()) {
                    int pos = 1;
                    long instId = rs.getLong(pos++);
                    String actKey = rs.getString(pos++);
                    String procKey = rs.getString(pos++);
                    String procMgr = rs.getString(pos++);
                    String resKey = rs.getString (pos++);
                    Date asndAt = rs.getTimestamp (pos++);
                    Object state = JDBCUtil.getBinary(rs, pos++);
                    ActivityUniqueKey auk
                        = new ActivityUniqueKey(procMgr, procKey, actKey);
                    res.add(new SimpleApplicationInfo
                            (instId, auk, asndAt, resKey, state));
                }
                return res;
            } finally {
                JDBCUtil.closeAll (rs, prepStmt, con);
            }
        } catch (ClassNotFoundException e) {
            throw new EJBException(e);
        } catch (IOException e) {
            throw new EJBException(e);
        } catch (SQLException e) {
            throw new EJBException(e);
        }
    }   

    /**
     * Return infos associated with a given application and resource.
     *
     * @param applName the application name
     * @param resourceKey the resource's key
     * @return the infos as collection
     * @ejb.interface-method view-type="both"
     */
    public Collection infosByResource
        (String applName, String resourceKey) {
        Collection res = new ArrayList ();
        try {
            Connection con = null;
            UniversalPrepStmt prepStmt = null;
            ResultSet rs = null;
            try {
                con = ds.getConnection();
                prepStmt = new UniversalPrepStmt
                    (ds, con, "SELECT DBId, ActivityKey, ProcessKey, "
                     + "ProcessMgr, AssignedAt, InstData "
                     + "FROM SimpleAppl "
                     + "WHERE ApplName = ? AND ResourceKey = ? ");
                prepStmt.setString (1, applName);
                prepStmt.setString (2, resourceKey);
                rs = prepStmt.executeQuery();
                while (rs.next()) {
                    int pos = 1;
                    long instId = rs.getLong(pos++);
                    String actKey = rs.getString(pos++);
                    String procKey = rs.getString(pos++);
                    String procMgr = rs.getString(pos++);
                    Date asndAt = rs.getTimestamp (pos++);
                    Object state = JDBCUtil.getBinary(rs, pos++);
                    ActivityUniqueKey auk
                        = new ActivityUniqueKey(procMgr, procKey, actKey);
                    res.add(new SimpleApplicationInfo
                            (instId, auk, asndAt, resourceKey, state));
                }
                return res;
            } finally {
                JDBCUtil.closeAll (rs, prepStmt, con);
            }
        } catch (ClassNotFoundException e) {
            throw new EJBException(e);
        } catch (IOException e) {
            throw new EJBException(e);
        } catch (SQLException e) {
            throw new EJBException(e);
        }
    }   

    /**
     * Update the state information associated with the given
     * application instance id.
     *
     * @param instId the application instance id previously assigned
     * by {@link #registerInstance <code>registerInstance</code>}
     * @param state the new state
     * @throws InvalidKeyException if there is no application instance
     * with the given id
     * @ejb.interface-method view-type="both"
     */
    public void updateState (long instId, Object state)
  throws InvalidKeyException {
  try {
      Connection con = null;
      UniversalPrepStmt prepStmt = null;
      ResultSet rs = null;
      try {
    con = ds.getConnection();
    prepStmt = new UniversalPrepStmt
        (ds, con,
         "UPDATE SimpleAppl SET InstData = ? WHERE DBId = ? ");
    prepStmt.setBinary (1, state);
    prepStmt.setLong (2, instId);
    if (prepStmt.executeUpdate() == 0) {
        throw new InvalidKeyException
      ("No application instance with key = " + instId);
    }
    if (logger.isDebugEnabled()) {
        logger.debug
      ("Updated state for application " + instId);
    }
      } finally {
    JDBCUtil.closeAll (rs, prepStmt, con);
      }
  } catch (IOException e) {
      throw new EJBException(e);
  } catch (SQLException e) {
      throw new EJBException(e);
  }
    }   

    /**
     * Update the resource associated with the given
     * application instance id.
     *
     * @param instId the application instance id previously assigned
     * by {@link #registerInstance <code>registerInstance</code>}
     * @param resourceKey the associated resource
     * @throws InvalidKeyException if there is no application instance
     * with the given id
     * @ejb.interface-method view-type="both"
     */
    public void updateResourceKey (long instId, String resourceKey)
        throws InvalidKeyException {
        try {
            Connection con = null;
            UniversalPrepStmt prepStmt = null;
            ResultSet rs = null;
            try {
                con = ds.getConnection();
                prepStmt = new UniversalPrepStmt
                    (ds, con,
                     "UPDATE SIMPLEAPPL SET RESOURCEKEY = ? WHERE DBID = ? ");
                prepStmt.setString (1, resourceKey);
                prepStmt.setLong (2, instId);
                if (prepStmt.executeUpdate() == 0) {
                    throw new InvalidKeyException
                        ("No application instance with key = " + instId);
                }
                if (logger.isDebugEnabled()) {
                    logger.debug
                        ("Updated resourceKey for application " + instId);
                }
            } finally {
                JDBCUtil.closeAll (rs, prepStmt, con);
            }
        } catch (SQLException e) {
            throw new EJBException(e);
        }
    }   

    /**
     * Update the activity associated with the given application
     * instance.  This is useful if an application instance is started
     * by one tool (agent) invocation and stopped by another.<P>
     *
     * Be careful to ensure the eventual termination of the
     * application. If the creating activity has completed, the
     * terminate method of the tool agent that started the application
     * will not be called on abnormal process completion. So, if a
     * process is terminated abnormally and the starting activity is
     * closed and the stopping activity has not yet been started (and
     * associated with the application) the application will not be
     * stopped. This should normally not be a problem for simple
     * applications.<P>
     *
     * As a convenience, any application information that is still
     * registered after a process completion will automatically be
     * deleted.<P>
     *
     * The new activity must belong to the same process as the
     * activity that initially created the application instance.
     *
     * @param instId the application instance id previously assigned
     * by {@link #registerInstance <code>registerInstance</code>}
     * @param auk the new activity's unique key. May be
     * <code>null</code> if the application instance is temporarily
     * not associated with an activity.
     * @throws InvalidKeyException if there is no application instance
     * with the given id
     * @ejb.interface-method view-type="both"
     */
    public void updateInvokingActivity (long instId, ActivityUniqueKey auk)
  throws InvalidKeyException {
  try {
      Connection con = null;
      UniversalPrepStmt prepStmt = null;
      ResultSet rs = null;
      try {
    con = ds.getConnection();
    prepStmt = new UniversalPrepStmt
        (ds, con, "UPDATE SimpleAppl "
         + "SET ActivityKey = ? WHERE DBId = ?");
    prepStmt.setString (1, auk == null ? null : auk.activityKey());
    prepStmt.setLong (2, instId);
    if (prepStmt.executeUpdate() == 0) {
        throw new InvalidKeyException
      ("No application instance with key = " + instId);
    }
    if (logger.isDebugEnabled()) {
        logger.debug ("Application " + instId
          + " has been associated with " + auk);
    }
      } finally {
    JDBCUtil.closeAll (rs, prepStmt, con);
      }
  } catch (SQLException e) {
      throw new EJBException(e);
  }
    }   

}
TOP

Related Classes of de.danet.an.workflow.tools.util.SimpleApplicationDirectoryEJB

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.