Package de.danet.an.workflow.ejbs.admin

Source Code of de.danet.an.workflow.ejbs.admin.ProcessDirectoryEJB

/*
* 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: ProcessDirectoryEJB.java 2945 2009-02-19 20:09:16Z mlipp $
*
* $Log$
* Revision 1.8  2007/05/03 21:58:25  mlipp
* Internal refactoring for making better use of local EJBs.
*
*/
package de.danet.an.workflow.ejbs.admin;

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

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

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

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;

import de.danet.an.util.EJBUtil;
import de.danet.an.util.JDBCUtil;
import de.danet.an.util.ResourceNotAvailableException;
import de.danet.an.util.logging.RequestLog;
import de.danet.an.util.logging.RequestScope;

import de.danet.an.workflow.localapi.ProcessLocal;
import de.danet.an.workflow.omgcore.WfRequester;
import de.danet.an.workflow.util.HibernateUtil;

import de.danet.an.workflow.api.Activity;
import de.danet.an.workflow.api.ActivityUniqueKey;
import de.danet.an.workflow.api.CannotRemoveException;
import de.danet.an.workflow.api.InvalidKeyException;
import de.danet.an.workflow.api.Process;
import de.danet.an.workflow.api.RangeAccess;
import de.danet.an.workflow.api.query.AscendingOrder;
import de.danet.an.workflow.api.query.FilterCriterion;
import de.danet.an.workflow.api.query.SortCriterion;
import de.danet.an.workflow.apix.ExtProcessDirectory;

import de.danet.an.workflow.ejbs.core.WfActivityHome;
import de.danet.an.workflow.ejbs.core.WfProcess;
import de.danet.an.workflow.ejbs.core.WfProcessHome;
import de.danet.an.workflow.ejbs.core.WfProcessLocalHome;
import de.danet.an.workflow.ejbs.core.WfProcessEJB.DAO;

/**
* The session bean <code>ProcessDirectoryEJB</code> manage the
* processes and activities of a contributor.
*
* @ejb.bean name="ProcessDirectory" display-name="ProcessDirectory"
* jndi-name="ejb/@@@_JNDI_Name_Prefix_@@@ProcessDirectory"
* type="Stateless" transaction-type="Container" view-type="both"
* @jonas.bean ejb-name="ProcessDirectory"
* @ejb.home
* remote-class="de.danet.an.workflow.ejbs.admin.ProcessDirectoryHome"
* local-class="de.danet.an.workflow.ejbs.admin.ProcessDirectoryLocalHome"
* @ejb.interface
* extends="javax.ejb.EJBObject, de.danet.an.workflow.apix.ExtProcessDirectory"
* remote-class="de.danet.an.workflow.ejbs.admin.ProcessDirectory"
* local-extends="javax.ejb.EJBLocalObject, de.danet.an.workflow.internalapi.ExtProcessDirectoryLocal"
* local-class="de.danet.an.workflow.ejbs.admin.ProcessDirectoryLocal"
* @ejb.ejb-ref ejb-name="WorkflowEngine" view-type="local"
* @ejb.ejb-ref ejb-name="ProcessDefinitionDirectory"
* view-type="remote"
* @ejb.ejb-ref ejb-name="ActivityBean" view-type="remote"
* @ejb.ejb-ref ejb-name="ProcessBean" view-type="remote"
* @ejb.ejb-ref ejb-name="ProcessBean" view-type="local"
* @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.resource-description
* res-ref-name="jdbc/WfEngine" jndi-name="DefaultDS"
* @ejb.transaction type="Required"
* @ejb.permission role-name="WfMOpenAdmin"
* @weblogic.enable-call-by-reference True
* @weblogic.transaction-isolation TRANSACTION_READ_COMMITTED
*/
public class ProcessDirectoryEJB implements SessionBean {

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

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

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

    private SessionFactory hibernateSessionFactory = null;

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

    /** The cached home interface of the activity EJB. */
    private WfActivityHome activityHomeCache = null;

    /** The cached home interface of the process EJB. */
    private WfProcessHome processHomeCache = null;
    private WfProcessLocalHome processLocalHomeCache = null;

