Overview
การสร้าง Custom Workflow บน Alfresco นั้นแบ่งออกเป็น 3 ส่วนใหญ่ๆ คือ- Workflow Definition
- Alfresco Model
- Share UI
Preparation
ก่อนที่เราจะเริ่มสร้าง Workflow กันเราก็ต้องมาเตรียมความพร้อมกันก่อนโดยสิ่งที่เราต้องเตรียมมีดังนี้- Assume Alfresco Installed in your machine
- Eclipse (can be STS) with Activiti Designer http://www.activiti.org/userguide/index.html#eclipseDesignerInstallation
Creating Workflow Definition
หลังจากติดตั้ง Tools กันเรียบร้อยแล้ว ขั้นตอนต่อไปเราจะมาสร้าง (Simple) Custom Workflow กันโดยมี Step การทำงานซัก 1-2 step โดยมีขั้นตอนดังนี้- Start the Eclipse (or STS)
- Create Activiti Diagram ใน project ใดก็ได้ (เนื่องจาก Alfresco ใช้งานเฉพาะ xml definition file ไม่ได้ต้องการ Activiti Project ดังนั้นการสร้างแค่ Diagram จึงทำได้ง่ายกว่า) โดยผมตั้งชื่อเป็น sample.bpmn20.xml
- วาด Workflow ตามรูปด้านล่าง
- Edit the candidate user or group in text editor
จากรูปจะเห็นได้ว่ามีการกำหนด formKey ลงไปที่ startEvent และ userTask หมายความว่าเมื่อเรา Deploy Definition นี้ลงไปที่ Alfresco แล้ว เราต้องการให้ใช้ form ใดในการแสดงผลนั่นเอง ซึ่งผมกำหนดไว้ว่า startEvent ให้ใช้ form bpm:startTask และ userTask ต่างๆ ให้ใช้ form ของตัวเองที่ชื่อว่า sample:task1 และ sample:task2
ในส่วนของ acvititi:assignee นั้นผมกำหนดให้ task วิ่งไปยัง user tantai ซึ่งเมื่อมีการ Start Workflow แล้ว Task ก็จะวิ่งไปยัง user tantai ทันที รวมทั้งเมื่อจบ task1 ก็จะวิ่งไปยัง user tantai เช่นกันที่ task2
ซึ่งต่อไปเราจะมาสร้าง Workflow Model กันบนฝั่ง Alfresco
Note : Recommended to edit workflow definition in the text editor (not in Activiti Designer) because Activiti Designer have a lot of bug in current version (My version is 5.12.0)
Creating Alfresco Model
การสร้าง Model บน Alfresco นั้นประกอบไปด้วย 3 ส่วนคือ- Spring Context files
- Model files
- Message
แนะนำให้อ่าน Data Dictionary ของ Alfresco ก่อนครับ http://wiki.alfresco.com/wiki/Data_Dictionary_Guide
เนื่องจาก Alfresco ได้เขียน Spring Config ไว้ให้ import ไฟล์ที่ชื่อตามด้วย -context.xml ทุกไฟล์ใน folder TOMCAT_HOME/shared/classes/alfresco/extension/ ไว้ ขั้นตอนแรกให้เราสร้าง Spring Context file ขึ้นมาโดยต้องตั้งชื่อเป็น sample-context.xml และวางไว้ที่ folder extension config bean ดังนี้
<beans> <!-- Registration of new models --> <bean depends-on="dictionaryBootstrap" id="sample.model" parent="dictionaryModelBootstrap"> <property name="models"> <list> <value>alfresco/extension/sample-model.xml</value> </list> </property> </bean> </beans>จาก code ด้านบนเมื่อ Start Alfresco แล้ว Alfresco จะ load model จากไฟล์ที่ชื่อว่า sample-model.xml ดังนั้นให้เราสร้างไฟล์ sample-model.xml วางไว้ที่เดียวกันและ config bean ดังนี้
<?xml version="1.0" encoding="UTF-8"?> <model name="sample:sampleModel" xmlns="http://www.alfresco.org/model/dictionary/1.0"> <!-- Optional meta-data about the model --> <description>Sample Model</description> <author>tantai@osdev.co.th</author> <version>1.0</version> <imports> <!-- Import Alfresco Dictionary Definitions --> <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/> <!-- Import Alfresco Content Domain Model Definitions --> <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/> <!-- Import Alfresco BPM Model Definitions --> <import uri="http://www.alfresco.org/model/bpm/1.0" prefix="bpm" /> <!-- Import Alfresco Workflow Model Definitions --> <import uri="http://www.alfresco.org/model/workflow/1.0" prefix="wf"/> </imports> <!-- Introduction of new namespaces defined by this model --> <namespaces> <namespace uri="http://www.osdev.co.th/sample/workflow" prefix="sample"/> </namespaces> <types> <type name="sample:task1"> <title>Task1</title> <parent>wf:reviewTask</parent> </type> <type name="sample:task2"> <title>Task2</title> <parent>wf:reviewTask</parent> </type> </types> </model>
จาก code ด้านบน ผมกำหนด type ขึ้นมา 2 type คือ sample:task1 และ sample:task2 เพื่อให้ Workflow ใช้ type ดังกล่าวในการแสดงผล สังเกตุได้ว่า ผมไม่ได้สร้าง bpm:startTask เนื่องจาก bpm:startTask นั้นมีอยู่แล้วบน Alfresco (สามารถดูได้จากไฟล์ bpmModel.xml) และทั้ง 2 type ที่ผมสร้างขึ้นมาใหม่นั้นใช้ parent เป็น wf:reviewTask ซึ่งมีอยู่แล้วใน Alfresco เช่นกัน โดยเมื่อสร้าง Model เรียบร้อยแล้ว ให้สั่ง Restart Service Alfresco เพื่อให้ Alfresco load model ไปใช้งาน
Deploy Workflow
การ Deploy Workflow บน Alfresco นั้นไม่ยากครับเพราะว่า Alfresco มีหน้า workflow-console เพื่อใช้จัดการพวก Workflow อยู่แล้ว โดยขั้นตอนการ Deploy เราแค่ copy file sample.bpmn20.xml ไปไว้ที่ folder extension จากนั้นไปยัง http://{host}:{port}/alfresco/faces/jsp/admin/workflow-console.jsp เพื่อสั่ง deploy workflow ด้วยคำสั่งdeploy activiti alfresco/extension/sample.bpmn20.xmlNote: หากเข้า url ดังกล่าวไม่ได้ ให้เช้าไปที่ url http://{host}:{port}/alfresco เพื่อทำการ login ก่อนแล้วจึงเข้าไปยัง url ดังกล่าวอีกครั้ง
โดยเมื่อสั่ง Deploy แล้ว ที่ Alfresco Share เราจะสามารถสั่ง Start Workflow Sample ที่เราทำได้
แต่เมื่อเลือก Sample Workflow แล้วจะสังเกตุได้ว่า form UI ต่างๆ นั้นจะแสดง properties ทั้งหมดออกมา
ซึ่งตามความเป็นจริงแล้ว เราต้องเลือกที่จะแสดงผล properties อะไรบ้าง ซึ่งจะอธิบายใน Step ต่อไปว่าเราจะกำหนด Share UI กันอย่างไร
Configure Share UI
การ Config Share UI นั้นเราสามารถทำได้ที่ไฟล์ share-config-custom.xml ซึ่งอยู่ที่ TOMCAT_HOME/shared/classes/alfresco/web-extension/share-config-custom.xml โดยเราสามารถกำหนดการแสดงผลของแต่ละ form ได้ดังนี้<config evaluator="string-compare" condition="activiti$sample"> <forms> <form> <field-visibility> <show id="packageItems" /> <show id="transitions" /> </field-visibility> <appearance> <set id="" appearance="title" label-id="workflow.set.general" /> <set id="items" appearance="title" label-id="workflow.set.items" /> <set id="response" appearance="title" label-id="workflow.set.response" /> <field id="packageItems" set="items" /> </appearance> </form> </forms> </config> <config evaluator="task-type" condition="sample:task1"> <forms> <form> <field-visibility> <show id="packageItems" /> <show id="transitions" /> </field-visibility> <appearance> <set id="" appearance="title" label-id="workflow.set.general" /> <set id="items" appearance="title" label-id="workflow.set.items" /> <set id="response" appearance="title" label-id="workflow.set.response" /> <field id="packageItems" set="items" /> </appearance> </form> </forms> </config> <config evaluator="task-type" condition="sample:task2"> <forms> <form> <field-visibility> <show id="packageItems" /> <show id="transitions" /> </field-visibility> <appearance> <set id="" appearance="title" label-id="workflow.set.general" /> <set id="items" appearance="title" label-id="workflow.set.items" /> <set id="response" appearance="title" label-id="workflow.set.response" /> <field id="packageItems" set="items" /> </appearance> </form> </forms> </config>
จาก config ด้านบนผมกำหนดให้ตอน startEvent, task1, task2 นั้นแสดงผล properties แค่ packageItem เท่านั้นหมายถึงผู้ Start Workflow จะ add file เข้ามาได้เพียงอย่างเดียว
โดยเมื่อ Start Workflow แล้ว Task จะวิ่งไปหา tantai ซึ่งถูกกำหนดไว้ที่ definition แล้ว โดยเมื่อ tantai login เข้ามาในระบบ จะเห็น task ดังนี้
โดยเมื่อคลิกเข้าไปก็จะเห็นหน้าตาดังที่เรา Config ไว้
โดยเมื่อกดปุ่ม Task Done, Task ก็จะวิ่งไปยัง tantai อีกครั้ง (หน้าตาเหมือนกันเพราะ Config ไว้เหมือนกัน)
โดยเมื่อกด Task Done อีกครั้งก็จะจบ Flow
ไม่มีความคิดเห็น:
แสดงความคิดเห็น