Government Services Infrastructure - GSi |
|
Application developer considerations
PrefaceForewordThis document tries to be a guide to start developing your applications on GSi. This document attempts to cover all the activities a developer would do when using GSi to build their own applications over it. This document covers how to build application using Java as the development language. Though the client communication mechanism uses Webservices, building applications using other languages is not covered here. We hope that you find this document useful, and we look forward to your comments. Intended audienceAny one who is going to develop applications over GSi would find this document useful. This document is not intended to explain the usage of GSi in general. Please refer to GSi User’s Guide about GSi usage. By reading this document, you will learn how to develop vertical applications over GSi. It will hopefully guide you around some of the common problems that frequently occur for new (and sometimes even advanced) developers of GSi. A developer who is reading this document is expected to know the following: · How to use & troubleshoot webservices for client communications · How to use java, to develop applications, well · How to use databases from java applications (optional) · How to use Application Server · Understand workflow concepts (recommended) Conventions followedCommands are written in fixed width font.
Guide are text relevant at the point of discussion but are discussed else where in detail.
Code snippets are written in fixed width font with a grey background. Tips are features that help overcome a possible usability issue.
Obtaining the latest copyThe latest copy of this documentation can be obtained on request from sales_gsi[AT]comat.com in PDF A4 format. Providing FeedbackShould you have any feedback about this document, please send it to dev_gsi[AT]comat.com Sources and referencesDocumentationOther resources that are associated with this document are: · User’s guide · Administrator’s guide · Installation guide · Tools user’s guides TrademarksGSi is a of Comat Technologies P Ltd. OverviewGovernment Services Infrastructure (GSi) is a unified technology platform which empowers government/business processes to be modeled, deployed, executed and managed in an intuitive and efficient manner.
GSi is based on open standards and is platform neutral. It helps to model, deploy and manage the Government processes and services. It is the bridge between Government functions and technology where users can design services in their own terminology namely, Social Welfare Department (SWD), Public Distribution System, Urban and Rural welfare, Rural Digital Services (RDS), Food and Civil supplies to name a few. Definitions• Process / Business Process – A set of connected and coordinated activities that accomplish a business goal • Ex. Process Order, Recruitment, SWD Scheme • Business Rules – Business rules are programmatic implementations of the policies and practices of a business organization • Ex. Scheme Approval for APL/BPL, Move to OLPS if age > 60 • Activity – A step that contributes to the completion of a process • Manual Activity – The manual step that contributes to the completion of a process. Activity with user intervention. • Ex. Approval, Feedback • Automated Activity – The automated step that contributes to the completion of a process. Activity with code “automated “and runs with no user intervention. • Ex. Send Offer Letter by Mail, Generate Employee Id • Vertical – Group of logical related processes. Like Social Welfare Department (SWD) with its schemes and other internal departments process, RDS with all the services it renders and the service processing • Workflow – The computerized facilitation or automation of a process, in whole or part • Process Definition (Process) – A coordinated set of automated and manual activities in computer understandable format • Sub-Process – A sub-process is nothing but a sequence of activities grouped together and this becomes a part of larger process (parent process). Complex processes can be simplified by breaking them in logical sub-processes and using them to achieve the complex/large process. • ActivitySet – Logical group of activities clubbed together to form a transaction block • Compensation – A set of activities (identified by an ActivitySet) can run in an all or none mode. An activity in this set can fail. If this happens, then the activities preceding this one in the activity set needs to be rolled-back and the set should be re-executed without affecting the process state. This rollback is called compensation which is achieved by executing the compensation logic of activities in the reverse direction of activity set • Task (Task Item) – A unit of work that needs to be performed by a user • Task List – A set of Tasks logically grouped based on Role/Org. Unit/Organization • Process Instance – Represents an instance of a process definition • Activity Instance – Represents an instance of a manual or automated activity • Transition – Link/Association connecting two activities
Where to findAfter installation (using the Installation Guide) you should be able to find and start Process Modeling tool, Vertical Generator and Admin tool. We will use these three tools to build our applications. The physical organization of the distribution is discussed in the Installation Guide. RequirementsServerServer requirements are covered in Installation Guide. ClientThe vertical application that intends to communicate with GSi should be able to use Webservices. These webservices API wrapped around in a set of Java classes to ease the usage of communication with the server. All client tools require JRE 1.4.2 or higher to be installed. Additionally to develop, compile and package application JDK 1.4.2 or higher is required on the client system. Relevant jars required for client are distributed when code generation happens using Vertical Generator. The jars that are included are: · axis.jar – Axis from Apache to communicate over webservices. Refer to ws.apache.org/axis/ for details. · axis-ant.jar – Ant task for using axis in build files. · commons-discovery.jar – Required by Axis. Refer to jakarta.apache.org/commons/ for details. · commons-logging.jar – Required by Axis for logging. Refer to jakarta.apache.org/commons/ for details. · jaxrpc.jar – Required by Axis. · wsdl4j.jar – Required by Axis. · saaj.jar – Required by Axis for handling attachments. · jdom.jar – Required by Axis and GSi Task Interface. · log4j-1.2.8.jar – Logger implementation used by commons-logging. Recommended for logging. · taglibs-i18n.jar – Required by web-based clients for internationalization. GSi generated code uses it. · gsitaskinf.jar – GSi task interface client API. Required to communicate with GSi for web-based client. · VerticalClientApi.jar – Client API. Required to communicate with GSi. · l2fprod-common-all.jar – Swing look and feel component. Used by GSi swing client. Optional. Setting upThe installation guide will have provided information on how the distribution is organized and where what is available. It would have also helped you install the application onto an Application Server. You will require the tools to generate and work with the application. And also familiarity with the Application server for deploying custom built libraries. This deployment is restricted to adding the libraries to classpath of the Application Server for GSi to be able to access it. There is no other special setup required, apart from being able to code, compile and package Java files for which utilities are already provided with JDK1.4.2. A vertical is composed of processes that are modeled using the modeling tool. Each process consists to a set of activities. Activities are of the following types: Automated, Manual, Split/ Joins, Sub process, Start/ Stop. For detailed information on how to model processes refer to Modeling tool user’s guide. We will concentrate on Automated and Manual activities and also use Splits to process manipulate routes.
Application developer considerationsThe steps creating a new application over GSi are listed below. Some of the steps are not mandatory, but we suggest going through them to understand the various options available when developing the application. Also refer to appendix for code samples. VerticalCreate a new vertical for your needs using Admin tool. Refer to admin tool user’s guide on how to do the same. The user profile (Users, Roles, Groups and Privileges) information for the vertical set of users can be maintained within GSi (Managed Vertical) and with the vertical (Unmanaged Vertical). In either case, define the groups / departments/ business unit and relevant roles using the Admin tool in case of managed vertical or custom vertical interfaces in case of unmanaged vertical. In case of unmanaged vertical, develop the UPM related implementation classes and deploy the same to GSi. Once this is once, the vertical and its user profile is available in the Modeler tool for process modeling.
ProcessesUse modeling tool to create processes and deploy them using Admin tool. Refer to Modeling tool user’s guide and Admin tool user’s guide on how to do the same. Note on process exception policies While modeling the exception policy for the process can be specified. The following three policies are supported; · Abort on Exception o If this policy is selected, in case of any unhandled exception (not specified in any of the alternate paths) within the process, the process aborts and cannot be restarted. · Retry on Exception o If this policy is selected, in case of any unhandled exception (not specified in any of the alternate paths) within the process, the failed activity is retried ‘n’ of times specified as retry count and within the retry interval. If the activity fails to succeed after the retries, the process is aborted. · Stop/Suspend on Exception o If this policy is selected, in case of any unhandled exception (not specified in any of the alternate paths) within the process, the process suspends and can be restarted. The suspended process can restart thru the Monitoring Tool with/without skipping the failed activity. In case of skipping of the failed activities, the outputs (if any) of the failed activity needs to be provided. The selection of the process exception policy will mostly depend on the process specific requirements and also on the tolerance of the activities (automated and manual) within the process. The developer while writing code for activity (mostly automated and in some cases of the vertical side manual activity code) needs to be aware of the way in which the activities need to behave for retries and for restart from suspended state. Auto generating codeStart the process modeling tool. The process modeling tool can be started by executing run.bat (on Windows) or run.sh (on Unix) from tools/modeler directory of the distribution. Contact GSi Administrator to acquire appropriate Modeling tool privileges. Open one process at a time, by double clicking on process on the left tree panel. Save all the processes that are related to the vertical we are developing, to the local disk at a location of your choice. Close the modeling tool. Now start the vertical generator tool. The vertical generator tool can be started by executing run.bat (on Windows) or run.sh (on Unix) from tools/vgenerator directory of the distribution. This is a standalone tool and does not require any network connections to work. Now click the new button [IMAGE] on the tool bar or choose File -> New. A wizard will start up to guide you through the generation. Provide process definition xml (saved from the modeling tool) and a destination directory which this tool will use to place generated code. Select overwrite if you want to overwrite any previously existing code that was generated before (on a file by file basis). Click next. A list of automated activities for the process will be displayed. Click on the selection check box against each of the activities. You will want to Select All for the first time. Subsequently only modified/ newly added activities could be chosen. Click next. A list of manual activities for the process will be displayed. Click on the selection check box against each of the activities. You will want to Select All for the first time. Subsequently only modified/ newly added activities could be chosen. Manual activities require user intervention to complete the activity. Choose want kind of User interface you will want to provide to the user either: Swing or Web. For swing based user interface type the package name for the code that will be generated. Click next. Summary of the choices you made in the previous screens is displayed. To proceed with code generation click Finish, to change information in the previous screens click back, to quit without generating any code click cancel. The vertical generator generates, on clicking Finish, utmost two directories _aa (for automated activities) and _swing or _web (depending on what choice you made for manual activities) in the destination directory chosen. Skeleton code for the selected activities will be in the directories. Repeat the above steps for each of the process xmls that for the vertical. You can choose the same destination directory for all the processes Now you are ready to code away. DeployingCompile the java files and make a jar of the automated classes. You should also be able to find the classpath for applications deployed on the Application server where GSi is installed, and to be able to add new libraries (usually jar files) to that classpath. For JBoss: this is usually %JBOSS_HOME%/server/default/lib Adding the newly built libraries into this directory and restarting JBoss server (using %JBOSS_HOME%/bin/shutdown.bat and %JBOSS_HOME%/bin/run.bat) will let GSi find these new libraries. Remember to add any other third party libraries (like database driver jar etc) the original library depends on, into the same directory. Automated activitiesActivities execute as single unit of task. Automated activities are of two types: simple and compensative. Simple activities do not support roll back on event of failure. SimpleAll automated activities must implement com.comat.gsi.utility.GenericActivity Interface. They need to have a public constructor that takes no parameters (also called the default constructor) such that GSi can create an instance of this class. To implement the interface the method: void execute(ProcessContext context) throws Exception needs to be given a concrete implementation. You can execute your business logic here. Information from one activity to another is carried over in the context. ProcessContext supports only java.lang.String to be stored in it. Hence implying that database connections cannot be carried over the next activity. You will have to create, use and close a database connection inside the execute method. To support rollback use a compensative activity. With ProcessContext you can retrieve information from the context using getAttributeValue method. This information is what the previous activity had stored in the processes context or what was stored during process kick off. You can put information into the context using putAttributeValue method. Make sure you put all the information required by the activity as outputs as defined in the process definition using the modeler. If all the mandatory outputs of an activity are not put/added to the context, the activity execution will fail at runtime with an error “Required Activity outputs are not generated”. Once this happens, the process execution will behave based on the process exception policy selected. For eg, if “Abort on Exception” policy is selected the process instance will abort. You can set error conditions in the ProcessContext using setErrorOccured(String name, String description) method. This name provided is used to match any alternate paths in the process definition, and if any match is found that path is takenThe method supports exceptions to be thrown. But we suggest you to try-catch the exception and set using setErrorOccured method. When an exception is thrown, the exception class name is automatically set as the errorOccured. And as with any other errorOccured name alternate path is attempted to be chosen. If no match/alternate path is found, the process execution will behave based on the process exception policy selected. For e.g., if “Abort on Exception” policy is selected the process instance will abort. CompensativeAll compensative automated activities must implement com.comat.gsi.utility.CompensativeActivity interface. They need to have a public constructor that takes no parameters (also called the default constructor) such that GSi can create an instance of this class. This has an extra method over GenericActivity, the method is: void compensate(ProcessContext oldProcessContext, ProcessContext newProcessContext) Compensate is called by GSi when a roll back of the ActivitySet happens. This method should not throw any exceptions. If this method throws any exception, the process aborts. The parameter oldProcessContext is the context state that the execute method had obtained during its forward course of execution. The parameter newProcessContext is the context state that the execute method had set and sent back. You can compare the changes using the two contexts and revert any such changes. For eg: Update the change in status field of the record or send an email to the user to ignore the previous mail with the reference id. Manual activitiesManual activities do not have any class implementations to do. Since manual activities require user input to complete the task eg: require authorization from HRManager, to proceed with the process, you will need to provide User Interface for these activities. You will have two choice: Webbased client or Desktop client. Vertical generator has option of generating code for either of these, in java technologies: JSPs or Swing. TasksGSi generates a task for each manual activity it encounters when executing the process. A task has potential performers; these are the same performers who are provided for the manual activity. Any user with the role and department mentioned in the performer for the manual activity will be able to see a list of pending activities for him. Meaning all users with the same role and belonging to the same department will see the task in their pending activities list. And then no other user will see the task in his pending activity list. The task, now, needs to be claimed by a user. Once claimed it will solely belong to him. He now has to complete the task. Once completed, the manual activity is marked off as complete and the process moves ahead. An admin, using the monitoring tool, can allocate a claimed task to another user. When user information is provided in performer of the manual activity, the task is automatically assigned to the user and will not appear to other users in their pending list. Reminders & escalationsWhen a task is not completed after being claimed for a certain period of time, reminder or escalation activities can be executed. Differences between reminder and escalation are that: same reminder can be fired multiple times, where as escalation is executed only once and after escalation a different path is taken where as after reminder the original activity is still executing. When an escalation path is taken upon expiry of a time frame, the original activity is activity is aborted and the related task is expired. If no one claims an activity then reminders or escalation becomes active. Any kind of activity can be executed as a reminder or escalation, except splits or joins. Getting listA list of tasks can be obtained from VerticalClientApi object by calling the method getTasks(). It returns all the tasks that are both pending and that are claimed. Pending tasks have no users associated with them. The user’s information is picked from the information provided during validateUser call. Only after validateUser is called on VerticalClientApi can getTasks can be called, else an exception is thrown. You can also get a list of the all Activities input parameters to let the user decide if he wants to claim the task. ClaimingA task can be claimed by a user by calling the claimTaskItem method and passing taskId and the user’s username. Now the task belongs to him. The task object among many other methods contains methods to get the input parameters. This is in the form of an xml, from the method getTskInputXml. The format of this xml is provided in the Appendix. Also a code snippet to convert the xml into a map of parameters is provided in the Appendix. The map contains name of the context parameter as the key and value of the context parameter as value, and both are strings. FinishingA claimed task can be finished by calling completedTaskItem method and passing taskId and output parameters to the task in the form of an xml. The xml format is defined in Appendix. Also a code snippet to convert a map of output parameters is provided in Appendix. The map contains name of the context parameter as the key and value of the context parameter as value, and both are strings. Starting processesA task can be kicked off by calling createProcessInstance() method on VerticalClientApi object. First an instance of this object is create by calling the construct with the following parameters: Url for WSDL file, namespace of the webservice and name of the endpoint of the webservice. Then validateUser has to be called to login a specific user before invoking a process. createProcessInstance starts a process instance asynchronously. It create a process instance immediately call createProcessInstanceImmediate method. Both these methods take the same parameters: · Name of the process definition · A unique Id (like invoice number) to uniquely identify the process instance for future references by the vertical. · The requestor who is invoking the process. If the requestor information does not match the process performers the process is not kicked off. The requestor’s department and role can be PUBLIC:PUBLIC to say that its no specific user who is kicking off this instance. · Map of input parameters to the process. Usually a process requires some input parameters to be started. These are provided as name, value pairs inside the map. All input parameters need to be string. All mandatory input parameters need to be provided else the process will not start. Getting state of processThe state of a process can be obtained by invoking [getPIStatusForVerticalUnqiueID] on the VerticalClientApi instance. The following parameters need to be passed to the method: process name for which you want to obtain the state and the uniqueVerticalId with which the process was started. To execute this operation , use the validateUser method. Making updatesVertical updatesUpdates to verticals are usually by adding a new process or deleting existing ones. After identifying the changes required and modeling the same in the modeling tool, steps to be followed are same as mentioned above for newly added processes. If you are deleting an existing process please remove references to vertical application in the following forms: Automated activities jar, Manual activity linkages in the Vertical application. Process updatesUpdates to existing processes could in the following ways: · Changing performers · Changing input/ output parameters · Changing paths · Modifying activities When paths are changed you will not have to make and changes in your application code. When adding new activities, you will have to use vertical generator tool for those specific activities to generate skeleton code. You will then follow the regular steps as mentioned above to code the activity, package it and deploy it. When modifying activities by changing performers for manual activities, you will have to make changes in vertical application. [SAMPLE] When modifying parameters, you will not be able to use vertical generator completely, as it would not be able to update existing code. You will have to generate new skeleton code using vertical generator and use snippets of the new code where applicable in already existing code of yours. [SAMPLE] Packaging for deploymentDepending on the choice of vertical made you would like to package the application in either of the two ways: swing or web. [IMAGE] Use jar tool (provided with JDK) to package the class files into jars, and place them as shown in the diagram. Each of the boxes in the diagram is a separate logic entity and can be packaged as 1 or multiple jars depending on your convenience. You can also use the build.xml script provided by vertical generator. Use Ant to run build.xml. Ant can be obtained from ant.apache.org. AppendixXML files samples1. Task input parameters 1. <?xml version="1.0" encoding="UTF-8"?> 2. <task-input-parameters> 3. <param name="name1" value="value1" /> 4. <param name="name2" value="value2" /> 5. </task-input-parameters>
2. Task output parameters 1. <?xml version="1.0" encoding="UTF-8"?> 2. <task-output-parameters> 3. <param name="name1" value="value1" /> 4. <param name="name2" value="value2" /> 5. </task-output-parameters>
Refer to API documentation for webservices formats for communication. Code examplesCode snippets in brown are auto generated from vertical generator. 1. Sample code for automated activity 1. package com.comat.vertical.hr; 2. import com.comat.gsi.utility.*; 3. /** 4. * Class for automated application: Regret Letter 5. * Process: HR Interview 6. * applicationId: 36 7. * verticalId: 22 8. * Generated on: 10-Aug-2005 at 02:07:18 9. */ 10. public class CreateRegretLetter implements GenericActivity{ 11. /* Always have a public default constructor */ 12. public RegretLetter(){ } 13. 14. /** Execute method: invoked by GSi (WFE) */ 15. public void execute(ProcessContext context) throws Exception{ 16. try { 17. String CandName = context.getAttributeValue("CandName"); 18. String candId = context.getAttributeValue("candId"); 19. String email = context.getAttributeValue("email"); 20. String JobTitle = context.getAttributeValue("JobTitle"); 21. String status = context.getAttributeValue("status"); 22. 23. long c = Long.parseLong(candId); 24. long s = Long.parseLong(status); 25. String msg = Util.createEmailFile("Regret_"+c+".txt",CandName,email); 26. long s1 = Util.updateCandidateStatus(c,s); 27. context.putAttributeValue("status", new Long(sl).toString()); 28. } 29. catch(Exception e) { 30. e.printStackTrace(); 31. } 32. }
2. Sample code for compensative automated activity. 1. package com.comat.vertical.hr; 2. import com.comat.gsi.utility.*; 3. /** 4. * Class for automated application: Regret Letter 5. * Process: HR Interview 6. * applicationId: 36 7. * verticalId: 22 8. * Generated on: 10-Aug-2005 at 02:07:18 9. */ 10. public class CreateRegretLetter implements CompensativeActivity/*GenericActivity*/{ 11. /* Always have a public default constructor */ 12. public RegretLetter(){ } 13. 14. /** Execute method: invoked by GSi (WFE) */ 15. public void execute(ProcessContext context) throws Exception{ 16. try { 17. String CandName = context.getAttributeValue("CandName"); 18. String candId = context.getAttributeValue("candId"); 19. String email = context.getAttributeValue("email"); 20. String status = context.getAttributeValue("status"); 21. 22. long c = Long.parseLong(candId); 23. long s = Long.parseLong(status); 24. String msg = Util.createEmailFile("Regret_"+c+".txt",CandName,email); 25. long s1 = Util.updateCandidateStatus(c,s); 26. context.putAttributeValue("status", new Long(sl).toString()); 27. 28. 29. } 30. catch(Exception e) { 31. e.printStackTrace(); 32. } 33. } 34. 35. /** Compensation method: invoke by GSi (WFE) during rollback */ 36. public void compensate(ProcessContext oldProcessContext, ProcessContext newProcessContext){ 37. //TODO: write the compensate logic here. Undo whatever was done in execute. 38. //oldProcessContext is what the execute method got. 39. //newProcessContext is what the execute method returned. 40. try { 41. String CandNameOLD = oldProcessContext.getAttributeValue("CandName"); 42. String candIdOLD = oldProcessContext.getAttributeValue("candId"); 43. String emailOLD = oldProcessContext.getAttributeValue("email"); 44. String statusOLD = oldProcessContext.getAttributeValue("status"); 45. 46. String CandNameNEW = newProcessContext.getAttributeValue("CandName"); 47. String candIdNEW = newProcessContext.getAttributeValue("candId"); 48. String emailNEW = newProcessContext.getAttributeValue("email"); 49. String statusNEW = newProcessContext.getAttributeValue("status"); 50. 51. long c = Long.parseLong(candIdOLD); 52. long s = Long.parseLong(statusNEW); 53. String msg = Util.deleteFile("Regret_"+c+".txt"); 54. 55. long s1 = Util.revertCandidateStatus(c,s); 56. context.putAttributeValue("status", new Long(sl).toString()); 57. 58. } 59. catch(Exception e) { 60. e.printStackTrace(); 61. } 62. } 63. }
3. Sample generated code for compensation of manual activity. 1. package com.comat.vertical.hr; 2. import com.comat.gsi.utility.*; 3. /** 4. * Compensation class for manual activity: Req for Approval 5. * Process: HR Interview 6. * activityId: 46 7. * verticalId: 22 8. * Generated on: 10-Aug-2005 at 02:07:18 9. */ 10. public class ApprReq implements Compensative{ 11. /* Always have a public default constructor */ 12. public ApprReq(){ } 13. 14. /** Compensation method: invoked by GSi (WFE) during rollback */ 15. public void compensate(ProcessContext oldProcessContext, ProcessContext newProcessContext){ 16. //TODO: write the compensate logic here. Undo whatever was done during the completion of the manual task. 17. //oldProcessContext is the state before the task execution. 18. //newProcessContext is the state after the task execution. 19. try { 20. String candIdOLD = oldProcessContext.getAttributeValue("candId"); 21. String statusOLD = oldProcessContext.getAttributeValue("status"); 22. 23. String candIdNEW = newProcessContext.getAttributeValue("candId"); 24. String statusNEW = newProcessContext.getAttributeValue("status"); 25. 26. Util.revertApprovalRequest(new Long(candIdOLD).longValue(), 27. new Long(statusNEW).longValue()); 28. 29. } catch(Exception e) {e.printStackTrace(); } 30. } 31. }
Screenshot of generated swing user interface for a task [IMAGE] Screenshot of generated swing task interface for obtaining list of tasks [IMAGE] 4. Sample generated code for manual activity swing based user interface. 1. package com.comat.vertical.hr.gui; 2. 3. import java.awt.event.ActionEvent; 4. import java.awt.event.ActionListener; 5. import java.io.ByteArrayInputStream; 6. import java.util.HashMap; 7. import java.util.Iterator; 8. import java.util.List; 9. import java.util.Map; 10. 11. import javax.swing.JDialog; 12. import javax.swing.JOptionPane; 13. 14. import org.jdom.Document; 15. import org.jdom.Element; 16. import org.jdom.JDOMException; 17. import org.jdom.input.SAXBuilder; 18. import org.xml.sax.InputSource; 19. 20. import com.comat.vertical.hr.controller.TaskController; 21. 22. 23. public class TaskHREvaluation extends javax.swing.JDialog implements ActionListener { 24. 25. private javax.swing.JButton jbOk; 26. private javax.swing.JButton jbCancel; 27. private javax.swing.JPanel jPanel; 28. private javax.swing.JScrollPane jScrollPane; 29. 30. private javax.swing.JLabel jlResult; 31. private javax.swing.JTextField jtfResult; 32. private javax.swing.JLabel jlChoice; 33. private javax.swing.JTextField jtfChoice; 34. 35. private String inDate; 36. private String inCandId; 37. private String inCandName; 38. private String inReqId; 39. private String inJobTitle; 40. 41. private long taskId; 42. private String inputXML; 43. 44. public TaskHREvaluation(JDialog parent, long taskId, String inputXML) { 45. super(parent); 46. this.taskId=taskId; 47. this.inputXML=inputXML; 48. populate(); 49. initComponents(); 50. addListeners(); 51. setTitle("Task TaskHREvaluation"); 52. } 53. 54. private void populate(){ 55. Map map = getTaskInputList(); 56. if(map==null)return; 57. inDate=(String)map.get("Date"); 58. inCandId=(String)map.get("candId"); 59. inCandName=(String)map.get("CandName"); 60. inReqId=(String)map.get("ReqId"); 61. inJobTitle=(String)map.get("JobTitle"); 62. //TODO: Use the input information 63. } 64. private void addListeners(){ 65. jbCancel.addActionListener(this); 66. jbOk.addActionListener(this); 67. } 68. 69. private void initComponents() { 70. jScrollPane = new javax.swing.JScrollPane(); 71. jPanel = new javax.swing.JPanel(); 72. jbOk = new javax.swing.JButton(); 73. jbCancel = new javax.swing.JButton(); 74. 75. getContentPane().setLayout(null); 76. addWindowListener(new java.awt.event.WindowAdapter() { 77. public void windowClosing(java.awt.event.WindowEvent evt) { 78. exitForm(evt); 79. } 80. }); 81. 82. jPanel.setLayout(null); 83. 84. jlResult = new javax.swing.JLabel(); 85. jtfResult = new javax.swing.JTextField(); 86. 87. jlResult .setText("Result"); 88. jPanel.add(jlResult); 89. jlResult .setBounds(10, 1*20, 130, 16); 90. 91. jPanel.add(jtfResult); 92. jtfResult .setBounds(140, 1*20, 110, 20); 93. jlChoice = new javax.swing.JLabel(); 94. jtfChoice = new javax.swing.JTextField(); 95. 96. jlChoice .setText("Choice"); 97. jPanel.add(jlChoice); 98. jlChoice .setBounds(10, 2*20, 130, 16); 99. 100. jPanel.add(jtfChoice); 101. jtfChoice .setBounds(140, 2*20, 110, 20); 102. 103. jbOk.setText("Ok"); 104. getContentPane().add(jbOk); 105. 106. jbCancel.setText("Cancel"); 107. getContentPane().add(jbCancel); 108. 109. getContentPane().add(jPanel); 110. jPanel.setBounds(10, 30, 360, 2*20+70); 111. jbOk.setBounds(180, 2*20+120, 73, 26); 112. jbCancel.setBounds(290, 2*20+120, 73, 26); 113. setSize(398, 2*20+190); 114. 115. } 116. 117. private void exitForm(java.awt.event.WindowEvent evt) { 118. dispose(); 119. } 120. private void save() throws Exception{ 121. Map map = new HashMap(); 122. map.put("Result",jtfResult.getText()); 123. map.put("Choice",jtfChoice.getText()); 124. TaskController.getInstance().completeTaskItem(taskId,map); 125. } 126. public void actionPerformed(ActionEvent e) { 127. Object src = e.getSource(); 128. if(src==jbOk){ 129. try{ 130. save(); 131. dispose(); 132. }catch(Exception ex){ 133. JOptionPane.showMessageDialog(this,ex.getMessage(),"Error finishing task",JOptionPane.ERROR_MESSAGE); 134. } 135. }else if(src ==jbCancel){ 136. dispose(); 137. } 138. } 139. public static void main(String[] args){ 140. new TaskHREvaluation(new JDialog(),0,"").show(); 141. } 142. 143. private final String NAME = "name"; 144. private final String VALUE = "value"; 145. /** 146. * This method parses the task input XML and returns a map of parameters 147. * @param taskInputParamsXML 148. * @return 149. */ 150. private Map getTaskInputList(){ 151. if(inputXML==null || inputXML.trim().length()<1)return null; 152. Map inputParams = new HashMap(); 153. try { 154. SAXBuilder builder = new SAXBuilder(); 155. InputSource iSource = new InputSource(new ByteArrayInputStream(inputXML.getBytes())); 156. Document document = builder.build(iSource); 157. 158. List list = document.getRootElement().getChildren(); 159. Iterator iterator = list.iterator(); 160. while(iterator.hasNext()) { 161. Element paramEle = (Element) iterator.next(); 162. inputParams.put(paramEle.getAttribute(NAME).getValue(), 163. paramEle.getAttribute(VALUE).getValue()); 164. } 165. } 166. catch(JDOMException jdome){ 167. jdome.printStackTrace(); 168. } 169. catch(Exception e) { 170. e.printStackTrace(); 171. } 172. return inputParams; 173. } 174. }
Screenshot of generated Web user interface for a task [IMAGE] Screenshot of generated web task interface for obtaining list of tasks [IMAGE] 6. Sample generated code for manual activity web based user interface. 1. <%@page contentType="text/html;charset=UTF-8" language="java" %> 2. <%@page import = "java.util.*" %> 3. <jsp:useBean id="taskItemAction" class="com.comat.gsi.tools.taskinterface.util.TaskItemAction" scope="session"/> 4. 5. <% 6. /** 7. * UI for manual activity: HR Evaluation 8. * Process: HR Interview 9. * activityId: 48 10. * verticalId: 22 11. * Generated on: 10-Aug-2005 at 02:34:08 12. */ 13. %> 14. 15. <html> 16. <head> 17. <title>HR Evaluation</title> 18. <link rel="stylesheet" href="style.css"> 19. </head> 20. <body> 21. <% 22. String login = (String)session.getAttribute("USER_NAME"); 23. if(login==null){ 24. out.println("Please login.<br><a href=Login.jsp>Login</a></body></html>"); 25. return; 26. } 27. String submit = request.getParameter("submit"); 28. 29. String _TaskName = null; 30. String _ProcessName = null; 31. String _Id = null; 32. 33. if(submit!=null && submit.length()>0){ 34. _TaskName = request.getParameter("_TaskName"); 35. _Id = request.getParameter("_Id"); 36. _ProcessName = request.getParameter("_ProcessName"); 37. }else{ 38. _TaskName = (String)request.getAttribute("TaskName"); 39. _ProcessName = (String)request.getAttribute("ProcessName"); 40. _Id = (String)request.getAttribute("Id"); 41. } 42. %> 43. <center> 44. <h2>HR Evaluation</h2> 45. <h4>Name: <%= _TaskName %></h4> 46. <h4>Process Name - <%= _ProcessName %></h4> 47. <h6>Task Id: <%= _Id %></h6> 48. <hr/> 49. <% 50. if(submit!=null && submit.length()>0){ 51. String taskName = request.getParameter("_TaskName"); 52. String id = request.getParameter("_id"); 53. 54. String ReqIdIN = request.getParameter("ReqIdIN"); 55. String CandNameIN = request.getParameter("CandNameIN"); 56. String JobTitleIN = request.getParameter("JobTitleIN"); 57. String DateIN = request.getParameter("DateIN"); 58. String candIdIN = request.getParameter("candIdIN"); 59. 60. String ResultOUT = request.getParameter("ResultOUT"); 61. String ChoiceOUT = request.getParameter("ChoiceOUT"); 62. try{ 63. //TODO: do processing here. 64. Map map=new HashMap(); 65. map.put("Result",ResultOUT); 66. map.put("Choice",ChoiceOUT); 67. taskItemAction.completeTaskItem(session,Long.parseLong(_Id),map); 68. out.println("<h2>Your task has been successfully completed.</h2>"); 69. }catch(Exception e){ 70. out.println("<font color=red><h2>Error! Your task could not be completed.</h2><br>Error was:"+e.getMessage()+"</font>"); 71. } 72. out.println("<br><a href=\"TaskList.jsp\">TaskList</a><br>"); 73. return; 74. } 75. %> 76. <form method=post action="HREvaluation.jsp"> 77. <input type=hidden name="_TaskName" value="<%= _TaskName %>"> 78. <input type=hidden name="_Id" value="<%= _Id %>"> 79. <input type=hidden name="_ProcessName" value="<%= _ProcessName %>"> 80. 81. <% 82. Map inParams = (Map)request.getAttribute("InputXML"); 83. %> 84. Inputs: 85. <table border=1> 86. <input type=hidden name="ReqIdIN" value="<%=inParams.get("ReqId")%>"> 87. <tr><th>ReqId</th><td><%=inParams.get("ReqId")%></td></tr> 88. <input type=hidden name="CandNameIN" value="<%=inParams.get("CandName")%>"> 89. <tr><th>CandName</th><td><%=inParams.get("CandName")%></td></tr> 90. <input type=hidden name="JobTitleIN" value="<%=inParams.get("JobTitle")%>"> 91. <tr><th>JobTitle</th><td><%=inParams.get("JobTitle")%></td></tr> 92. <input type=hidden name="DateIN" value="<%=inParams.get("Date")%>"> 93. <tr><th>Date</th><td><%=inParams.get("Date")%></td></tr> 94. <input type=hidden name="candIdIN" value="<%=inParams.get("candId")%>"> 95. <tr><th>candId</th><td><%=inParams.get("candId")%></td></tr> 96. </table> 97. 98. <p/><p/> 99. Outputs: 100. <table border=1 cellpadding=2 cellspacing=2> 101. <tr><th>Result</th><td><input type=text name="ResultOUT" value=""></td></tr> 102. <tr><th>Choice</th><td><input type=text name="ChoiceOUT" value=""></td></tr> 103. <tr><td> </td><td> </td></tr> 104. <tr><td><input type=submit name="submit" value="Complete task"></td><td><input type=reset value="Reset"></td></tr> 105. </table> 106. </form> 107. 108. </center> 109. </body> 110. </html>
7. Sample implementation for UPM for Unmanaged vertical 1. package com.comat.vertical; 2. 3. import java.rmi.RemoteException; 4. import java.sql.Connection; 5. import java.sql.DriverManager; 6. import java.sql.PreparedStatement; 7. import java.sql.ResultSet; 8. import java.sql.Statement; 9. import java.util.ArrayList; 10. import java.util.HashMap; 11. import java.util.HashSet; 12. import java.util.Iterator; 13. import java.util.List; 14. import java.util.Map; 15. import java.util.Set; 16. import com.comat.gsi.utility.upmutil.IVUPM; 17. import com.comat.gsi.utility.upmutil.UPMException; 18. 19. public class HrrsImpl implements IVUPM{ 20. /** 21. * This method gets user contacts for a given userId and the mechanism. 22. * Returns a Map of - UserId:Username 23. */ 24. public Map getUserContact(Set userIds, String mechanism) throws RemoteException,UPMException{ 25. 26. Map hm = new HashMap(); 27. String field = "EMP_EMAIL"; 28. if(mechanism!=null && mechanism.length()>0){ 29. if(mechanism.equalsIgnoreCase("email")) { 30. if(userIds==null || userIds.size()<1)return hm; 31. for (Iterator iter = userIds.iterator(); iter.hasNext();) { 32. String uid = (String)iter.next(); 33. hm.put(uid,uid); 34. } 35. return hm; 36. } 37. if(mechanism.equalsIgnoreCase("phone")) field = "EMP_PHONE"; 38. else if(mechanism.equalsIgnoreCase("mobile")) field = "EMP_MOBILE"; 39. } 40. 41. if(userIds==null || userIds.size()<1)return hm; 42. 43. StringBuffer sb = new StringBuffer(); 44. for (Iterator iter = userIds.iterator(); iter.hasNext();) { 45. String uid = (String)iter.next(); 46. sb.append("'"+uid+"',"); 47. } 48. sb.deleteCharAt(sb.length()-1); 49. 50. Connection conn = null; 51. String sql = "select EMP_EMAIL , "+field+" from EMP_MASTER where EMP_EMAIL in ("+sb.toString()+")";//TODO: issue with more than 50 UIDs 52. try{ 53. conn = getConnection(); 54. Statement pst = conn.createStatement(); 55. ResultSet rs = pst.executeQuery(sql); 56. while(rs.next()) 57. hm.put(rs.getObject(1),rs.getObject(2)); 58. }catch (Exception e) {System.err.println(sql+"\nDBError: "+e.getMessage());} 59. finally{ 60. try {if(conn!=null)conn.close();} catch (Exception e) {} 61. } 62. return hm; 63. } 64. 65. /** 66. * This method validates a user with a given Organization unit. 67. */ 68. public boolean validate(String userId, String ou) throws RemoteException,UPMException{ 69. Connection conn = null; 70. String sql = "select EMP_DETAIL.EMP_ID from EMP_MASTER, EMP_DETAIL, DEPT_MASTER where EMP_EMAIL =? and EMP_MASTER.EMP_ID=EMP_DETAIL.EMP_ID and EMP_DETAIL.DM_ID = DEPT_MASTER.DM_ID and DEPT_MASTER.DM_DEPT_NAME=?"; 71. try{ 72. conn = getConnection(); 73. PreparedStatement pst = conn.prepareStatement(sql); 74. pst.setString(1,userId); 75. pst.setString(2,ou); 76. ResultSet rs = pst.executeQuery(); 77. rs.next(); 78. if(rs.getRow() == 0) return false; else return true; 79. }catch (Exception e) {System.err.println(sql+"\nDBError: "+e.getMessage());} 80. finally{ 81. try {if(conn!=null)conn.close();} catch (Exception e) {} 82. } 83. return false; 84. } 85. 86. /** 87. * This method validates a user having a role given and belonging to the Organizational Unit. 88. */ 89. public boolean validate(String userId, String role, String ou) throws RemoteException,UPMException{ 90. Connection conn = null; 91. String sql = "select EMP_DETAIL.EMP_ID from EMP_MASTER, EMP_DETAIL, DEPT_MASTER, ROLE_MASTER where EMP_EMAIL =? and EMP_MASTER.EMP_ID=EMP_DETAIL.EMP_ID and EMP_DETAIL.DM_ID = DEPT_MASTER.DM_ID and ROLE_MASTER.RM_ID=EMP_DETAIL.RM_ID and DEPT_MASTER.DM_DEPT_NAME=? and ROLE_MASTER.RM_ROLE_NAME=?"; 92. try{ 93. conn = getConnection(); 94. PreparedStatement pst = conn.prepareStatement(sql); 95. pst.setString(1,userId); 96. pst.setString(2,ou); 97. pst.setString(3,role); 98. ResultSet rs = pst.executeQuery(); 99. rs.next(); 100. if(rs.getRow() == 0) return false; else return true; 101. }catch (Exception e) {System.err.println(sql+"\nDBError: "+e.getMessage());} 102. finally{ 103. try {if(conn!=null)conn.close();} catch (Exception e) {} 104. } 105. return false; 106. } 107. 108. /** 109. * This method validates a user having a role given and belonging to the Organizational Unit. 110. */ 111. public boolean validateUserofRole(String userId, String role) throws RemoteException,UPMException{ 112. System.out.println("HrrsImpl.validateUserofRole"); 113. Connection conn = null; 114. String sql = "select EMP_DETAIL.EMP_ID from EMP_MASTER, EMP_DETAIL, ROLE_MASTER where EMP_EMAIL =? and EMP_MASTER.EMP_ID=EMP_DETAIL.EMP_ID and EMP_DETAIL.RM_ID = ROLE_MASTER.RM_ID and ROLE_MASTER.RM_ROLE_NAME=?"; 115. try{ 116. conn = getConnection(); 117. PreparedStatement pst = conn.prepareStatement(sql); 118. pst.setString(1,userId); 119. pst.setString(2,role); 120. ResultSet rs = pst.executeQuery(); 121. rs.next(); 122. if(rs.getRow() == 0) return false; else return true; 123. }catch (Exception e) {System.err.println(sql+"\nDBError: "+e.getMessage());} 124. finally{ 125. try {if(conn!=null)conn.close();} catch (Exception e) {} 126. } 127. return false; 128. } 129. 130. /** 131. * This method gets departments for an unmanaged vertical 132. * Returns a List of GroupNames in it .. 133. */ 134. public List getDepartments() throws RemoteException,UPMException{ 135. List list = new ArrayList(); 136. Connection conn = null; 137. String sql = "select DM_DEPT_NAME from DEPT_MASTER"; 138. try{ 139. conn = getConnection(); 140. PreparedStatement pst = conn.prepareStatement(sql); 141. ResultSet rs = pst.executeQuery(); 142. while(rs.next()) 143. list.add(rs.getObject(1)); 144. }catch (Exception e) {System.err.println(sql+"\nDBError: "+e.getMessage());} 145. finally{ 146. try {if(conn!=null)conn.close();} catch (Exception e) {} 147. } 148. return list; 149. } 150. 151. /** 152. * This method gets Users for an unmanaged vertical 153. * Returns a Map inside a List having UserId:UserName inside the Map 154. * the List will contain only 1 entry 155. */ 156. public List getVerticalUsers()throws RemoteException,UPMException{ 157. List list = new ArrayList(); 158. Map map = new HashMap(); 159. Connection conn = null; 160. String sql = "select EMP_EMAIL, EMP_NAME from EMP_MASTER"; 161. try{ 162. conn = getConnection(); 163. PreparedStatement pst = conn.prepareStatement(sql); 164. ResultSet rs = pst.executeQuery(); 165. while(rs.next()) 166. map.put(rs.getObject(1),rs.getObject(2)); 167. list.add(map); 168. }catch (Exception e) {System.err.println(sql+"\nDBError: "+e.getMessage());} 169. finally{ 170. try {if(conn!=null)conn.close();} catch (Exception e) {} 171. } 172. return list; 173. } 174. 175. /** 176. * This method gets Roles for an unmanaged vertical 177. * Returns a List of Rolenames in it .. 178. */ 179. public List getVerticalRoles() throws RemoteException,UPMException{ 180. System.out.println("HrrsImpl.getVerticalRoles"); 181. List list = new ArrayList(); 182. Connection conn = null; 183. String sql = "select RM_ROLE_NAME from ROLE_MASTER"; 184. try{ 185. conn = getConnection(); 186. PreparedStatement pst = conn.prepareStatement(sql); 187. ResultSet rs = pst.executeQuery(); 188. while(rs.next()) 189. list.add(rs.getObject(1)); 190. }catch (Exception e) {System.err.println(sql+"\nDBError: "+e.getMessage());} 191. finally{ 192. try {if(conn!=null)conn.close();} catch (Exception e) {} 193. } 194. return list; 195. } 196. 197. /** 198. * This method gets Roles for an unmanaged vertical 199. * Returns a Map of RoleId:RoleName 200. */ 201. public Map getVerticalUserRoles(Long userId) throws RemoteException,UPMException{ 202. Map map = new HashMap(); 203. Connection conn = null; 204. String sql = "select EMP_DETAIL.RM_ID, RM_ROLE_NAME from ROLE_MASTER, EMP_DETAIL where ROLE_MASTER.RM_ID=EMP_DETAIL.RM_ID and EMP_DETAIL.EMP_ID=?"; 205. try{ 206. conn = getConnection(); 207. PreparedStatement pst = conn.prepareStatement(sql); 208. pst.setLong(1, userId.longValue()); 209. ResultSet rs = pst.executeQuery(); 210. while(rs.next()) 211. map.put(rs.getObject(1),rs.getObject(2)); 212. }catch (Exception e) {System.err.println(sql+"\nDBError: "+e.getMessage());} 213. finally{ 214. try {if(conn!=null)conn.close();} catch (Exception e) {} 215. } 216. return map; 217. } 218. 219. 220. /** 221. * This method gets Username and password for validation and returns all the 222. * Organization Units that the user belongs to . 223. * Returns a Map of - GroupId:GroupName 224. */ 225. public Map validateUser(String userName , String password) throws RemoteException,UPMException{ 226. Map map = new HashMap(); 227. Connection conn = null; 228. String sql = "select EMP_DETAIL.DM_ID, DM_DEPT_NAME from EMP_MASTER, EMP_DETAIL, DEPT_MASTER where EMP_EMAIL =? and EMP_MASTER.EMP_ID=EMP_DETAIL.EMP_ID and EMP_DETAIL.DM_ID = DEPT_MASTER.DM_ID and EMP_PASSWORD=?"; 229. try{ 230. conn = getConnection(); 231. PreparedStatement pst = conn.prepareStatement(sql); 232. pst.setString(1,userName); 233. pst.setString(2,password); 234. ResultSet rs = pst.executeQuery(); 235. while(rs.next()) 236. map.put(rs.getObject(1),rs.getObject(2)); 237. }catch (Exception e) {System.err.println(sql+"\nDBError: "+e.getMessage());} 238. finally{ 239. try {if(conn!=null)conn.close();} catch (Exception e) {} 240. } 241. return map; 242. } 243. 244. /** 245. * This method gets UserId and UserName for the given OU and Role 246. * Returns UserLoginName in the List 247. */ 248. public List getVerticalUsers(String ou,String role,int verticalId)throws RemoteException,UPMException{ 249. List list = new ArrayList(); 250. Connection conn = null; 251. String sql = "select EMP_EMAIL from EMP_MASTER, EMP_DETAIL, DEPT_MASTER, ROLE_MASTER where EMP_MASTER.EMP_ID=EMP_DETAIL.EMP_ID and EMP_DETAIL.DM_ID = DEPT_MASTER.DM_ID and ROLE_MASTER.RM_ID=EMP_DETAIL.RM_ID and DEPT_MASTER.DM_DEPT_NAME=? and ROLE_MASTER.RM_ROLE_NAME=?"; 252. try{ 253. conn = getConnection(); 254. PreparedStatement pst = conn.prepareStatement(sql); 255. pst.setString(2,role); 256. pst.setString(1,ou); 257. ResultSet rs = pst.executeQuery(); 258. while(rs.next()) 259. list.add(rs.getObject(1)); 260. }catch (Exception e) {System.err.println(sql+"\nDBError: "+e.getMessage());} 261. finally{ 262. try {if(conn!=null)conn.close();} catch (Exception e) {} 263. } 264. return list; 265. } 266. 267. private Connection getConnection(){ 268. Connection con = null; 269. try{ 270. Class.forName("oracle.jdbc.driver.OracleDriver"); 271. String datastring="jdbc:oracle:thin:@192.168.100.1:1521:test"; 272. String username= "testhr"; 273. String password= "testhr"; 274. System.out.println("Using: "+datastring+"("+username+"/"+password+")"); 275. con =DriverManager.getConnection(datastring,username,password); 276. }catch (Exception e) { 277. System.err.println("Error getting connection"); 278. } 279. return con; 280. } 281. }
8. Sample code snippet for Login 1. com.comat.gsi.common.verticalapi.VerticalClientApi verticalApi = new 2. com.comat.gsi.common.verticalapi.VerticalClientApi( "file:///C:/VerticalApi.wsdl", "http://com.comat.gsi.common.verticalapi", "VerticalApi"); 3. 4. String userName = "simone"; 5. String role[] = new String {"Manager"}; 6. String ou[] = new String{"Java"}; 7. String verticalId = "HRInterview"; 8. boolean success = verticalApi.validateUser(userName, role, ou, verticalId);
9. Sample code snippet for Start process 1. //refer to code snippet for Login to obtain verticalApi instance 2. public String invokeProcessInstance(VerticalClientApi verticalApi, boolean async, String candidateName, String candEmailId){ 3. String status = null; 4. try { 5. 6. String username = "simone"; 7. String roleName = "Manager"; 8. String deptName = "Java"; 9. String verticalName = "HR"; 10. String processDefinition = "HRInterview"; 11. 12. String verticalUniqueID = Util.getNewInterviewNumber().toString(); 13. Map inputParams = new HashMap(); 14. inputParams.put("candId",verticalUniqueID); 15. inputParams.put("name",CandidateName); 16. inputParams.put("email",candEmailId); 17. 18. String requestor = username+":"+roleName+":"+deptName+ ":"+verticalName; 19. 20. int i = 0; 21. if (async) { 22. i = verticalApi.createProcessInstance(processDefinition,verticalUniqueID,requestor,params); 23. switch (i) { 24. case 1: status = "Successfully sent request";break; 25. case 2: status = "Request failed";break; 26. case 3: status = "Invalid usertoken";break; 27. } 28. } else { 29. i = verticalApi.createProcessInstanceImmediate(processDefinition,verticalUniqueID,requestor,params); 30. switch (i) { 31. case 1: status = "Successfully sent request";break; 32. case 2: status = "Insufficient input parameters";break; 33. case 3: status = "Process definition not found";break; 34. case 4: status = "Unknown exception";break; 35. case 5: status = "Invalid user token";break; 36. case 6: status = "Unable to contact WFE";break; 37. } 38. } 39. } catch(Exception e) { 40. e.printStackTrace(); 41. } 42. return status; 43. }
10. Sample code snippet for Get tasks 1. //refer to code snippet for Login to obtain verticalApi instance 2. private Object openTasks; 3. private Object claimedTasks; 4. 5. public void setAllTaskItems() { 6. Object tasks[] = verticalApi.getTasks(); 7. int openCount = 0, claimCount = 0; 8. for (int i = 0; i < tasks.length; i++ ) { 9. com.comat.gsi.common.verticalapi.types.UserTask userTask = (com.comat.gsi.common.verticalapi.types.UserTask) tasks[i]; 10. if ( userTask.getTskPerformer() == null) { 11. openCount++; 12. }else{ 13. claimCount++; 14. } 15. } 16. openTasks = new Object[openCount]; 17. claimedTasks = new Object[claimCount]; 18. openCount = 0; claimCount = 0; 19. for (int i = 0; i < tasks.length; i++ ){ 20. UserTask userTask = (UserTask) tasks[i]; 21. if (userTask.getTskPerformer() == null){ 22. openTasks[openCount++] = tasks[i]; 23. }else{ 24. claimedTasks[claimCount++] = tasks[i]; 25. } 26. } 27. }
11. Sample code snippet for Claim task 28. //refer to code snippet for Login to obtain verticalApi instance 29. setAllTaskItems(); //refer to code snippet for Get tasks 30. int i=0; 31. UserTask userTask = (UserTask)openTasks[i]; 32. String inputXml = userTask.getTskInputXml(); 33. Map inputMap = getTaskInputList(inputXml); 34. //user inputMap to do some business logic 35. long taskId = userTask.getId(); 36. String userName = "simone"; 37. int status = verticalApi.claimTaskItem(taskId, userName); 38. 39. /* Parses the task input XML and returns a map of parameters */ 40. public Map getTaskInputList(String taskInputParamsXML) { 41. Map inputParams = new HashMap(); 42. try { 43. SAXBuilder builder = new SAXBuilder(); 44. InputSource iSource = new InputSource(new ByteArrayInputStream(taskInputParamsXML.getBytes())); 45. Document document = builder.build(iSource); 46. 47. List list = document.getRootElement().getChildren(); 48. Iterator iterator = list.iterator(); 49. while(iterator.hasNext()) { 50. Element paramEle = (Element) iterator.next(); 51. inputParams.put(paramEle.getAttribute("name").getValue(), paramEle.getAttribute("value").getValue()); 52. } 53. }catch(JDOMException jdome){jdome.printStackTrace(); 54. }catch(Exception e) {e.printStackTrace(); 55. } 56. return inputParams; 57. } 12. Sample code snippet for Complete task 1. //refer to code snippet for Login to obtain verticalApi instance 2. setAllTaskItems(); //refer to code snippet for Get tasks 3. int i = 0; 4. UserTask userTask = (UserTask)claimedTasks[i]; 5. long taskId = userTask.getId(); 6. Map outputAttrs = new HashMap(); 7. //after executing business logic populate outputAttrs 8. String outputXML = buildOutputXML(outputAttrs); 9. int statusCode = verticalApi.completedTaskItem(taskId, outputXML); 10. String status = null; 11. switch(status){ 12. case 1: status = "Successfully Claimed";break; 13. case 2: status = "Invalid State";break; 14. case 3: status = "Task not found/ Doesnot have access";break; 15. case 4: status = "Failed for unknown reason";break; 16. case 5: status = "Invalid token/ User not authenticated";break; 17. case 6: status = "Unable to contact WFE";break; 18. } 19. 20. /* Builds the task output XML using the output Attributes */ 21. private String buildOutputXML(Map outputAttrs) { 22. StringBuffer sb = new StringBuffer(); 23. sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>";); 24. sb.append("<task-output-parameters>"); 25. int size = outputAttrs.size(); 26. Iterator it = outputAttrs.keySet().iterator(); 27. while(it.hasNext()) { 28. String name = (String)it.next(); 29. sb.append( "<param"+ " " + "name" + "=\""+ name +"\" "+ "value"+ "=\"" + (String)outputAttrs.get(name) +"\" />"); 30. } 31. sb.append("</task-output-parameters>"); 32. return sb.toString(); 33. }
|