    /**
     * This operation method delivers a WfActivity home interface.
     * @return home of ActivityBean
     * {@link de.danet.an.workflow.omgcore.WfProcess <code>WfActivity</code>}
     */
    private WfActivityHome activityHome()
  throws ResourceNotAvailableException {
  if (activityHomeCache == null) {
      activityHomeCache
    = (WfActivityHome)EJBUtil.retrieveEJBHome
    (WfActivityHome.class, "java:comp/env/ejb/ActivityBean");
  }
  return activityHomeCache;
    }

    /**
     * This operation method delivers a WFProcessHome interface.
     * @return home interface of WfProcessBean
     * {@link de.danet.an.workflow.omgcore.WfProcess <code>WfProcess</code>}
     */
    private WfProcessHome processHome() throws ResourceNotAvailableException {
  if (processHomeCache == null) {
      processHomeCache = (WfProcessHome)EJBUtil.retrieveEJBHome
    (WfProcessHome.class, "java:comp/env/ejb/ProcessBean");
  }
  return processHomeCache;
    }

    /**
     * This operation method delivers a WFProcessHome interface.
     * @return home interface of WfProcessBean
     * {@link de.danet.an.workflow.omgcore.WfProcess <code>WfProcess</code>}
     */
    private WfProcessLocalHome processLocalHome()
        throws ResourceNotAvailableException {
        if (processLocalHomeCache == null) {
            processLocalHomeCache = (WfProcessLocalHome)
                EJBUtil.retrieveEJBLocalHome
                (WfProcessLocalHome.class,
                 "java:comp/env/ejb/ProcessBeanLocal");
        }
        return processLocalHomeCache;
    }

    public void setSessionContext(SessionContext context)
  throws EJBException {
        ctx = context;
  activityHomeCache = null;
  processHomeCache = null;
  try {
      // getting new data source
      ds = JDBCUtil.refreshDS(null, DB_NAME);
            // prepare Hibernate
            hibernateSessionFactory
                = ((WorkflowEngineLocal)EJBUtil.createSession
                   (WorkflowEngineLocalHome.class,
                   "java:comp/env/ejb/WorkflowEngineLocal"))
                   .hibernateSessionFactory();
  } catch (NamingException e) {
      throw new EJBException(e);
        } catch (ResourceNotAvailableException e) {
            throw new EJBException(e);
        }
    }
   
    /**
     * 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 {
    }

    public void ejbRemove() {
  ds = null;
  activityHomeCache = null;
  processHomeCache = null;
  ctx = null;
    }

    /**
     * Create an new instance of ProcessDirectoryBean for the Contributor.
     * @throws CreateException Throws if the ProcessDirectoryBean can not
     * be create.
     */
    public void ejbCreate() throws CreateException {
  // Write your code here
    }

