Package de.danet.an.workflow.assignment

Source Code of de.danet.an.workflow.assignment.StandardResourceAssignmentService

/*
* 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: StandardResourceAssignmentService.java 2548 2007-10-22 14:00:52Z  $
*
* $Log$
* Revision 1.7  2007/02/27 14:34:18  drmlipp
* Some refactoring to reduce cyclic dependencies.
*
* Revision 1.6  2006/10/15 19:29:51  mlipp
* Merged changes from 1.4.x up to 1.4ea3pre1.
*
* Revision 1.5.2.2  2006/10/15 18:25:12  mlipp
* Fixed visibility.
*
* Revision 1.5.2.1  2006/10/14 21:34:06  mlipp
* Simplified resource assignment service implementation.
*
* Revision 1.5  2006/09/29 12:32:12  drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.4  2005/10/15 21:19:38  mlipp
* Added support for providing WfAssignment
* implementations based purely on methods of Activity.
*
* Revision 1.3  2005/08/17 21:15:31  mlipp
* Synchronized with 1.3.1p3.
*
* Revision 1.1.1.2.6.1  2005/08/16 14:04:04  drmlipp
* Backported LDAP RMS and security role fixes.
*
* Revision 1.1.1.2.4.2  2005/08/15 16:38:13  drmlipp
* Improved sealing of exceptions from RMS.
*
* Revision 1.1.1.2.4.1  2005/08/14 21:07:55  drmlipp
* Fixed initialization problem (RMS initialized in wrong context).
*
* Revision 1.2  2005/07/04 20:40:25  mlipp
* Improved problem reporting.
*
* Revision 1.1.1.2  2004/08/18 15:17:36  drmlipp
* Update to 1.2
*
* Revision 1.28  2004/06/14 19:37:19  lipp
* Fixed assignment functions and cleaned up assignment related
* interfaces.
*
* Revision 1.27  2004/03/03 17:23:13  lipp
* Implemented setAssignee and cleaned up code a bit.
*
* Revision 1.26  2003/06/27 08:51:46  lipp
* Fixed copyright/license information.
*
* Revision 1.25  2003/04/26 16:11:15  lipp
* Moved some classes to reduce package dependencies.
*
* Revision 1.24  2003/04/25 14:50:59  lipp
* Fixed javadoc errors and warnings.
*
* Revision 1.23  2002/12/19 21:37:43  lipp
* Reorganized interfaces.
*
* Revision 1.22  2002/11/26 11:23:30  lipp
* Modified RemoteException comment.
*
* Revision 1.21  2002/06/27 10:55:35  lipp
* Delayed initialization even more.
*
* Revision 1.20  2002/01/23 15:22:53  huaiyang
* Add M:<name> as resource selection in autoAssignResources method.
*
* Revision 1.19  2002/01/15 13:42:21  lipp
* Added resourceByKey to ResourceAssignmentService and some missing
* NoSuchResourceExceptions in various methods.
*
* Revision 1.18  2002/01/15 11:25:59  huaiyang
* Add the assigned activity function to the mgmt client.
*
* Revision 1.17  2002/01/09 14:48:51  lipp
* Changed access to current user as resource.
*
* Revision 1.16  2002/01/09 14:00:01  lipp
* Cleaned up relation between wfcore, resource assignment and resource
* management service.
*
* Revision 1.15  2002/01/08 18:12:06  lipp
* Method to determined currently logged on user moved to resource
* management service.
*
* Revision 1.14  2001/12/20 22:32:06  lipp
* Removed no longer needed method.
*
* Revision 1.13  2001/12/20 22:27:34  lipp
* WfResource release semantics fixed.
*
* Revision 1.12  2001/12/20 22:22:50  lipp
* Resource release implemented.
*
* Revision 1.11  2001/12/20 16:24:25  lipp
* Resource assignment extended.
*
* Revision 1.10  2001/12/19 22:07:29  lipp
* Automatic resource assignment (workflow core part) implemented.
*
* Revision 1.9  2001/12/18 22:16:52  lipp
* Restructured DOM generation, implemented "assignments" method from ras.
*
* Revision 1.8  2001/12/18 15:35:11  lipp
* Implemented workItems and isMemberOfWorkItem.
*
* Revision 1.7  2001/12/17 19:56:03  lipp
* Implementation of equality checking improved.
*
* Revision 1.6  2001/12/17 15:50:57  lipp
* Better handling of resource refs.
*
* Revision 1.5  2001/12/17 12:14:04  lipp
* Adapted to configurable ResourceManagement/AssignmentServices.
*
* Revision 1.4  2001/12/17 10:52:19  lipp
* Added configurable resource management service.
*
* Revision 1.3  2001/12/17 09:15:50  lipp
* Javadoc fixes.
*
* Revision 1.2  2001/12/16 21:48:57  lipp
* addAssignment implemented.
*
* Revision 1.1  2001/12/16 10:37:35  lipp
* Assignment service implemented.
*
*/
package de.danet.an.workflow.assignment;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import java.io.IOException;
import java.io.OptionalDataException;
import java.rmi.RemoteException;
import java.security.Principal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.ejb.EJBException;
import javax.sql.DataSource;

