/*
* Copyright 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.web;
import org.apache.agila.engine.Engine;
import org.apache.agila.engine.EngineMessage;
import org.apache.agila.engine.InstanceID;
import org.apache.agila.engine.MessageProcessor;
import org.apache.agila.impl.EngineMessageImpl;
import org.apache.agila.impl.QueueServiceImpl;
import org.apache.agila.impl.servlet.ActionServlet;
import org.apache.agila.impl.memory.TimerServiceImpl;
import org.apache.agila.impl.memory.InstanceServiceImpl;
import org.apache.agila.impl.memory.BusinessProcessServiceImpl;
import org.apache.agila.impl.memory.TaskServiceImpl;
import org.apache.agila.impl.memory.NotificationServiceImpl;
import org.apache.agila.impl.memory.UserServiceImpl;
import org.apache.agila.impl.memory.TokenServiceImpl;
import org.apache.agila.model.BusinessProcessID;
import org.apache.agila.model.Variable;
import org.apache.agila.services.BusinessProcessInfo;
import org.apache.agila.services.InstanceInfo;
import org.apache.agila.services.notification.NotificationID;
import org.apache.agila.services.task.HTTPRenderer;
import org.apache.agila.services.task.HTTPResponseHandler;
import org.apache.agila.services.task.Renderer;
import org.apache.agila.services.task.ResponseHandler;
import org.apache.agila.services.task.ResponseHandlerResponse;
import org.apache.agila.services.task.Task;
import org.apache.agila.services.task.TaskID;
import org.apache.agila.services.TokenService;
import org.apache.agila.services.log.LogService;
import org.apache.agila.services.user.UserID;
import org.apache.agila.services.user.UserInfo;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
public class AgilaServlet extends ActionServlet implements LogService {
public static final String HTTP_ACTION_VERB = "action";
private TokenService tokenService = null;
private InstanceServiceImpl eiSvc = null;
private BusinessProcessServiceImpl graphManager = null;
private TaskServiceImpl taskService = null;
private TimerServiceImpl timerService = null;
private MessageProcessor impl = null;
private QueueServiceImpl qs = null;
private Engine engine = null;
private NotificationServiceImpl notifyService = null;
private UserServiceImpl userService = null;
public void init() throws ServletException {
super.init();
this.tokenService = new TokenServiceImpl();
this.eiSvc = new InstanceServiceImpl();
this.graphManager = new BusinessProcessServiceImpl();
this.taskService = new TaskServiceImpl();
this.timerService = new TimerServiceImpl();
this.notifyService = new NotificationServiceImpl();
this.userService = new UserServiceImpl();
//for temporary user to test user preference
UserInfo user = new UserInfo("user", "user", "user",false);
user.setUserID(new UserID( 1 ));
this.userService.addUser(user);
taskService.setTokenService(tokenService);
taskService.setInstanceService(eiSvc);
taskService.setBusinessProcessService(graphManager);
this.impl = new MessageProcessor();
this.impl.setTaskService( taskService );
this.impl.setTimerService( timerService );
this.impl.setExecutionInstanceService( eiSvc );
this.impl.setTokenService( tokenService );
this.impl.setBusinessProcessService( graphManager );
this.impl.setNotificationService( notifyService );
impl.setLogService(this);
this.qs = new QueueServiceImpl( impl );
timerService.setQueueService( qs );
impl.setQueueService( qs );
eiSvc.setBusinessProcessService( graphManager );
eiSvc.setQueueService( qs );
eiSvc.setTokenService( tokenService );
/*
* now start the message pump for processing since we are all ready
*/
qs.start();
engine = new Engine( tokenService, eiSvc, graphManager, qs );
Reader reader = new InputStreamReader( getClass().getClassLoader().getResourceAsStream( "LeaveApplication.xml" ) );
engine.addBusinessProcess( reader );
}
protected String getActionVerb() {
return (HTTP_ACTION_VERB);
}
/**
* Called when there is no action specified
*/
public void defaultAction( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
if( request.isUserInRole( "admin" ) ) {
show_process_list( request, response );
return;
} else if( request.isUserInRole( "user" ) ) {
show_task_list(request, response);
return;
}
doRender( request, response );
}
public void upload_submit( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException {
String xml = req.getParameter( "xml" );
System.out.println( "upload_submit : " + xml );
engine.addBusinessProcess( new StringReader( xml ) );
show_process_list( req, res );
}
public void upload_process( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
request.setAttribute( "pageToDisplay", "/WEB-INF/view/uploadprocess.jsp" );
doRender( request, response );
}
public void show_process_list( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
IOException {
List l = graphManager.getCurrentProcessInfos();
request.setAttribute( "list", l );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/processlist.jsp" );
doRender( request, response );
}
public void show_notification_list( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
IOException {
List notificationList = null;
try {
notificationList = notifyService.getNotificationsForUser( new UserID( 1 ) );
} catch( Exception e ) {
// Do nothing. notification list is empty
}
request.setAttribute( "list", notificationList );
request.setAttribute( "notifyService", notifyService );
request.setAttribute( "graphManager", graphManager );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/notificationlist.jsp" );
doRender( request, response );
}
public void show_user_preference( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
IOException {
UserInfo user = userService.getUserInfo(new UserID (1));
request.setAttribute( "email", user.getProperty("EMAIL_ADDRESS"));
request.setAttribute( "graphManager", graphManager );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/userpreference.jsp" );
doRender( request, response );
}
public void save_user_preference( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
IOException {
UserInfo user = userService.getUserInfo(new UserID (1));
user.setProperty("EMAIL_ADDRESS",request.getParameter("txtEmail")) ;
userService.saveUser(user);
show_user_preference( request, response );
}
public void show_task_list( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
List taskList = null;
try {
taskList = taskService.getTasksForUser( new UserID( 1 ), Task.TASK_INCOMPLETE );
} catch( NullPointerException e ) {
// Do nothing. task list is empty
}
request.setAttribute( "list", taskList );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/tasklist.jsp" );
doRender( request, response );
}
public void show_instance_list( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
IOException {
List l = eiSvc.listInstanceInfo();
request.setAttribute( "list", l );
request.setAttribute( "tokenService", tokenService );
request.setAttribute( "graphManager", graphManager );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/instancelist.jsp" );
doRender( request, response );
}
public void start_process_instance( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
IOException {
String name = request.getParameter( "name" );
BusinessProcessID proc = graphManager.getGraphIDByName(name);
BusinessProcessInfo businessProcessInfo = graphManager.getInfoByID( proc );
List requiredVariables = businessProcessInfo.getRequiredVariables();
if( requiredVariables.size() > 0 ) {
request.setAttribute( "processName", name );
request.setAttribute( "businessProcessID", new Integer( proc.getID() ) );
request.setAttribute( "variables", requiredVariables );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/initVars.jsp" );
} else {
startNewInstance( request, proc, name, new HashMap());
request.setAttribute( "pageToDisplay", "/WEB-INF/view/startedprocess.jsp" );
}
doRender( request, response );
}
public void start_process_instance_with_variables( HttpServletRequest request,
HttpServletResponse response ) throws ServletException, IOException {
BusinessProcessID businessProcessID = new BusinessProcessID( Integer.parseInt( request.getParameter( "businessProcessID" ) ) );
BusinessProcessInfo businessProcessInfo = graphManager.getInfoByID( businessProcessID );
// Retrieve the list of variables to know which parameter names to retrieve.
// TODO probably there's a better way to do this. A call to getRequiredVariables() slows down the system.
List requiredVariables = businessProcessInfo.getRequiredVariables();
Map appParams = new HashMap();
for( Iterator iterator = requiredVariables.iterator(); iterator.hasNext(); ) {
Variable variable = (Variable)iterator.next();
String name = variable.getName();
String value = request.getParameter( name );
appParams.put( name, value );
}
startNewInstance( request, businessProcessID, request.getParameter( "processName" ), appParams );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/startedprocess.jsp" );
doRender( request, response );
}
private void startNewInstance( HttpServletRequest request,
BusinessProcessID businessProcessID, String name, Map appParams ) {
InstanceID instanceID = engine.startNewInstance( businessProcessID.getID(), appParams );
request.setAttribute( "iid", instanceID );
request.setAttribute( "processName", name );
}
public void nudge_from_task( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
Task t = taskService.getTaskByID( new TaskID( Integer.parseInt( request.getParameter( "taskid" ) ) ) );
engine.nudge( t.getSourceTokenID() );
taskService.setTaskStatus( t.getTaskID(), Task.TASK_COMPLETE );
show_task_list( request, response );
}
public void do_task( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
Task t = taskService.getTaskByID(
new TaskID(Integer.parseInt(request.getParameter("taskid"))));
Renderer renderer = taskService.getRendererForTask(t.getTaskID(), HTTPRenderer.class);
if (renderer != null) {
if (renderer instanceof HTTPRenderer ) {
String renderData = ((HTTPRenderer) renderer).render(request, response);
request.setAttribute( "form", renderData );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/taskFormDisplay.jsp" );
doRender(request, response);
return;
}
}
show_task_list(request, response);
}
public void submit_task_info(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
TaskID tid = new TaskID(Integer.parseInt(request.getParameter("taskid")));
ResponseHandler handler = taskService.getResponseHandlerForTask(tid,
HTTPResponseHandler.class);
if (handler != null) {
if (handler instanceof HTTPResponseHandler) {
ResponseHandlerResponse rhr =
((HTTPResponseHandler) handler).processAction(request, response);
/*
* package data and send into engine
*/
if (rhr.isAbleToContinue()) {
/*
* queue a message for this instance
*/
EngineMessage em = new EngineMessageImpl();
em.setMessageType(EngineMessage.TYPE_MOVE_TOKEN);
em.setCurrentTokenID(rhr.getTokenID());
em.addAppData(rhr.getActivityDataName(), rhr.getActivityData());
qs.enqueue(em);
/*
* TODO - is this the right place?
*
* mark the task as complete
*/
taskService.setTaskStatus(tid, Task.TASK_COMPLETE);
}
}
}
// A hack. Wait for the sleeping thread to wake up and finish execution.
// What if we will use wait/notify instead?
try {
Thread.sleep( 1000 );
} catch( InterruptedException e ) {}
show_task_list(request,response);
}
public void dismiss_from_list( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
IOException {
notifyService.dismissNotification( new NotificationID( Integer.parseInt( request.getParameter( "notifyid" ) ) ) );
show_notification_list( request, response );
}
public void user_logout( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
IOException {
request.getSession().invalidate();
response.sendRedirect(request.getRequestURL().toString());
}
/**
* Stop the instance. Only applicable to running instances.
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void stop_instance( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
InstanceID instanceID = new InstanceID( Integer.parseInt( request.getParameter( "instanceid" ) ) );
engine.stop( instanceID );
List l = eiSvc.listInstanceInfo();
request.setAttribute( "list", l );
request.setAttribute( "tokenService", tokenService );
request.setAttribute( "graphManager", graphManager );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/instancelist.jsp" );
doRender( request, response );
}
public void detail_instance( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
InstanceID instanceID = new InstanceID( Integer.parseInt( request.getParameter( "instanceid" ) ) );
InstanceInfo info = eiSvc.getInstanceInfoByID(instanceID);
request.setAttribute( "instance", info );
request.setAttribute( "graphManager", graphManager );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/instancedetail.jsp" );
doRender( request, response );
}
/**
* Suspend the instance. Only applicable to running instances.
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void suspend_instance( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
InstanceID instanceID = new InstanceID( Integer.parseInt( request.getParameter( "instanceid" ) ) );
engine.suspend( instanceID );
List l = eiSvc.listInstanceInfo();
request.setAttribute( "list", l );
request.setAttribute( "tokenService", tokenService );
request.setAttribute( "graphManager", graphManager );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/instancelist.jsp" );
doRender( request, response );
}
/**
* Resume the instance. Only applicable to suspended instances.
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void resume_instance( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
InstanceID instanceID = new InstanceID( Integer.parseInt( request.getParameter( "instanceid" ) ) );
engine.resume( instanceID );
List l = eiSvc.listInstanceInfo();
request.setAttribute( "list", l );
request.setAttribute( "tokenService", tokenService );
request.setAttribute( "graphManager", graphManager );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/instancelist.jsp" );
doRender( request, response );
}
/**
* Display the list of users
*/
public void show_user_list( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
List userList = userService.listAllUserInfo();
request.setAttribute( "userlist", userList );
request.setAttribute( "pageToDisplay", "/WEB-INF/view/userlist.jsp" );
doRender( request, response );
}
/**
* Called when the action specified is not found
*
* @param req
* @param res
* @throws javax.servlet.ServletException
* @throws java.io.IOException
*/
public void unknownAction( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException {
// TODO Auto-generated method stub
}
/**
* Render the JSP page
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void doRender( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
String pageToDisplay = "errorPage.jsp";
if( request.isUserInRole( "admin" ) ) {
pageToDisplay = "/WEB-INF/view/adminmenu.jsp";
} else if( request.isUserInRole( "user" ) ) {
pageToDisplay = "/WEB-INF/view/usermenu.jsp";
}
RequestDispatcher requestDispatcher = request.getRequestDispatcher( pageToDisplay );
requestDispatcher.forward( request, response );
}
public boolean isInfoEnabled() {
return false;
}
public void info(Object msg) {
log(msg.toString());
}
public void info(Object msg, Throwable t) {
log(msg.toString(), t);
}
public boolean isDebugEnabled() {
return false;
}
public void debug(Object msg) {
log(msg.toString());
}
public void debug(Object msg, Throwable t) {
log(msg.toString(), t);
}
public boolean isErrorEnabled() {
return false;
}
public void error(Object msg) {
log(msg.toString());
}
public void error(Object msg, Throwable t) {
log(msg.toString(), t);
}
}