    /**
     * This operation method delivers a collection of process types
     * of created processes or an empty collection if no processes
     * are found.
     *
     * @return collection of process definition types as String objects
     * or an empty collection if no processes are found.
     * @ejb.interface-method
     * view-type="remote"
     */
    public Collection processMgrNames() {
        RequestScope scope = RequestLog.enterScope
            (this, "processMgrNames", (Object[])null);
        Collection definitionTypes = null;
        try {
            definitionTypes = new ArrayList();
            Connection con = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                try {
                    con = ds.getConnection();
                    String selectStatement
                        = "SELECT distinct processMgr FROM process";
                    stmt = con.createStatement();
                    rs = stmt.executeQuery(selectStatement);
                    while (rs.next()) {
                        String type = rs.getString(1);
                        definitionTypes.add(type);
                    }
                } finally {
                    JDBCUtil.closeAll (rs, stmt, con);
                }
            } catch (SQLException se) {
                throw new EJBException(se);
            }
        } finally {
            scope.leave(definitionTypes);
        }
        return definitionTypes;
    }

    /**
     * This operation method delivers a collection of process names
     * of created processes or an empty collection if no processes
     * are found.
     *
     * @return collection of process names as String objects
     * or an empty collection if no processes are found.
     * @ejb.interface-method
     * view-type="remote"
     */
    public Collection processNames() {
        Collection processNames = new ArrayList();
        RequestScope scope = RequestLog.enterScope
            (this, "processNames", (Object[])null);
        try {
            Connection con = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                con = ds.getConnection();
                String selectStatement
                    = "SELECT DISTINCT NAME FROM PROCESS ORDER BY NAME";
                stmt = con.createStatement();
                rs = stmt.executeQuery(selectStatement);
                while (rs.next()) {
                    String name = rs.getString(1);
                    processNames.add(name);
                }
            } finally {
                JDBCUtil.closeAll (rs, stmt, con);
            }
        } catch (SQLException se) {
            throw new EJBException(se);
        } finally {
            scope.leave (processNames);
        }
        return processNames;
    }

    /**
     * This operation method creates and delivers a collection of all
     * known processes. The objects of the collection are
     * remote interface of type
     * {@link de.danet.an.workflow.omgcore.WfProcess <code>WfProcess</code>}.
     * @return a Collection object
     * @ejb.interface-method
     * view-type="remote"
     */
    public Collection processes() {
        RequestScope scope = RequestLog.enterScope
            (this, "processes", (Object[])null);
        Collection res = null;
  try {
      res = processHome().findAll();
  } catch (ResourceNotAvailableException re) {
      throw new EJBException(re);
  } catch (FinderException ne) {
      throw new EJBException(ne);
  } catch (RemoteException re) {
      throw new EJBException(re);
  } finally {
      scope.leave (res);
  }
  return res;
    }

    public static class ProcessDirectoryRangeAccess
        implements RangeAccess, Serializable {

        private ExtProcessDirectory processDirectory;
        private byte[] filterData;
        private byte[] orderData;
       
        /**
         * Create a new instance with all attributes initialized
         * to defaults or the given values.
         * @param processDirectory
         * @param criteria
         * @param orderCriteria TODO
         */
        public ProcessDirectoryRangeAccess
            (ExtProcessDirectory processDirectory, byte[] filterData,
             byte[] orderData) {
            this.processDirectory = processDirectory;
            this.filterData = filterData;
            this.orderData = orderData;
        }

        /* (non-Javadoc)
         * Comment copied from interface or superclass.
         */
        public long itemCount() throws RemoteException {
            return processDirectory.processCount(filterData);
        }

        /* (non-Javadoc)
         * Comment copied from interface or superclass.
         */
        public List items(long start, long end) throws RemoteException {
            return processDirectory.processes
                (filterData, orderData, start, end);
        }
       
    }
   
    /**
     * This method returns an access object to an ordered set of
     * processes. The objects in the result are
     * remote interface of type
     * {@link de.danet.an.workflow.api.Process
     * <code>Process</code>}.
     *
     * @param filter a filter for the result
     * @param order the sort order for the result
     * @return access object to 
     * {@link de.danet.an.workflow.api.Process <code>Processes</code>}
     * @throws RemoteException if a system-level error occurs.
     */
    public RangeAccess processes (FilterCriterion filter, SortCriterion order)
        throws RemoteException {
        RequestScope scope = RequestLog.enterScope
            (this, "processes", new Object[] { filter, order });
        ProcessDirectoryRangeAccess res = null;
        try {
            Criterion filterCriteria = HibernateUtil.convertFilterCriterion(filter);
            List orderCriteria = new ArrayList();
            while (order != null) {
                String sortProp = order.getSortProperty();
                if (sortProp.equals("key")) {
                    sortProp = "dbId";
                }
                if (order instanceof AscendingOrder) {
                    orderCriteria.add(Order.asc(sortProp));
                } else {
                    orderCriteria.add(Order.desc(sortProp));
                }
                order = order.getSubCriterion();
            }
            // serialize (1) because criteria can only be used once and
            // (2) to avoid hibernate classes on client side
            byte[] filterData = null;
            byte[] orderData = null;
            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(bos);
                oos.writeObject(filterCriteria);
                oos.flush();
                oos.close();
                filterData = bos.toByteArray();
                bos = new ByteArrayOutputStream();
                oos = new ObjectOutputStream(bos);
                oos.writeObject(orderCriteria);
                oos.flush();
                oos.close();
                orderData = bos.toByteArray();
            } catch (IOException e) {
                throw (IllegalStateException)
                    (new IllegalStateException()).initCause(e);
            }
            res = new ProcessDirectoryRangeAccess
                ((ExtProcessDirectory)ctx.getEJBObject(),
                 filterData, orderData);
        } finally {
            scope.leave (res);
        }
        return res;
    }

    /**
     * Return the number of available processes considering the given
     * criteria.
     *
     * @param criteria the criteria for filtering
     * @return the result
     */
    public long processCount (byte[] filterData) {
        Criterion filterCriterion = null;
        try {
            ByteArrayInputStream bis
                = new ByteArrayInputStream(filterData);
            ObjectInputStream ois = new ObjectInputStream (bis);
            filterCriterion = (Criterion)ois.readObject();
        } catch (IOException e) {
            throw (IllegalArgumentException)
                (new IllegalArgumentException()).initCause(e);
        } catch (ClassNotFoundException e) {
            throw (IllegalArgumentException)
                (new IllegalArgumentException()).initCause(e);
        }
        RequestScope scope = RequestLog.enterScope
            (this, "processCount", new Object[] { filterCriterion });
        Session session = null;
        long result = 0;
        try {
            session = hibernateSessionFactory.openSession();
            Criteria curCrit = session.createCriteria(DAO.class);
            curCrit.setProjection(Projections.rowCount());
            if (filterCriterion != null) {
                curCrit.add(filterCriterion);
            }
            Object res = curCrit.uniqueResult();
            result = ((Number)res).longValue();
        } finally {
            if (session != null) {
                session.close();
            }
            scope.leave(new Long(result));
        }
        return result;
    }
   
    /**
     * Return a collection of processes based on the given criteria and limits.
     *
     * @param criteria the criteria
     * @param start the index of the first item
     * @param end the index of the last item
     * @return the collection
     */
    public List processes
        (byte[] filterData, byte[] orderData, long start, long end) {
        RequestScope scope = RequestLog.enterScope
            (this, "processes", new Object[]
             { filterData, orderData, new Long(start), new Long(end) });
        List res = null;
        try {
            res = (List)processHome().findRange
                (filterData, orderData, start, end);
        } catch (ResourceNotAvailableException re) {
            throw new EJBException(re);
        } catch (FinderException fe) {
            throw new EJBException(fe);
        } catch (RemoteException re) {
            throw new EJBException(re);
        } finally {
            scope.leave(res);
        }
        return res;
    }
   
    /**
     * This method finds the process identified by the given
     * type and key.
     *
     * @param processMgrName type of the given process.
     * @param processKey key of the process.
     * @return the process found.
     * @throws InvalidKeyException if no such process can be
     * found.
     * @ejb.interface-method
     * view-type="remote"
     */
    public de.danet.an.workflow.api.Process lookupProcess
  (String processMgrName, String processKey)
  throws InvalidKeyException {
        RequestScope scope = RequestLog.enterScope
            (this,"lookupProcess",new Object[] { processMgrName, processKey });
        de.danet.an.workflow.api.Process res = null;
  try {
      res = processHome().findByProcessKey(processKey);
  } catch (ObjectNotFoundException onfe) {
      ctx.setRollbackOnly();
            throw new InvalidKeyException
    ("No process of type = " + processMgrName + ", key = "
     + processKey + ": " + onfe.getMessage());
  } catch (ResourceNotAvailableException re) {
      throw new EJBException(re);
  } catch (FinderException fe) {
      throw new EJBException(fe);
  } catch (RemoteException re) {
      throw new EJBException(re);
  } finally {
      scope.leave(res);
  }
  return res;
    }

    /**
     * This method finds the process identified by the given
     * type and key.
     *
     * @param processMgrName type of the given process.
     * @param processKey key of the process.
     * @return the process found.
     * @throws InvalidKeyException if no such process can be
     * found.
     * @ejb.interface-method
     * view-type="remote"
     */
    public ProcessLocal lookupProcessLocal
        (String processMgrName, String processKey)
        throws InvalidKeyException {
        try {
            return processLocalHome().findByProcessKey(processKey);
        } catch (ObjectNotFoundException onfe) {
            ctx.setRollbackOnly();
            throw new InvalidKeyException
                ("No process of type = " + processMgrName + ", key = "
                 + processKey + ": " + onfe.getMessage());
        } catch (ResourceNotAvailableException re) {
            throw new EJBException(re);
        } catch (FinderException fe) {
            throw new EJBException(fe);
        } catch (RemoteException re) {
            throw new EJBException(re);
        }
    }

    /**
     * Return the processes requested by the given requester. This is
     * a helper method intended to be used when implementing a
     * <code>WfRequester</code>. Applications should use {@link
     * de.danet.an.workflow.omgcore.WfRequester#performers
     * <code>WfRequester.performers</code>} instead.
     * @param req the requester.
     * @return the processes created with the given requester.
     * @ejb.interface-method view-type="remote"
     */
    public Collection requestedBy (WfRequester req) {
  Collection res = new ArrayList ();
  try {
      Collection hashEqual
    = processHome().findByRequesterHash (req.hashCode());
      for (Iterator i = hashEqual.iterator (); i.hasNext();) {
    Process p = (Process)i.next ();
    if (p.requester().equals (req)) {
        res.add (p);
    }
      }
      return res;
  } catch (ResourceNotAvailableException re) {
      throw new EJBException(re);
  } catch (FinderException ne) {
      throw new EJBException(ne);
  } catch (RemoteException re) {
      throw new EJBException(re);
  }
    }

    /**
     * Removes the given process. The process can be removed, only and if only
     * it is in state "closed".
     *
     * @param process the process to remove.
     * @throws CannotRemoveException if the process cannot be removed,
     * because it is still in progress.
     * @ejb.interface-method view-type="remote"
     */
    public void removeProcess(de.danet.an.workflow.omgcore.WfProcess process)
  throws CannotRemoveException {
        RequestScope scope = RequestLog.enterScope
            (this, "remoceProcess", new Object[] { process });
  try {
      ((WfProcess)process).remove();
  } catch (RemoteException re) {
      throw new CannotRemoveException(re.getMessage());
  } catch (RemoveException re) {
      throw new CannotRemoveException(re.getMessage());
  } finally {
      scope.leave();
  }
    }
   
    /**
     * This method returns the activity identified be the given unique
     * key.
     *
     * @param key denotes the activity to be looked up.
     * @return the corresponding <code>Activity</code> value
     * @exception InvalidKeyException if the activity specified by
     * <code>key</code> cannot be found.
     * @ejb.interface-method
     * view-type="remote"
     */
    public Activity lookupActivity (ActivityUniqueKey key)
  throws InvalidKeyException {
        RequestScope scope = RequestLog.enterScope
            (this, "lookupActivity", new Object[] { key });
        Activity res = null;
  try {
      Long pk = Long.valueOf (key.activityKey());
      res = activityHome().findByPrimaryKey(pk);
  } catch (NumberFormatException nex) {
      ctx.setRollbackOnly();
      throw new InvalidKeyException ("Cause: " + nex.getMessage ());
  } catch (FinderException nex) {
      throw new InvalidKeyException ("Cause: " + nex.getMessage ());
  } catch (RemoteException nex) {
      throw new EJBException (nex);
  } finally {
      scope.leave (res);
  }
  return res;
    }   

    /**
     * This method finds the activity identified be the given unique
     * key and returns all available information about it.
     *
     * @param key denotes the activity to be looked up.
     * @return the corresponding <code>Activity.Info</code> value
     * @exception InvalidKeyException if the activity specified by
     * <code>key</code> cannot be found.
     * @ejb.interface-method
     * view-type="remote"
     */
    public de.danet.an.workflow.api.Activity.Info lookupActivityInfo
  (ActivityUniqueKey key) throws InvalidKeyException {
        RequestScope scope = RequestLog.enterScope
            (this, "lookupActivityInfo", new Object[] { key });
        de.danet.an.workflow.api.Activity.Info res = null;
  try {
      Long pk = Long.valueOf (key.activityKey());
      res = activityHome().findByPrimaryKey(pk).activityInfo();
  } catch (NumberFormatException nex) {
      ctx.setRollbackOnly();
      throw new InvalidKeyException ("Cause: " + nex.getMessage ());
  } catch (FinderException nex) {
      throw new EJBException (nex);
  } catch (RemoteException nex) {
      throw new EJBException (nex);
  } finally {
      scope.leave (scope);
  }
  return res;
    }   

}
TOP

Related Classes of de.danet.an.workflow.ejbs.admin.ProcessDirectoryEJB

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.