import de.danet.an.util.EJBUtil;
import de.danet.an.util.JDBCUtil;
import de.danet.an.util.ResourceNotAvailableException;
import de.danet.an.util.UniversalPrepStmt;
import de.danet.an.workflow.omgcore.InvalidResourceException;
import de.danet.an.workflow.omgcore.NotAssignedException;
import de.danet.an.workflow.omgcore.WfActivity;
import de.danet.an.workflow.omgcore.WfAssignment;
import de.danet.an.workflow.omgcore.WfResource;

import de.danet.an.workflow.api.AlreadyAssignedException;
import de.danet.an.workflow.api.InvalidKeyException;
import de.danet.an.workflow.api.NoSuchResourceException;
import de.danet.an.workflow.api.Participant;
import de.danet.an.workflow.api.Participant.ParticipantType;

import de.danet.an.workflow.spis.ras.ActivityFinder;
import de.danet.an.workflow.spis.ras.FactoryConfigurationError;
import de.danet.an.workflow.spis.ras.NoSuchActivityException;
import de.danet.an.workflow.spis.ras.ResourceAssignmentService;
import de.danet.an.workflow.spis.rms.ResourceAssignmentContext;
import de.danet.an.workflow.spis.rms.ResourceManagementService;
import de.danet.an.workflow.spis.rms.ResourceManagementServiceFactory;
import de.danet.an.workflow.spis.rms.ResourceNotFoundException;

