/**
*
* Copyright 2003-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.agila.impl.hibernate;
import org.apache.agila.engine.Instance;
import org.apache.agila.engine.InstanceID;
import org.apache.agila.engine.Token;
import org.apache.agila.engine.TokenID;
import org.apache.agila.impl.BusinessProcessImpl;
import org.apache.agila.impl.InstanceImpl;
import org.apache.agila.impl.TokenImpl;
import org.apache.agila.impl.dao.AgilaDAO;
import org.apache.agila.model.BusinessProcess;
import org.apache.agila.model.BusinessProcessID;
import org.apache.agila.model.NodeID;
import org.apache.agila.services.InstanceInfo;
import org.apache.agila.services.InstanceServiceInfo;
import org.apache.agila.services.task.Task;
import org.apache.agila.services.task.TaskID;
import org.apache.agila.services.task.TaskImpl;
import org.apache.agila.services.user.GroupID;
import org.apache.agila.services.user.UserID;
import org.apache.agila.services.user.UserInfo;
import org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* @version $Revision: 66 $
*/
public class HibernateDAO extends HibernateDaoSupport implements AgilaDAO {
private int maxAttempts = 30;
private long sleepTime = 2000;
public HibernateDAO() {
}
public BusinessProcessID addGraph(BusinessProcess graph) {
getHibernateTemplate().save(graph);
return graph.getBusinessProcessID();
}
public BusinessProcess getGraphByID(BusinessProcessID id) {
return (BusinessProcess) getHibernateTemplate().load(BusinessProcessImpl.class, new Integer(id.getID()));
}
public List getAllProcessGraphs() {
return getHibernateTemplate().loadAll(BusinessProcessImpl.class);
}
public BusinessProcessID getGraphIDByName(String name) {
List list = getHibernateTemplate().find("from BusinessProcessImpl b where b.name = ?", name);
if (list.isEmpty()) {
return null;
}
else {
BusinessProcess process = (BusinessProcess) list.get(0);
return process.getBusinessProcessID();
}
}
public Instance newInstance(BusinessProcessID processID, Map params) {
InstanceImpl answer = new InstanceImpl();
answer.setBusinessProcessID(processID);
answer.setInstanceVariables(params);
getHibernateTemplate().save(answer);
getHibernateTemplate().flush();
return answer;
}
public void saveInstance(Instance instance) {
// we might have updated the variables directly, so lets reset them just in case
instance.setInstanceVariables(instance.getInstanceVariables());
getHibernateTemplate().saveOrUpdate(instance);
getHibernateTemplate().flush();
}
public Instance getInstanceByID(InstanceID id) {
return (Instance) getHibernateTemplate().load(InstanceImpl.class, new Integer(id.getID()));
}
public List listInstanceInfo() {
List list = getHibernateTemplate().loadAll(InstanceImpl.class);
List answer = new ArrayList(list.size());
for (Iterator iter = list.iterator(); iter.hasNext();) {
InstanceImpl instance = (InstanceImpl) iter.next();
InstanceInfo info = new InstanceInfo(instance);
answer.add(info);
}
return answer;
}
public InstanceServiceInfo getInstanceServiceInfo() {
// TODO could do this with a single SQL statement...
int stopped = 0;
int suspended = 0;
int running = 0;
int completed = 0;
List instances = getHibernateTemplate().loadAll(InstanceImpl.class);
for (Iterator iter = instances.iterator(); iter.hasNext();) {
InstanceImpl instance = (InstanceImpl) iter.next();
int status = instance.getStatus();
switch (status) {
case Instance.STATUS_STOPPED:
stopped++;
break;
case Instance.STATUS_SUSPENDED:
suspended++;
break;
case Instance.STATUS_RUNNING:
running++;
break;
case Instance.STATUS_COMPLETE:
completed++;
break;
}
}
return new InstanceServiceInfo(running, suspended, stopped,
completed);
}
public TaskID updateTask(Task task) {
getHibernateTemplate().update(task);
return task.getTaskID();
}
public TaskID insertTask(Task task) {
getHibernateTemplate().save(task);
return task.getTaskID();
}
public boolean saveToken(Token token) {
getHibernateTemplate().save(token);
return true;
}
public Token newToken(InstanceID instanceID, NodeID nodeID, int state) {
TokenImpl answer = new TokenImpl();
answer.setInstanceID(instanceID);
answer.setCurrentNodeID(nodeID);
answer.setCurrentState(state);
getHibernateTemplate().save(answer);
getHibernateTemplate().flush();
if (logger.isDebugEnabled()) {
logger.debug("Created a new Token with ID: " + answer.getTokenID());
}
return answer;
}
public Token getTokenByID(TokenID id) {
// lets retry as the new workflow might not have been comitted yet
/*
HibernateObjectRetrievalFailureException lastException = null;
for (int i = 0; i < maxAttempts; i++) {
if (i > 0) {
// lets try sleep a while
logger.info("Retrying, attempt: " + i + ". Sleeping for: " + sleepTime + " milli(s)");
System.out.println("Retrying, attempt: " + i + ". Sleeping for: " + sleepTime + " milli(s)");
try {
Thread.sleep(sleepTime);
}
catch (InterruptedException e) {
logger.warn("Our thread was just interupted trying to sleep: " + e, e);
}
// now lets force a flush and evict
getHibernateTemplate().flush();
}
try {
return (Token) getHibernateTemplate().load(TokenImpl.class, new Integer(id.getID()));
}
catch (HibernateObjectRetrievalFailureException e) {
lastException = e;
logger.info("Caught token not exist exception: "+ e);
}
}
throw lastException;
*/
return (Token) getHibernateTemplate().load(TokenImpl.class, new Integer(id.getID()));
}
public UserInfo getUserFromPrincipal(String principle) {
List list = getHibernateTemplate().find("from UserInfo b where b.userPrincipal = ?", principle);
if (list.isEmpty()) {
return null;
}
else {
return (UserInfo) list.get(0);
}
}
public UserInfo getUserInfo(UserID id) {
return (UserInfo) getHibernateTemplate().load(UserInfo.class, new Integer(id.getID()));
}
public UserID addUser(UserInfo newUser) {
getHibernateTemplate().save(newUser);
return newUser.getUserID();
}
public List listAllUserInfo() {
return getHibernateTemplate().loadAll(UserInfo.class);
}
public void saveUser(UserInfo info) {
getHibernateTemplate().update(info);
}
public List getTasksForInstance(InstanceID id, int status) {
List answer = new ArrayList();
List tasks = getHibernateTemplate().find("from TaskImpl t where t.instanceKey = ?", new Integer(id.getID()));
for (Iterator iter = tasks.iterator(); iter.hasNext();) {
TaskImpl task = (TaskImpl) iter.next();
if (status == Task.TASK_ALL || task.getStatus() == status) {
answer.add(task);
}
}
return answer;
}
public int setTaskStatusForInstance(InstanceID id, int oldStatus, int newStatus) {
List tasks = getTasksForInstance(id, oldStatus);
for (Iterator iter = tasks.iterator(); iter.hasNext();) {
TaskImpl task = (TaskImpl) iter.next();
task.setStatus(newStatus);
}
getHibernateTemplate().flush();
return tasks.size();
}
public List getTasksForUser(UserID id, int status) {
if (status == Task.TASK_ALL) {
return getHibernateTemplate().find("from TaskImpl t where t.userKey = ?", new Integer(id.getID()));
}
else {
return getHibernateTemplate().find("from TaskImpl t where t.userKey = ? and status = ?", new Object[]{new Integer(id.getID()), new Integer(status)});
}
}
public Task getTaskByID(TaskID id) {
return (Task) getHibernateTemplate().load(TaskImpl.class, new Integer(id.getID()));
}
public boolean lockTaskForUser(TaskID id, UserID userID) {
Task task = getTaskByID(id);
if (task != null && !userID.equals(task.getUserID())) {
task.setUserID(userID);
getHibernateTemplate().flush();
return true;
}
return false;
}
public void unlockTaskForUser(TaskID id, UserID userID) {
Task task = getTaskByID(id);
if (task != null && userID.equals(task.getUserID())) {
task.setUserID(null);
getHibernateTemplate().flush();
}
}
public List getActiveTokensForInstance(InstanceID id) {
return getHibernateTemplate().find("from TokenImpl t where t.instanceKey = ? and t.currentState = 1", new Integer(id.getID()));
}
public List getTasksForGroups(GroupID[] groupIDs, int status) {
StringBuffer buffer = new StringBuffer("from TaskImpl t where t.groupKey in (");
for (int i = 0; i < groupIDs.length; i++) {
GroupID groupID = groupIDs[i];
if (i > 0) {
buffer.append(", ");
}
buffer.append(Integer.toString(groupID.getID()));
}
buffer.append(")");
if (status != Task.TASK_ALL) {
buffer.append(" and t.status = " + status);
}
return getHibernateTemplate().find(buffer.toString());
}
}