Introducción al API de Activiti
0. Índice de contenidos.
- 1. Introducción.
- 2. Entorno.
- 3. Notación básica BPMN en formato XML de Activiti.
- 4. Construir el diagrama BPM en Activiti.
- 5. Creación de la librería de Activi en Eclipse.
- 6. Configuración del esquema BPMN 2.0 en Eclipse.
- 7. Probar nuestro proceso con JUnit.
- 8. Conclusiones.
1. Introducción
En este tutorial se va continuar enseñando a utilizar la herramienta de BPM Activiti
pero esta vez centrándonos en implementar un proceso de BPM básico de Activiti en el lenguaje Java
usando para ello la herramienta de desarrollo Eclipse.
Para la buena comprensión de este tutorial se aconseja leer previamente el siguiente tutorial : Introducción a Activiti
Nos basaremos en la eleción de un ejemplo «muy básico» que nos sirva para entender como fuciona Activi
en esta parte de forma conceptual.El ejemplo elegido es el siguiente :
- Un estado inicial que se llama «inicio»
- Un tarea que se denomina «tarea»
- Un flujo denominado «flujo1» que conecta el estado inicial con la tarea
- Un flujo denominado «flujo2» que conecta la tarea con el estado final
- Un estado final que se llama «fin»
Comenzamos con la implementación….
2. Entorno.
El tutorial está escrito usando el siguiente entorno:
- Hardware: Portátil Asus G50Vseries (Core Duo P8600 2.4GHz, 4GB RAM,320 GB HD).
- Sistema operativo: Windows Vista Ultimate.
- Mozilla Firefox 2.0.0.20
- Apache Tomcat 6.0.26
- Activiti Alpha 3
- Eclipse Java EE IDE
3. Notación básica BPMN en formato XML de Activiti.
En este punto se va a explicar los elementos más comunes de BPMN cuando se implementa
sobre un fichero de XML en la herramienta Activiti.
Para explicar mejor esta parte vamos a realizar una serie de modificaciones sobre un fichero de prueba
que generaremos, asi ire explicando diferentes puntos de la implementación sobre ese fichero de ejemplo.
Antes de comenzar con la explicación, generamos un fichero que tenga como extensión «.bpmn20.xml» , el motivo
por el que se tiene que finalizar el el fichero de la anterior forma viene dado porque esa extensión es reconocida
por el motor de Activi, por lo que los ficheros que finalicen de esta forma serán tratados por Activi.
Vamos a crear una definición de un proceso BPMN 2.0 en XML :
1) Este fichero al ser un XML deberá de comenzar por la siguiente línea : <?xml version=»1.0″ encoding=»UTF-8″?>
2) Una vez tengamos la anterior línea incorporaremos la siguiente parte :
1 2 3 4 5 6 7 8 9 10 11 |
<definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xsi:schemaLocation="http://schema.omg.org/spec/BPMN/2.0 BPMN20.xsd" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/bpmn2.0"> <!-- Incluir aqui el proceso --> </definitions> |
El elemento raiz en un schema BPMN 2.0 es el elemento : definitions
3) Crearemos un proceso dentro de las etiquetas de definitions para ello introduciremos el siguiente código :
1 2 |
<process id="ID_PROCESO" name="NOMBRE_PROCESO"> </process> |
El elemento proceso tiene 2 atributos :
- id :Identificador que se asigna a la propiedad clave en Activiti (Es un atributo obligatorio)
- name :Nombre que de una ProcessDefinition (Es un atributo opcional)
Tipos de elementos :
– Tarea de usuario (User Task)
Es una actividad que necesita ser realizado por un actor humano (usuario o assigne en terminología
Activi). [Ver Ejemplo 1]
Cuando se crea una de estas tareas se asigna a un usuario/s o grupo.
Este tipo de tareas pueden tener asociada una descripción que se implementa mediante
el elemento : documentation [Ver Ejemplo 2].
Nota : La notacion BPMN 2.0 indica que cualquiera de sus elementos puede tener asociada
una descripción. Pero hasta la fecha solamente se puede incorporar la descripción a este tipo
de tareas.
Como son tareas asociados a un actor humano significa que podremos asociarlas de alguna forma
a alguno de los usuarios. Para ellos se utiliza el elemento : humanPerformer [Ver Ejemplo 3].
Nota : Para poder definir un usuario el elemento humanPerformer requiere del elmento resorceAssignmentExpresion
que define el usuario y este a su vez uso del elemento formalExpresion (que es la única forma que
esta soportada a día de hoy) [Ver Ejemplo 4].
Importante : únicamente se puede asociar un usuario a una User Task.
Otra cosa que se puede realizar con este tipo de tareas es la asignación a lo que se denominan usuarios
potenciales (candidatos). Para ello se utiliza el elemento : potencialOwner y requiere definir en el elemento
formalExpresion si nos estamos refiriendo a un usuario (user(XXX) o a un grupo ( group(YYY) [Ver Ejemplo 5].
Nota : Si no indicamos el tipo de elemento user o group el elemento por defecto es el grupo.
Debido a que esto puede llegar a ser un poco engorroso, se han habilitado algunos atributos de extensión
sobre el elemento userTask para simplificar al máximo esta parte.
- assigne :Asigna un usuario directamente [Ver Ejemplo 6]
- candidateUsers :Permite establecer candidatos a la tarea [Ver Ejemplo 7]
- candidateGroup :Permite establecer los grupos de las tareas [Ver Ejemplo 8]
Representación :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<!-- Ejemplo 1 : User task --> <userTask id="id_tarea" name="Nombre de la tarea" /> <!-- Ejemplo 2 :User task con descripción --> <userTask id="id_tarea_descripcion" name="Nombre de la tarea con descripcion" > <documentation>Descripcion de la tarea</documentation> </userTask> <!-- Ejemplo 3 : User task asociada al usuario Victor --> <userTask id='id_tarea_usuario' name='Nombre de la tarea con usuario asociado' > <humanPerformer> <resourceAssignmentExpression> <formalExpression>Victor</formalExpression> </resourceAssignmentExpression> </humanPerformer> </userTask> <!-- Ejemplo 4 : User task asociada a candidatos : Usuario Víctor y grupo management --> <userTask id='id_tarea_candidatos' name='Nombre de la tarea con candidatos' > <potentialOwner> <resourceAssignmentExpression> <formalExpression>user(Victor), group(management)</formalExpression> </resourceAssignmentExpression> </potentialOwner> </userTask> <!-- Ejemplo 5 : User task asociada a candidatos : grupo management por defecto --> <userTask id='id_tarea_candidatos_defecto' name='Nombre de la tarea con candidatos por defecto' > <potentialOwner> <resourceAssignmentExpression> <formalExpression>management</formalExpression> </resourceAssignmentExpression> </potentialOwner> </userTask> <!-- Ejemplo 6 : User task asociada al usuario Victor --> <!-- Simplifica el Ejemplo 3 --> <userTask id="id_tarea_usuario_2" name="Nombre de la tarea con usuario asociado 2" activiti:assignee="Victor" /> <!-- Ejemplo 7 : User task asociada al usuario Victor y Ricardo --> <!-- Simplifica el Ejemplo 4 con más de un usuario --> <userTask id="id_tarea_candidatos_2" name="Nombre de la tarea con candidatos 2" activiti:candidateUsers="Victor, Ricardo" /> <!-- Ejemplo 8 : User task asociada al grupo management y accountancy --> <!-- Simplifica el Ejemplo 4 con más de un grupo --> <userTask id="id_tarea_candidatos_3" name="Nombre de la tarea con candidatos 3" activiti:candidateGroup="management, accountancy" |
Es cierto, que faltan algunos elementos para completar esta lista pero ya los iré introduciendo en próximos
tutoriales.
4. Construir el diagrama BPM en Activiti.
Tenemos dos opciones para construir el diagrama con notación BPMN en Activiti :
1) Usando la herramienta Modeler facilitada por Activiti
Nota: Se aconseja revisar el tutorial mencionado en el punto de introducción.
Para ello generamos el diagrama anterior mediante esta herramienta.
Guardamos el modelo, por lo que quedará almacenado en el repositorio de modelos que
se encuentra disponible en el ACTIVITI_HOME/apps/activiti-model-repository pudiendo
encontrarse almacenado en algún directorio establecido (en nuestro caso Autentia).
Como podéis ver se han generado dos ficheros :
-> miProceso.bpmn20.xml
Fichero en el que se detalla de forma automática la expresión del diagrama anterior en formato
XML.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<definitions id="oryx_0795a400-7fbe-4a14-a14a-6a3436d7e832" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.omg.org/bpmn20" xmlns="http://schema.omg.org/spec/BPMN/2.0" xmlns:bpmndi="http://bpmndi.org"> <process id="oryx_e1085a90-a96e-4e1d-b8c9-35f22611e2f1"> <laneSet id="oryx_dccbe611-1435-44e1-a298-c2c06c13ab8b"> <lane name="DefaultLane" id="oryx_437f1c81-2524-4248-aca5-9a51be28a993"> <flowElementRef>oryx_383180C9-774A-4AC3-8C04-B8305EBC445E</flowElementRef> <flowElementRef>oryx_80C1A0B7-5F2E-4119-8F46-B38119A215B0</flowElementRef> <flowElementRef>oryx_AEB3AB31-D851-450B-874F-2E5807333425</flowElementRef> </lane> </laneSet> <task completionQuantity="1" startQuantity="1" isForCompensation="false" name="tarea" id="oryx_383180C9-774A-4AC3-8C04-B8305EBC445E"/> <startEvent name="inicio" id="oryx_80C1A0B7-5F2E-4119-8F46-B38119A215B0"/> <endEvent name="fin" id="oryx_AEB3AB31-D851-450B-874F-2E5807333425"/> <sequenceFlow targetRef="oryx_383180C9-774A-4AC3-8C04-B8305EBC445E" sourceRef="oryx_80C1A0B7-5F2E-4119-8F46-B38119A215B0" name="" id="oryx_7F0F5FF4-BEA1-4A8F-8B28-9BB7E22B93B2"> <conditionExpression xsi:type="tFormalExpression" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">flujo1</conditionExpression> </sequenceFlow> <sequenceFlow targetRef="oryx_AEB3AB31-D851-450B-874F-2E5807333425" sourceRef="oryx_383180C9-774A-4AC3-8C04-B8305EBC445E" name="" id="oryx_78290DC6-316E-4BAA-B73B-7CD65D7B93AE"> <conditionExpression xsi:type="tFormalExpression" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">flujo2 </conditionExpression> </sequenceFlow> </process> <bpmndi:processDiagram processRef="oryx_e1085a90-a96e-4e1d-b8c9-35f22611e2f1" id="oryx_e1085a90-a96e-4e1d-b8c9-35f22611e2f1_gui"> <bpmndi:laneCompartment isVisible="false" height="0.0" width="0.0" y="0.0" x="0.0" name="DefaultLane" id="oryx_437f1c81-2524-4248-aca5-9a51be28a993_gui"> <bpmndi:activityShape activityRef="oryx_383180C9-774A-4AC3-8C04-B8305EBC445E" height="80.0" width="100.0" y="75.0" x="195.0" name="tarea" id="oryx_383180C9-774A-4AC3-8C04-B8305EBC445E_gui"/> <bpmndi:eventShape eventRef="oryx_80C1A0B7-5F2E-4119-8F46-B38119A215B0" height="30.0" width="30.0" y="100.0" x="59.0" name="inicio" id="oryx_80C1A0B7-5F2E-4119-8F46-B38119A215B0_gui"/> <bpmndi:eventShape eventRef="oryx_AEB3AB31-D851-450B-874F-2E5807333425" height="28.0" width="28.0" y="101.0" x="386.0" name="fin" id="oryx_AEB3AB31-D851-450B-874F-2E5807333425_gui"/> </bpmndi:laneCompartment> <bpmndi:sequenceFlowConnector sequenceFlowRef="oryx_7F0F5FF4-BEA1-4A8F-8B28-9BB7E22B93B2" label="" targetRef="oryx_383180C9-774A-4AC3-8C04-B8305EBC445E_gui" sourceRef="oryx_80C1A0B7-5F2E-4119-8F46-B38119A215B0_gui" id="oryx_7F0F5FF4-BEA1-4A8F-8B28-9BB7E22B93B2_gui"/> <bpmndi:sequenceFlowConnector sequenceFlowRef="oryx_78290DC6-316E-4BAA-B73B-7CD65D7B93AE" label="" targetRef="oryx_AEB3AB31-D851-450B-874F-2E5807333425_gui" sourceRef="oryx_383180C9-774A-4AC3-8C04-B8305EBC445E_gui" id="oryx_78290DC6-316E-4BAA-B73B-7CD65D7B93AE_gui"/> </bpmndi:processDiagram> </definitions> |
Nota : A este fichero le he quitado para mostrarlo de esta forma la línea : <?xml version=»1.0″ encoding=»UTF-8″ standalone=»yes»?>
Por lo que se recuerda incorporarla si se copia este código.
Aspectos a tener en cuenta de este fichero :
- El código ha sido generado automáticamente por lo que puede haber cosas que no nos faciliten su entendimiento (como casi siempre
que utilizamos un herramienta que genera código de forma automática 🙂 ) - Los identificadores que ha generado han sido automáticos por lo que no son demasiado intuitivos
- El orden de declaración de los elementos sigue su estructura interna
- Etc…
-> miProceso.oryx.xml
Fichero utilizado para definir el modelo.
1 2 3 4 5 6 |
<oryxmodel> <description></description> <type>BPMN 2.0</type> <json-representation><![CDATA[{"resourceId":"canvas","properties":{"name":"","documentation":"","auditing":"","monitoring":"","version":"","author":"","language":"English","namespaces":"","targetnamespace":"http://www.omg.org/bpmn20","expressionlanguage":"http://www.w3.org/1999/XPath","typelanguage":"http://www.w3.org/2001/XMLSchema","creationdate":"","modificationdate":""},"stencil":{"id":"BPMNDiagram"},"childShapes":[{"resourceId":"oryx_383180C9-774A-4AC3-8C04-B8305EBC445E","properties":{"name":"tarea","documentation":"","auditing":"","monitoring":"","categories":"","startquantity":1,"completionquantity":1,"isforcompensation":"","assignments":"","callacitivity":"","tasktype":"None","implementation":"webService","resources":"","messageref":"","operationref":"","instantiate":"","script":"","script_language":"","bgcolor":"#ffffcc","looptype":"None","testbefore":"","loopcondition":"","loopmaximum":"","loopcardinality":"","loopdatainput":"","loopdataoutput":"","inputdataitem":"","outputdataitem":"","behavior":"all","complexbehaviordefinition":"","completioncondition":"","onebehavioreventref:":"signal","nonebehavioreventref":"signal","properties":"","datainputset":"","dataoutputset":"","operationname":"","inmessagename":"","inmsgitemkind":"Information","inmsgstructure":"","inmsgimport":"","inmsgiscollection":"","outmessagename":"","outmsgitemkind":"Information","outmsgstructure":"","outmsgimport":"","outmsgiscollection":""},"stencil":{"id":"Task"},"childShapes":[],"outgoing":[{"resourceId":"oryx_78290DC6-316E-4BAA-B73B-7CD65D7B93AE"}],"bounds":{"lowerRight":{"x":295,"y":155},"upperLeft":{"x":195,"y":75}},"dockers":[]},{"resourceId":"oryx_80C1A0B7-5F2E-4119-8F46-B38119A215B0","properties":{"name":"inicio","documentation":"","auditing":"","monitoring":"","eventdefinitionref":"","eventdefinitions":"","dataoutputassociations":"","dataoutput":"","outputset":"","bgcolor":"#ffffff","trigger":"None"},"stencil":{"id":"StartNoneEvent"},"childShapes":[],"outgoing":[{"resourceId":"oryx_7F0F5FF4-BEA1-4A8F-8B28-9BB7E22B93B2"}],"bounds":{"lowerRight":{"x":89,"y":130},"upperLeft":{"x":59,"y":100}},"dockers":[]},{"resourceId":"oryx_AEB3AB31-D851-450B-874F-2E5807333425","properties":{"name":"fin","documentation":"","auditing":"","monitoring":"","eventdefinitionref":"","eventdefinitions":"","datainputassociations":"","datainput":"","inputset":"","bgcolor":"#ffffff","trigger":"None"},"stencil":{"id":"EndNoneEvent"},"childShapes":[],"outgoing":[],"bounds":{"lowerRight":{"x":414,"y":129},"upperLeft":{"x":386,"y":101}},"dockers":[]},{"resourceId":"oryx_7F0F5FF4-BEA1-4A8F-8B28-9BB7E22B93B2","properties":{"name":"","documentation":"","auditing":"","monitoring":"","conditiontype":"None","conditionexpression":"flujo1","isimmediate":"","showdiamondmarker":""},"stencil":{"id":"SequenceFlow"},"childShapes":[],"outgoing":[{"resourceId":"oryx_383180C9-774A-4AC3-8C04-B8305EBC445E"}],"bounds":{"lowerRight":{"x":194.5703125,"y":116},"upperLeft":{"x":89.6953125,"y":114}},"dockers":[{"x":15,"y":15},{"x":50,"y":40}],"target":{"resourceId":"oryx_383180C9-774A-4AC3-8C04-B8305EBC445E"}},{"resourceId":"oryx_78290DC6-316E-4BAA-B73B-7CD65D7B93AE","properties":{"name":"","documentation":"","auditing":"","monitoring":"","conditiontype":"None","conditionexpression":"flujo2\n","isimmediate":"","showdiamondmarker":""},"stencil":{"id":"SequenceFlow"},"childShapes":[],"outgoing":[{"resourceId":"oryx_AEB3AB31-D851-450B-874F-2E5807333425"}],"bounds":{"lowerRight":{"x":385.6796875,"y":116},"upperLeft":{"x":295.6484375,"y":114}},"dockers":[{"x":50,"y":40},{"x":14,"y":14}],"target":{"resourceId":"oryx_AEB3AB31-D851-450B-874F-2E5807333425"}}],"bounds":{"lowerRight":{"x":1485,"y":1050},"upperLeft":{"x":0,"y":0}},"stencilset":{"url":"/activiti-modeler/editor/stencilsets//bpmn2.0/bpmn2.0.json","namespace":"http://b3mn.org/stencilset/bpmn2.0#"},"ssextensions":[]}]]></json-representation> <svg-representation><![CDATA[<svg xmlns="http://www.w3.org/2000/svg" xmlns:oryx="http://oryx-editor.org" id="oryx_1C8769F0-5402-413D-9361-482506E2C7F3" width="405" height="130" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg"><defs><marker id="oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222start" refX="1" refY="5" markerUnits="userSpaceOnUse" markerWidth="17" markerHeight="11" orient="auto"> <path id="oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222conditional" d="M 0 5 L 8 0 L 16 5 L 8 10 L 0 5" fill="white" stroke="black" stroke-width="1" display="none"/> <path id="oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222default" d="M 5 0 L 11 10" fill="white" stroke="black" stroke-width="1" display="none"/> </marker><marker id="oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222end" refX="15" refY="6" markerUnits="userSpaceOnUse" markerWidth="15" markerHeight="12" orient="auto"> <path d="M 0 1 L 15 6 L 0 11z" fill="black" stroke="black" stroke-linejoin="round" stroke-width="2" id="oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222_oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222_2"/> </marker><marker id="oryx_333BEBD0-6C94-4312-9218-1FC70196B5FCstart" refX="1" refY="5" markerUnits="userSpaceOnUse" markerWidth="17" markerHeight="11" orient="auto"> <path id="oryx_333BEBD0-6C94-4312-9218-1FC70196B5FCconditional" d="M 0 5 L 8 0 L 16 5 L 8 10 L 0 5" fill="white" stroke="black" stroke-width="1" display="none"/> <path id="oryx_333BEBD0-6C94-4312-9218-1FC70196B5FCdefault" d="M 5 0 L 11 10" fill="white" stroke="black" stroke-width="1" display="none"/> </marker><marker id="oryx_333BEBD0-6C94-4312-9218-1FC70196B5FCend" refX="15" refY="6" markerUnits="userSpaceOnUse" markerWidth="15" markerHeight="12" orient="auto"> <path d="M 0 1 L 15 6 L 0 11z" fill="black" stroke="black" stroke-linejoin="round" stroke-width="2" id="oryx_333BEBD0-6C94-4312-9218-1FC70196B5FC_oryx_333BEBD0-6C94-4312-9218-1FC70196B5FC_2"/> </marker></defs><g stroke="black" font-family="Verdana, sans-serif" font-size-adjust="none" font-style="normal" font-variant="normal" font-weight="normal" line-heigth="normal" font-size="12"><g class="stencils" transform="translate(-34, -50)"><g class="me"/><g class="children"><g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD"><g class="stencils" transform="translate(195, 75)"><g class="me"><g pointer-events="fill" oryx:minimumSize="50 40" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD" title="Task"> <defs id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_17"> <radialGradient id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDbackground" cx="10%" cy="10%" r="100%" fx="10%" fy="10%"> <stop offset="0%" stop-color="#ffffff" stop-opacity="1" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_18"/> <stop id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDfill_el" offset="100%" stop-color="#ffffcc" stop-opacity="1"/> </radialGradient> </defs> <rect id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDtext_frame" oryx:anchors="bottom top right left" x="1" y="1" width="94" height="79" rx="10" ry="10" stroke="none" stroke-width="0" fill="none"/> <rect id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDcallActivity" oryx:resize="vertical horizontal" oryx:anchors="bottom top right left" x="0" y="0" width="100" height="80" rx="10" ry="10" stroke="black" stroke-width="4" fill="none" display="none"/> <rect id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDbg_frame" oryx:resize="vertical horizontal" x="0" y="0" width="100" height="80" rx="10" ry="10" stroke="black" stroke-width="1" fill="url(#oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDbackground) #ffffcc"/> <text font-size="12" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDtext_name" x="50" y="40" oryx:align="middle center" oryx:fittoelem="text_frame" stroke="black" stroke-width="0pt" letter-spacing="-0.01px" text-anchor="middle" transform="rotate(0, 50, 40)" visibility="inherit" oryx:fontSize="12"><tspan x="50" y="40" dy="5" id="ext-gen561">tarea</tspan></text> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDmanualTask" transform="scale(0.7) translate(8, 8)" display="none"> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDhand" style="opacity: 1; fill: none; fill-opacity: 1; stroke: rgb(0, 0, 0); stroke-width: 1;" d="M0.5,3.751l4.083-3.25c0,0,11.166,0.083,12.083,0.083s-2.417,2.917-1.5,2.917 s11.667,0,12.584,0c1.166,1.708-0.168,3.167-0.834,3.667s0.875,1.917-1,4.417c-0.75,0.25,0.75,1.875-1.333,3.333 c-1.167,0.583,0.583,1.542-1.25,2.833c-1.167,0-20.833,0.083-20.833,0.083l-2-1.333V3.751z"/> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDfinger" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0); stroke-width: 2;" d="M 13.5 7 L 27 7"/> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDfinger1" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0); stroke-width: 2;" d="M 13.5 11 L 26 11"/> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDfinger2" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0); stroke-width: 1.5;" d="M 14 14.5 L 25 14.5"/> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDthumb" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0); stroke-width: 1.5;" d="M 8.2 3.1 L 15 3.1"/> </g> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDbusinessRuleTask" transform="scale(0.7) translate(8, 8)" display="none"> <rect oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDtop" x="0" y="0" width="22" height="4" style="opacity: 1; fill: rgb(179, 177, 179); fill-opacity: 1; stroke: rgb(0, 0, 0);"/> <rect oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDrect" x="0" y="4" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0);" width="22" height="12"/> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDrow" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0);" d="M 0 10 L 22 10"/> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDcol" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0);" d="M 7 4 L 7 16"/> </g> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDscriptTask" transform="scale(0.7) translate(8, 8)" display="none"> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDpaper" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0);" d="M6.402,0.5h14.5c0,0-5.833,2.833-5.833,5.583s4.417,6,4.417,9.167 s-4.167,5.083-4.167,5.083H0.235c0,0,5-2.667,5-5s-4.583-6.75-4.583-9.25S6.402,0.5,6.402,0.5z"/> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDline1" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0); stroke-width: 1.5;" d="M 3.5 4.5 L 13.5 4.5"/> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDline2" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0); stroke-width: 1.5;" d="M 3.8 8.5 L 13.8 8.5"/> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDline3" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0); stroke-width: 1.5;" d="M 6.3 12.5 L 16.3 12.5"/> <path oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDline4" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0); stroke-width: 1.5;" d="M 6.5 16.5 L 16.5 16.5"/> </g> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDuserTask" transform="scale(0.7) translate(8, 8)" display="none"> <path oryx:anchors="top left" style="opacity: 1; fill: rgb(244, 246, 247); stroke: rgb(0, 0, 0);" d="M0.585,24.167h24.083v-7.833c0,0-2.333-3.917-7.083-5.167h-9.25 c-4.417,1.333-7.833,5.75-7.833,5.75L0.585,24.167z" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_19"/> <path oryx:anchors="top left" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0);" d="M 6 20 L 6 24" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_20"/> <path oryx:anchors="top left" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0);" d="M 20 20 L 20 24" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_21"/> <circle oryx:anchors="top left" fill="#000000" stroke="#000000" cx="13.002" cy="5.916" r="5.417" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_22"/> <path oryx:anchors="top left" style="opacity: 1; fill: rgb(240, 239, 240); stroke: rgb(0, 0, 0);" d="M8.043,7.083c0,0,2.814-2.426,5.376-1.807s4.624-0.693,4.624-0.693 c0.25,1.688,0.042,3.75-1.458,5.584c0,0,1.083,0.75,1.083,1.5s0.125,1.875-1,3s-5.5,1.25-6.75,0S8.668,12.834,8.668,12 s0.583-1.25,1.25-1.917C8.835,9.5,7.419,7.708,8.043,7.083z" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_23"/> </g> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDserviceTask" transform="scale(0.7) translate(8, 8)" display="none"> <polygon oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDteethForeground" style="opacity: 1; fill: rgb(255, 255, 255); stroke: rgb(0, 0, 0);" points="15.392,5.064 17.954,2.502 20.347,4.895 17.786,7.455 18.729,9.732 22.353,9.732 22.353,13.115 18.731,13.115 17.788,15.392 20.351,17.955 17.958,20.347 15.397,17.786 13.12,18.729 13.12,22.353 9.737,22.353 9.737,18.731 7.46,17.788 4.897,20.35 2.506,17.958 5.066,15.397 4.124,13.12 0.5,13.12 0.5,9.737 4.121,9.737 5.065,7.461 2.503,4.898 4.895,2.506 7.455,5.066 9.732,4.125 9.732,0.5 13.116,0.5 13.116,4.121"/> <circle oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDringForeground" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0);" cx="11.427" cy="11.426" r="3.714"/> <polygon oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDteethBackground" style="opacity: 1; fill: rgb(255, 255, 255); stroke: rgb(0, 0, 0);" points="21.392,11.064 23.954,8.502 26.347,10.895 23.786,13.455 24.729,15.732 28.353,15.732 28.353,19.115 24.731,19.115 23.788,21.392 26.351,23.955 23.958,26.347 21.397,23.786 19.12,24.729 19.12,28.353 15.737,28.353 15.737,24.731 13.46,23.788 10.897,26.35 8.506,23.958 11.066,21.397 10.124,19.12 6.5,19.12 6.5,15.737 10.121,15.737 11.065,13.461 8.503,10.898 10.895,8.506 13.455,11.066 15.732,10.125 15.732,6.5 19.116,6.5 19.116,10.121"/> <circle oryx:anchors="top left" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDringBackground" style="opacity: 1; fill: none; stroke: rgb(0, 0, 0);" cx="17.427" cy="17.426" r="3.714"/> </g> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDsendTask" display="none"> <path oryx:anchors="left top" stroke="white" fill="black" stroke-width="1" d="M8,11 L8,21 L24,21 L24,11 L16,17z" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_24"/> <path oryx:anchors="left top" stroke="white" fill="black" stroke-width="1" d="M7,10 L16,17 L25 10z" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_25"/> </g> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDreceiveTask" display="none"> <path oryx:anchors="left top" stroke="black" fill="none" stroke-width="1" d="M8,11 L8,21 L24,21 L24,11z M8,11 L16,17 L24,11" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_26"/> </g> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDnone" display="inherit"/> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDloop" display="none"> <path oryx:anchors="bottom" style="opacity: 1; fill: none; fill-opacity: 1; stroke: rgb(0, 0, 0); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; stroke-miterlimit: 2.1; stroke-dasharray: none; stroke-opacity: 1;" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDpath2396" d="M 47.608384,75.188343 L 47.608384,78.188343 L 44.608384,78.188343 M 47.608384,78.188343 A 4.875,4.875 0 1 1 51.639336,78.189378"/> </g> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDparallel" display="none"> <path oryx:anchors="bottom" fill="none" stroke="black" d="M46 70 v8 M50 70 v8 M54 70 v8" stroke-width="2" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_27"/> </g> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDsequential" display="none"> <path oryx:anchors="bottom" fill="none" stroke="#000000" stroke-width="2" d="M46,76h10M46,72h10 M46,68h10" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_28"/> </g> <g id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FDcompensation" display="none"> <path oryx:anchors="bottom" fill="none" stroke="black" d="M 62 74 L 66 70 L 66 78 L 62 74 L 62 70 L 58 74 L 62 78 L 62 74" stroke-width="1" id="oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_oryx_E4377EEC-FBC0-4B68-9272-4C67530035FD_29"/> </g> </g></g><g class="children" style="overflow: hidden;"/><g class="edge"/></g><g class="controls"><g class="dockers"/><g class="magnets" transform="translate(195, 75)"><g pointer-events="all" display="none" transform="translate(-7, 12)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(-7, 32)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(-7, 52)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(17, 71)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(42, 71)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(67, 71)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(91, 12)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(91, 32)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(91, 52)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(17, -7)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(42, -7)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(67, -7)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g><g pointer-events="all" display="none" transform="translate(42, 32)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g></g></g></g><g id="oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3C"><g class="stencils" transform="translate(59, 100)"><g class="me"><g pointer-events="fill" id="oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3C" title="Start Event"> <defs id="oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3C_oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3C_5"> <radialGradient id="oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3Cbackground" cx="10%" cy="10%" r="100%" fx="10%" fy="10%"> <stop offset="0%" stop-color="#ffffff" stop-opacity="1" id="oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3C_oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3C_6"/> <stop id="oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3Cfill_el" offset="100%" stop-color="#ffffff" stop-opacity="1"/> </radialGradient> </defs> <circle id="oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3Cbg_frame" cx="15" cy="15" r="15" stroke="black" fill="url(#oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3Cbackground) white" stroke-width="1"/> <text font-size="11" id="oryx_E16307B3-7C18-4CEF-BACC-0B18FBBDEC3Ctext_name" x="15" y="32" oryx:align="top center" stroke="black" stroke-width="0pt" letter-spacing="-0.01px" text-anchor="middle" transform="rotate(0, 15, 32)" visibility="inherit" oryx:fontSize="11"><tspan x="15" y="32" dy="11" id="ext-gen570">inicio</tspan></text> </g></g><g class="children" style="overflow: hidden;"/><g class="edge"/></g><g class="controls"><g class="dockers"/><g class="magnets" transform="translate(59, 100)"><g pointer-events="all" display="none" transform="translate(7, 7)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g></g></g></g><g id="oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DE"><g class="stencils" transform="translate(386, 101)"><g class="me"><g pointer-events="fill" id="oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DE" title="End Event"> <defs id="oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DE_oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DE_5"> <radialGradient id="oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DEbackground" cx="10%" cy="10%" r="100%" fx="10%" fy="10%"> <stop offset="0%" stop-color="#ffffff" stop-opacity="1" id="oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DE_oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DE_6"/> <stop id="oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DEfill_el" offset="100%" stop-color="#ffffff" stop-opacity="1"/> </radialGradient> </defs> <circle id="oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DEbg_frame" cx="14" cy="14" r="14" stroke="black" fill="url(#oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DEbackground) white" stroke-width="3"/> <text font-size="11" id="oryx_D2DB9AFA-E5EE-4CF3-97B8-0362CA0D14DEtext_name" x="14" y="30" oryx:align="top center" stroke="black" stroke-width="0pt" letter-spacing="-0.01px" text-anchor="middle" transform="rotate(0, 14, 30)" visibility="inherit" oryx:fontSize="11"><tspan x="14" y="30" dy="11">fin</tspan></text> </g></g><g class="children" style="overflow: hidden;"/><g class="edge"/></g><g class="controls"><g class="dockers"/><g class="magnets" transform="translate(386, 101)"><g pointer-events="all" display="none" transform="translate(6, 6)"><circle cx="8" cy="8" r="4" stroke="none" fill="red" fill-opacity="0.3"/></g></g></g></g></g><g class="edge"><g id="oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222"><g class="stencils"><g class="me" title="Sequence Flow"><g pointer-events="painted"><path d="M89.6953125 115L194.5703125 115 " stroke="black" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" marker-start="url(#oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222start)" marker-end="url(#oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222end)" id="oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222_1"/></g><text id="oryx_A829D497-36A5-45EE-B3C4-78A1E0C0F222condition" x="103.695" y="101" oryx:edgePosition="startTop" stroke-width="0pt" letter-spacing="-0.01px" text-anchor="start" transform="rotate(360, 89.6953, 115)" visibility="inherit" oryx:fontSize="12"><tspan x="103.695" y="101" dy="0" id="ext-gen610">flujo1</tspan></text></g><g class="children" style="overflow: hidden;"/><g class="edge"/></g><g class="controls"><g class="dockers"/><g class="magnets"/></g></g><g id="oryx_333BEBD0-6C94-4312-9218-1FC70196B5FC"><g class="stencils"><g class="me" title="Sequence Flow"><g pointer-events="painted"><path d="M295.6484375 115L385.6796875 115 " stroke="black" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" marker-start="url(#oryx_333BEBD0-6C94-4312-9218-1FC70196B5FCstart)" marker-end="url(#oryx_333BEBD0-6C94-4312-9218-1FC70196B5FCend)" id="oryx_333BEBD0-6C94-4312-9218-1FC70196B5FC_1"/></g><text id="oryx_333BEBD0-6C94-4312-9218-1FC70196B5FCcondition" x="309.648" y="101" oryx:edgePosition="startTop" stroke-width="0pt" letter-spacing="-0.01px" text-anchor="start" transform="rotate(360, 295.648, 115)" visibility="inherit" oryx:fontSize="12"><tspan x="309.648" y="101" dy="0">flujo2</tspan></text></g><g class="children" style="overflow: hidden;"/><g class="edge"/></g><g class="controls"><g class="dockers"/><g class="magnets"/></g></g></g></g></g></svg>]]></svg-representation> </oryxmodel> |
Nota : A este fichero le he quitado para mostrarlo de esta forma la línea : <?xml version=»1.0″ encoding=»utf-8″?>
Por lo que se recuerda incorporarla si se copia este código.
2) Definiendo el diagrama en un XML
Fichero en el que una vez conocemos la notación en XML podemos definir los diagramas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<definitions id="ejemploMiPrimerProceso" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/bpmn2.0"> <process id='miProceso' name="Mi primer proceso"> <startEvent id='inicio' /> <sequenceFlow id='flujo1' sourceRef='inicio' targetRef='tarea' /> <userTask id='tarea' name='Mi primera tarea' > <documentation>Descripcion tarea</documentation> <humanPerformer> <resourceAssignmentExpression> <formalExpression>victor</formalExpression> </resourceAssignmentExpression> </humanPerformer> </userTask> <sequenceFlow id='flujo2' sourceRef='tarea' targetRef='fin' /> <endEvent id='fin' /> </process> </definitions> |
Nota : A este fichero le he quitado para mostrarlo de esta forma la línea : <?xml version=»1.0″ encoding=»UTF-8″?>
Por lo que se recuerda incorporarla si se copia este código.
5. Creación de la librería de Activi en Eclipse.
En este punto se enseñará a crear la librería de Activi de la que hará uso nuestro proyecto :
PASO 1 : Accedemos desde Eclipse a Windows -> Preference
PASO 2 : Seleccionamos Java -> Build Path -> User Libraries
PASO 3 : Introducimos una nueva librería mediante la opción New… a la que denominamos Activi
Una vez aceptado se creará la biblioteca pero estará vacia de contenido
PASO 4 : Incorporarmos los JAR del proyeco Activi, para ellos seleccionamos la opcion Add JARs… y añadimos todas las
librerias que se encuentran en el directorio de instalacion de Activi salvo las que contienen «-sources»
Situación final de la librería :
6. Configuración del esquema BPMN 2.0 en Eclipse.
En este punto se enseñará a configurar el esquema de BPMN 2.0 en el catálogo de XML de Eclipse
PASO 1 : Accedemos desde Eclipse a Windows -> Preference
PASO 2 : Seleccionamos XML -> XML Catalog
PASO 3 : Introducimos un nuevo esquema en los catalogos definidos de Eclipse pulsando sobre Add… y
seleccionando el fichero BPMN20.xsd que se encuentran en directorio de instalación de Activiti /docs/xsd/BPMN20.xsd
PASO 4 : Verificar que ha sido incluido
7. Probar nuestro proceso con JUnit.
Para poder probar nuestro proceso tendremos que crear un test en JUnit, para ello seguiremos los
siguienes pasos :
PASO 1 : Creamos un nuevo proyecto de Java Básico , en mi caso «Proyecto_Activi».
PASO 2 : Incluimos la librería de Activiti que ha sido creada anteriormente.
PASO 3 : Creamos un paquete en src que se denomine : com.acme.activiti.ejemplo1
PASO 4 : Creamos en el interior del paquete un fichero : MiProceso.bpmn20.xml
Le incorporamos el siguiente contenido que ha sido definido manualmente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<definitions id="ejemploMiPrimerProceso" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/bpmn2.0"> <process id='miProceso' name="Mi primer proceso"> <startEvent id='inicio' /> <sequenceFlow id='flujo1' sourceRef='inicio' targetRef='tarea' /> <userTask id='tarea' name='Mi primera tarea' > <documentation>Descripcion tarea</documentation> <humanPerformer> <resourceAssignmentExpression> <formalExpression>victor</formalExpression> </resourceAssignmentExpression> </humanPerformer> </userTask> <sequenceFlow id='flujo2' sourceRef='tarea' targetRef='fin' /> <endEvent id='fin' /> </process> </definitions> |
Nota : A este fichero le he quitado para mostrarlo de esta forma la línea : <?xml version=»1.0″ encoding=»UTF-8″?>
Por lo que se recuerda incorporarla si se copia este código.
PASO 5 : Creamos en el nivel de src el fichero : activiti.properties
Este fichero contendrá el siguiente contenido :
1 2 3 4 5 6 7 |
database=h2 jdbc.driver=org.h2.Driver jdbc.url=jdbc:h2:mem:activiti jdbc.username=sa jdbc.password= db.schema.strategy=create-drop job.executor.auto.activate=off |
Este fichero configura el uso de la base de datos H2 que como se puede ver se ejecutará en
memoria y cada vez será creada-borrada.
PASO 6 : Creamos un test de JUnit para probar nuestro proceso en el paquete anterior : MiProcesoTest
Este fichero contendrá las comprobaciones para verficar que es nuestro proceso :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
package com.acme.activiti.ejemplo1; import static org.junit.Assert.assertEquals; import java.util.List; import org.activiti.ProcessInstance; import org.activiti.Task; import org.activiti.test.ProcessDeclared; import org.activiti.test.ProcessDeployer; import org.junit.Rule; import org.junit.Test; public class MiProcesoTest { /** * Se encarga de lanzar el proceso */ @Rule public ProcessDeployer deployer = new ProcessDeployer(); /** * Test que prueba nuestro proceso * Se le indica el proceso mediante la anotacion @ProcessDeclares */ @Test @ProcessDeclared(resources={"MiProceso.bpmn20.xml"}) public void testMiProceso() { //Inicia la instancia del proceso definido en base a su identificador ProcessInstance processInstance = deployer.getProcessService().startProcessInstanceByKey("miProceso"); //Comprobación de si la instancia del proceso ha sido completada deployer.expectProcessEnds(processInstance.getId()); //Muestra información sobre la instancia del proceso System.out.println("[PROCESO] id :"+processInstance.getId()+" | process definition id :"+processInstance.getProcessDefinitionId()+"\n"); //Devuelve la lista de tareas asignadas a victor y verífica que solamente hay una (La indicada en el proceso) List<Task> tasksAssigned = deployer.getTaskService().findAssignedTasks("victor"); System.out.println("Lista de tareas asignadas a victor...\t: "+tasksAssigned.size()+" tareas"); assertEquals(1, tasksAssigned.size()); //Devuelve la lista de tareas que no asignadas a victor y verifica que no hay ninguna List<Task> tasksUnassigned = deployer.getTaskService().findUnassignedTasks("victor"); System.out.println("Lista de tareas NO asignadas a victor...\t: "+tasksUnassigned.size()+" tareas"); assertEquals(0, tasksUnassigned.size()); //Lista de tareas asignadas if (!tasksAssigned.isEmpty()){ //Mostrar las tareas asignadas System.out.println("\nLista de tareas asignadas a victor..."); for (Task t : tasksAssigned){ System.out.println("[TAREA] id :"+t.getId()+" | name :"+t.getName()+" | process definition id :"+t.getProcessDefinitionId()+" | assignee :"+t.getAssignee()); } //Verificar que la primera tarea es la establecida Task myTask = tasksAssigned.get(0); assertEquals("Mi primera tarea", myTask.getName()); assertEquals("Descripcion tarea", myTask.getDescription()); // Completar la tarea por lo que el proceso habrá finalizado deployer.getTaskService().complete(myTask.getId()); } } } |
PASO 7 : Ejecutamos el test
Con la ejecución de este test verificaremos que hemos realizado bien nuestro proceso,
aunque no tiene demasiado misterio nuestro proceso debido a que era muy sencillito 😉
8. Conclusiones.
Como habéis podido comprobar esto del BPM tiene su miga y más si empezamos a hacer cosas
un poquito serías.Prometo empezar a complicar los modelos en los próximos tutoriales para que
asi podáis ver la potencia de esta gran herramienta.Espero haberos podido ayudar a entender un
poquito mejor como funciona Activiti a la hora de implementar y utilizar los modelos.
Hola gracias por tu aporte en activiti, estoy empezando a manejar esta herramienta BPM, y aun tengo muchas dudas, agradecería mas información de como crear procesos que pidan llenar formularios para seguir con la siguiente actividad….. por favor
Estoy en las mismas, quiiero saber como asociar formularios personalizados a una tarea.
hola gente alguno o pudo hacer en netbeans….en eclipse no se pero no me anda…hay algún tutorial en español