/**
* This class implements the standard resource assignment service provided
* as part of the workflow package.
*/
public class StandardResourceAssignmentService
    implements ResourceAssignmentService {

    private static final org.apache.commons.logging.Log logger
  = org.apache.commons.logging.LogFactory.getLog
  (StandardResourceAssignmentService.class);

    /** Warned about RMS not supporting resource selection? */
    private static boolean rmsUnsuppportedWarned = false;
   
    /** An in memory representation of the known finders. */
    private static Map finderByDBIdCache = new HashMap(); // used for sync
    private static Map dbIdByFinderCache = null; // indicates uninitialized

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

    /** The resource management service associated with this service. */
    private ResourceManagementService rms = null;

    /**
     * Constructs a new resource assignment service.
     *
     * @param rasCtx an implementation of the resource Assignment context
     * @param rmsFac the resource management service factory.
     * @throws FactoryConfigurationError if a problem creating the RMS
     * occurs
     */
    public StandardResourceAssignmentService
  (ResourceManagementServiceFactory rmsFac,
         ResourceAssignmentContext rasCtx, DataSource ds)
  throws FactoryConfigurationError {
  try {
      rmsFac.setResourceAssignmentContext (rasCtx);
      rms = rmsFac.newResourceManagementService ();
  } catch (de.danet.an.workflow.spis.rms.FactoryConfigurationError e) {
      throw (FactoryConfigurationError)
          (new FactoryConfigurationError
     ("Cannot create RMS: " + e.getMessage())).initCause(e);
  }
        this.ds = ds;
    }

    /**
     * Return the data source oassed to the constructor.
     * @return Returns the data source.
     */
    protected DataSource getDataSource() {
        return ds;
    }

    /**
     * Return the resource management service passed to the constructor.
     * @return Returns the rms.
     */
    protected ResourceManagementService getResourceManagementService() {
        return rms;
    }

    /**
     * @throws EJBException
     */
    private void initFinderCache() throws EJBException {
        synchronized (finderByDBIdCache) {
            if (dbIdByFinderCache == null) {
                // read finders from database. we cannot do lazy loading,
                // because we cannot lookup by finder (being binary)
                Map finderLookup = new HashMap();
                Map dbIdLookup = new HashMap();
                try {
                    Connection con = null;
                    PreparedStatement prepStmt = null;
                    ResultSet rs = null;
                    try {
                        con = ds.getConnection();
                        String selectStatement
                            = "SELECT DBId, LocData FROM ActivityFinders";
                        prepStmt = con.prepareStatement(selectStatement);
                        rs = prepStmt.executeQuery();
                        while (rs.next()) {
                            long idx = rs.getLong(1);
                            Object finder = JDBCUtil.getBinary(rs, 2);
                            finderLookup.put (new Long(idx), finder);
                            dbIdLookup.put (finder, new Long(idx));
                        }
                    } finally {
                        JDBCUtil.closeAll (rs, prepStmt, con);
                    }
                } catch (SQLException se) {
                    throw new EJBException(se);
                } catch (OptionalDataException ode) {
                    throw new EJBException(ode);
                } catch (IOException ioe) {
                    throw new EJBException(ioe);
                } catch (ClassNotFoundException cnf) {
                    throw new EJBException(cnf);
                }
                finderByDBIdCache = finderLookup;
                dbIdByFinderCache = dbIdLookup;
            }
        }
    }

    /**
     * Get the finder id for a finder.
     *
     * @param finder the activity finder in question.
     * @return the associated index.
     * @throws RemoteException if a system-level error occurs.
     */
    protected long finderId (ActivityFinder finder)
  throws RemoteException {
        synchronized (finderByDBIdCache) {
            initFinderCache();
            Long idx = (Long)dbIdByFinderCache.get (finder);
            if (idx != null) {
                return idx.longValue();
            }
            // new finder, insert
            try {
                Connection con = ds.getConnection();
                UniversalPrepStmt prepStmt = null;
                long newIdx = EJBUtil.newPrimaryKey ("ActivityFinders");
                try {
                    prepStmt = new UniversalPrepStmt
                        (ds, con, "INSERT INTO ActivityFinders (DBId, LocData) "
                         + "VALUES (?, ?)");
                    prepStmt.setLong(1, newIdx);
                    prepStmt.setBinary(2, finder);
                    prepStmt.executeUpdate();
                } finally {
                    JDBCUtil.closeAll (null, prepStmt, con);
                }
                finderByDBIdCache.put (new Long(newIdx), finder);
                dbIdByFinderCache.put (finder, new Long(newIdx));
                return newIdx;
            } catch (ResourceNotAvailableException e) {
                throw new EJBException (e);
            } catch (SQLException se) {
                throw new EJBException(se);
            } catch (OptionalDataException ode) {
                throw new EJBException(ode);
            } catch (IOException ioe) {
                throw new EJBException(ioe);
            }
        }
    }

    /**
     * Lookup a finder for a given finder id.
     *
     * @param finderId the finder id
     * @return the finder
     */
    protected ActivityFinder finderByIndex (long finderId) {
        initFinderCache();
        return (ActivityFinder)finderByDBIdCache.get(new Long(finderId));
    }
   
    /**
     * Change an assignment for enacting an activity.<P>
     *
     * @param finder the finder used to lookup activities by
     * their <code>finderId</code>s
     * @param actId a unique (with respect to an <code>ActivityFinder</code>)
     * identifier for the Activity. The length of <code>actId</code> is
     * guaranteed not to exceed 64
     * @param activity the activity being enacted
     * @param oldResource the resource that has its assignment removed
     * @param newResource the resource to be assigned
     * @throws RemoteException if a system-level error occurs
     * @throws InvalidResourceException if the resource is invalid.
     * As the environment is a concurrent multi user environment,
     * <code>WfResource</code> objects may become invalid
     * @throws AlreadyAssignedException if the assignment already
     * exists
     * @throws NotAssignedException if there is no assignment to the
     * old resource
     * @see ActivityFinder
     */
    public void changeAssignment
  (ActivityFinder finder, String actId, WfActivity activity,
   WfResource oldResource, WfResource newResource)
  throws RemoteException, InvalidResourceException,
         AlreadyAssignedException, NotAssignedException {
  long finderId = finderId (finder);
        try {
            Connection con = null;
            PreparedStatement prepStmt = null;
            ResultSet rs = null;
            try {
                con = ds.getConnection();
                prepStmt = con.prepareStatement
                    ("UPDATE Assignments SET assignedresource=? WHERE "
                     + "actfinder=? AND activity=? AND assignedresource=?");
                prepStmt.setString (1, newResource.resourceKey());
                prepStmt.setLong (2, finderId);
                prepStmt.setString (3, actId);
                prepStmt.setString (4, oldResource.resourceKey());
                if (prepStmt.executeUpdate() != 1) {
                    throw new NotAssignedException ();
                }
            } finally {
                JDBCUtil.closeAll (rs, prepStmt, con);
            }
        } catch (SQLException se) {
            throw new EJBException(se);
        }
    }

    /**
     * Remove the assignment of a resource to an activity. This method
     * is called by the workflow engine to implement the assignment
     * manipulation methods provided by its API.<P>
     *
     * @param actId a unique (with respect to an <code>ActivityFinder</code>)
     * identifier for the Activity. The length of <code>actId</code> is
     * guaranteed not to exceed 64.
     * @param finder the finder used to lookup activities by
     * their <code>finderId</code>s.
     * @param activity the activity that is about to become ready.
     * @param resource the resource to be assigned.
     * @throws RemoteException if a system-level error occurs.
     * @throws InvalidResourceException if the resource is invalid.
     * @throws NotAssignedException if the resource is not assigned to
     * the given activity
     * @see ActivityFinder
     */
    public void removeAssignment (ActivityFinder finder, String actId,
          WfActivity activity, WfResource resource)
  throws RemoteException, InvalidResourceException, NotAssignedException {
  long finderId = finderId (finder);
        try {
            Connection con = null;
            PreparedStatement prepStmt = null;
            ResultSet rs = null;
            try {
                con = ds.getConnection();
                prepStmt = con.prepareStatement
                    ("DELETE FROM Assignments WHERE "
                     + "actfinder=? AND activity=? AND assignedresource=?");
                prepStmt.setLong (1, finderId);
                prepStmt.setString (2, actId);
                prepStmt.setString (3, resource.resourceKey());
                if (prepStmt.executeUpdate() != 1) {
                    throw new NotAssignedException ();
                }
            } finally {
                JDBCUtil.closeAll (rs, prepStmt, con);
            }
        } catch (SQLException se) {
            throw new EJBException(se);
        }
    }

    /**
     * Get the resource associated with an Assignment.<P>
     *
     * @param asnmnt the assignment
     * @return the resource
     * @throws RemoteException if a system-level error occurs.
     * @see de.danet.an.workflow.spis.ras.ActivityFinder
     * @ejb.interface-method view-type="remote"
     */
    public WfResource getResource (WfAssignment asnmnt)
  throws RemoteException  {
        String resKey = null;
        Connection con = null;
        PreparedStatement prepStmt = null;
        ResultSet rs = null;
        try {
            con = ds.getConnection();
            try {
                prepStmt = con.prepareStatement
                    ("SELECT AssignedResource FROM Assignments WHERE DBId = ?");
                prepStmt.setLong (1, ((Assignment)asnmnt).key());
                rs = prepStmt.executeQuery();
                if (!rs.next()) {
                    throw new IllegalStateException
                        ("Cannot access assignment info, "
                         + "assignment has probably been removed");
                }
                resKey = rs.getString(1);
            } finally {
                JDBCUtil.closeAll (rs, prepStmt, con);
            }
        } catch (SQLException se) {
            throw new EJBException(se);
        }
  try {
      return rms.resourceByKey (resKey);
  } catch (ResourceNotFoundException rnf) {
      logger.error (rnf.getMessage (), rnf);
      throw new IllegalStateException
    ("Cannot lookup resource, "
     + "has probably been deleted while being assigned");
  } catch (RemoteException e) {
      throw e;
  } catch (Exception e) {
      logger.error
    (rms + " has thrown an unexpected exception "
     + "(mapped to IllegalStateException): "
     + e.getMessage (), e);
      throw (IllegalStateException)
    (new IllegalStateException
     ("Unexpected exception from RMS: " + e.getMessage ()))
    .initCause (e);
  }
    }

    /**
     * Return the assignments to an activity.
     *
     * @param actId a unique (with respect to an <code>ActivityFinder</code>)
     * identifier for the Activity. The length of <code>actId</code> is
     * guaranteed not to exceed 64.
     * @param finder the finder used to lookup activities by
     * their <code>finderId</code>s.
     * @param activity the activity.
     * @return the collection of assignments (instances of
     * {@link de.danet.an.workflow.omgcore.WfAssignment
     * <code>WfAssignment</code>}).
     * @throws RemoteException if a system-level error occurs.
     */
    public Collection assignments (ActivityFinder finder, String actId,
           WfActivity activity)
  throws RemoteException {
        Collection res = new ArrayList ();
        Connection con = null;
        PreparedStatement prepStmt = null;
        ResultSet rs = null;
        try {
            try {
                con = ds.getConnection();
                String selectStatement
                    = "SELECT DBId FROM Assignments "
                    + "WHERE actfinder=? AND activity=?";
                prepStmt = con.prepareStatement(selectStatement);
                prepStmt.setLong (1, finderId(finder));
                prepStmt.setString (2, actId);
                rs = prepStmt.executeQuery();
                while (rs.next()){
                    res.add (new Assignment(rs.getLong (1), activity));
                }
            } finally {
                JDBCUtil.closeAll (rs, prepStmt, con);
            }
        } catch (SQLException se) {
            throw new EJBException(se);
        }
  return res;
    }

    /**
     * Return the assignments of a given resource.
     *
     * @param resource the resource.
     * @return the collection of assigned work items (instances of
     * {@link de.danet.an.workflow.omgcore.WfAssignment
     * <code>WfAssignment</code>}).
     * @throws RemoteException if a system-level error occurs.
     * @see de.danet.an.workflow.spis.rms
     */
    public Collection workItems (WfResource resource)
  throws RemoteException {
        Connection con = null;
        PreparedStatement prepStmt = null;
        ResultSet rs = null;
        Collection res = new ArrayList();
        try {
            try {
                con = ds.getConnection();
                prepStmt = con.prepareStatement
                    ("SELECT DBId, actfinder, activity FROM Assignments "
                     + "WHERE assignedresource=?");
                prepStmt.setString (1, resource.resourceKey());
                rs = prepStmt.executeQuery();
                while (rs.next()){
                    long dbid = rs.getLong (1);
                    long idx = rs.getLong (2);
                    ActivityFinder finder = finderByIndex(idx);
                    String actKey = rs.getString(3);
                    try {
                        res.add (new Assignment (dbid, finder.find (actKey)));
                    } catch (NoSuchActivityException e) {
                        // race condition
                        logger.debug
                            ("Found assignment to activity key " + actKey
                             + " but not the activity: " + e.getMessage ());
                    } catch (RemoteException rex) {
                        throw new EJBException (rex);
                    }
                }
            } finally {
                JDBCUtil.closeAll (rs, prepStmt, con);
            }
        } catch (RemoteException e) {
            throw new EJBException(e);
        } catch (SQLException se) {
            throw new EJBException(se);
        }
        return res;
    }

    /**
     * Find out if a given assignment belongs to the work items assigned to
     * a particular resource.
     *
     * @param resource the resource.
     * @param assignment the assignment in question.
     * @return <code>true</code> if the <code>assignment</code> belongs to
     * the work items of the <code>resource</code>.
     * @throws RemoteException if a system-level error occurs.
     * @throws NoSuchResourceException if the resource is invalid.
     * @see de.danet.an.workflow.spis.rms
     */
    public boolean isMemberOfWorkItems (WfResource resource,
          WfAssignment assignment)
  throws RemoteException, NoSuchResourceException {
  if (!(assignment instanceof Assignment)) {
      return false;
  }
  Assignment assmnt = (Assignment)assignment;
  return resource.equals (assmnt.assignee());
    }

    /**
     * Triggers the automatic assignment of resources to an activity that
     * is about to become ready.<P>
     *
     * If <code>resSel</code> is of type string, the following cases
     * are handled by the assignment service:
     * <dl>
     *   <dt><code>!:currentUser</code></dt>
     *   <dd>Assigns the current user.</dd>
     * </dl>
     *
     * In all other cases the parameter <code>resSel</code> is simply
     * passed through to
     * {@link ResourceManagementService#selectResources the resource
     * selection service}.
     *
     * @param actId a unique (with respect to an <code>ActivityFinder</code>)
     * identifier for the Activity. The length of <code>actId</code> is
     * guaranteed not to exceed 64.
     * @param finder the finder used to lookup activities by
     * their <code>finderId</code>s.
     * @param activity the activity that is about to become ready.
     * @param principal the current caller as known in the EJB context,
     * may be <code>null</code>.
     * @param participant the <code>Participant</code> that describes the
     * resource selection criteria.
     * @return the assigned resources (instances of {@link
     * de.danet.an.workflow.omgcore.WfResource
     * <code>WfResource</code>}).
     * @throws RemoteException if a system-level error occurs.
     * @see ActivityFinder
     */
    public Collection autoAssignResources
        (ActivityFinder finder, String actId, WfActivity activity,
         Principal principal, Participant participant)
        throws RemoteException {
        if (participant == null) {
            return new ArrayList ();
        }

        Object resSel = null;
        ParticipantType type = participant.getParticipantType();
        Collection assigned = new ArrayList ();
        if (type.isResourceSet()) {
            resSel = "G:" + participant.getName();
        } else if (type.isRole()) {
            resSel = "R:" + participant.getName();
        } else if (type.isHuman()) {
            String crit = (String)participant.getResourceSelection();
            if (crit != null && crit.startsWith ("!:currentUser")
                && principal != null) {
                try {
                    WfResource res = asResource (principal);
                    assigned.add (res);
                    addAssignment (finderId(finder), actId, res);
                    return assigned;
                } catch (AlreadyAssignedException rnf) {
                    return assigned;
                } catch (InvalidKeyException rnf) {
                    return assigned;
                }
            }
            resSel = "M:" + participant.getName();
        }

        // fall through
        try {
            Collection reses = rms.selectResources (resSel);
            if (reses.size() == 0) {
                return assigned;
            }
            long finderId = finderId (finder);
            for (Iterator i = reses.iterator(); i.hasNext();) {
                WfResource res = (WfResource)i.next();
                assigned.add (res);
                addAssignment (finderId, actId, res);
            }
            return assigned;
        } catch (AlreadyAssignedException rnf) {
            return assigned;
        } catch (UnsupportedOperationException uo) {
                if (!rmsUnsuppportedWarned) {
                logger.warn ("Configured RMS does not support resource "
                             + "selection, no resources assigned.");
                rmsUnsuppportedWarned = true;
            }
            return assigned;
        } catch (RemoteException e) {
            throw e;
        } catch (Exception e) {
            logger.error
                (rms + " has thrown an unexpected exception, "
                 + "no resources are assigned: " + e.getMessage (), e);
            return assigned;
        }
    }

    /**
     * Assign a resource to an activity.
     *
     * @param actId a unique (with respect to an <code>ActivityFinder</code>)
     * identifier for the Activity. The length of <code>actId</code> is
     * guaranteed not to exceed 64.
     * @param finderId the <code>finderId</code>s.
     * @param activity the activity that is about to become ready.
     * @param resource the resource to be assigned.
     * @throws RemoteException if a system-level error occurs.
     * @throws NoSuchResourceException if the resource is invalid.
     * @see ActivityFinder
     * @throws AlreadyAssignedException if the assignment already
     * exists
     */
    protected void addAssignment
        (long finderId, String actId, WfResource resource)
        throws RemoteException, AlreadyAssignedException {
        try {
            Connection con = null;
            PreparedStatement prepStmt = null;
            ResultSet rs = null;
            try {
                con = ds.getConnection();
                prepStmt = con.prepareStatement
                    ("SELECT DBId FROM Assignments WHERE "
                     + "actfinder=? AND activity=? AND assignedresource=?");
                prepStmt.setLong (1, finderId);
                prepStmt.setString (2, actId);
                prepStmt.setString (3, resource.resourceKey());
                rs = prepStmt.executeQuery();
                if (rs.next()){
                    throw new AlreadyAssignedException ();
                }
                rs.close ();
                rs = null;
                prepStmt.close ();
                prepStmt = con.prepareStatement
                    ("INSERT INTO Assignments "
                     + "(DBId, actfinder, activity, assignedresource) "
                     + "VALUES (?, ?, ?, ?)");
                long id = EJBUtil.newPrimaryKey ("Assignments");
                prepStmt.setLong (1, id);
                prepStmt.setLong(2, finderId);
                prepStmt.setString (3, actId);
                prepStmt.setString (4, resource.resourceKey());
                prepStmt.executeUpdate();
            } catch (ResourceNotAvailableException e) {
                throw new SQLException
                    ("Cannot get primary key" + e.getMessage());
            } finally {
                JDBCUtil.closeAll (rs, prepStmt, con);
            }
        } catch (SQLException se) {
            throw new EJBException(se);
        }
       
    }

    /**
     * Returns at least the collection of all the workflow resources whom has
     * been assigned work items, but optionally it can return the additional
     * workflow resources who are known to the resource assignment service.
     *
     * @return the collection of the known resources to the ras (instances of
     * {@link de.danet.an.workflow.omgcore.WfResource
     * <code>WfResource</code>}).
     * @throws RemoteException if a system-level error occurs.
     * @see de.danet.an.workflow.assignment
     */
    public Collection knownResources ()
  throws RemoteException {
  try {
      return rms.listResources();
  } catch (RemoteException e) {
      throw e;
  } catch (Exception e) {
      logger.error
    (rms + " has thrown an unexpected exception, "
     + "no resources are listed: " + e.getMessage (), e);
      return new ArrayList ();
  }
    }

    /* Comment copied from interface. */
    public Collection authorizers (WfResource resource)
  throws RemoteException {
  try {
      return rms.authorizers(resource);
  } catch (RemoteException e) {
      throw e;
  } catch (Exception e) {
      logger.error
    (rms + " has thrown an unexpected exception, "
     + "no authorizers returned: "
     + e.getMessage (), e);
      return new ArrayList ();
  }
    }
   
    /**
     * Given a {@link java.security.Principal principal}, return the
     * workflow resource associated with this principal. This implementation
     * simply delegates the request to the resource management service.
     *
     * @param principal the principal.
     * @return a <code>WfResource</code> object corresponding to the
     * given principal.
     * @throws NoSuchResourceException if the StaffMember with the given key
     * can't be found or the key is not associate with an StaffMember object.
     * @throws RemoteException if a system-level error occurs.
     */
    public WfResource asResource (Principal principal)
        throws RemoteException, InvalidKeyException {
        try {
            return rms.asResource (principal);
        } catch (ResourceNotFoundException rnf) {
            throw new InvalidKeyException (rnf.getMessage());
        }
    }

    /**
     * Given the <code>key</code> of a <code>WfResource</code>
     * (obtained with {@link WfResource#resourceKey
     * <code>resourceKey()</code>}), return the workflow resource
     * associated with this key.<P>
     *
     * This method is implemented by simply calling
     * {@link ResourceManagementService#resourceByKey
     * <code>resourceByKey</code>} of the underlying resource
     * management service.
     *
     * @param key the key.
     * @return a <code>WfResource</code> object corresponding to the
     * given key.
     * @throws NoSuchResourceException if the resource with the given
     * key can't be found. As the environment is a concurrent multi
     * user environment, <code>WfResource</code> objects (and keys obtained
     * from <code>WfResource</code> objects) may become invalid.
     * @throws RemoteException if a system-level error occurs.
     */
    public WfResource resourceByKey (String key)
        throws InvalidKeyException, RemoteException {
        try {
            return rms.resourceByKey (key);
        } catch (ResourceNotFoundException rnf) {
            throw new InvalidKeyException (rnf.getMessage());
        }      
    }
}
TOP

Related Classes of de.danet.an.workflow.assignment.StandardResourceAssignmentService

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.