2016-04-19 10 views
0

私の質問はとても簡単です。どのようにしてbpmnファイルを解析できますか?これを行うためにJavaにパッケージがありますか? 私はグーグルでサンプルコードを見つけましたが、mainはなく、bpmnファイルを解析して解析する方法はありません。BPMNファイルの解析

import java.net.URL; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.Enumeration; 
import java.util.List; 

import javax.xml.namespace.QName; 

import org.w3c.dom.Element; 

import org.jbpm.api.JbpmException; 
import org.jbpm.api.activity.ActivityBehaviour; 
import org.jbpm.bpmn.common.Resource; 
import org.jbpm.bpmn.common.ResourceParameter; 
import org.jbpm.bpmn.flownodes.BpmnActivity; 
import org.jbpm.bpmn.model.BpmnProcessDefinition; 
import org.jbpm.bpmn.model.SequenceflowCondition; 
import org.jbpm.bpmn.parser.BindingsParser; 
import org.jbpm.internal.log.Log; 
import org.jbpm.pvm.internal.cal.CronExpression; 
import org.jbpm.pvm.internal.cal.Duration; 
import org.jbpm.pvm.internal.env.EnvironmentImpl; 
import org.jbpm.pvm.internal.model.ActivityImpl; 
import org.jbpm.pvm.internal.model.CompositeElementImpl; 
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl; 
import org.jbpm.pvm.internal.model.ScopeElementImpl; 
import org.jbpm.pvm.internal.model.TimerDefinitionImpl; 
import org.jbpm.pvm.internal.model.TransitionImpl; 
import org.jbpm.pvm.internal.model.VariableDefinitionImpl; 
import org.jbpm.pvm.internal.task.TaskDefinitionImpl; 
import org.jbpm.pvm.internal.util.CollectionUtil; 
import org.jbpm.pvm.internal.util.TagBinding; 
import org.jbpm.pvm.internal.util.XmlUtil; 
import org.jbpm.pvm.internal.xml.Bindings; 
import org.jbpm.pvm.internal.xml.Parse; 
import org.jbpm.pvm.internal.xml.Parser; 

public class BpmnParser extends Parser { 

    private static final Log log = Log.getLog(BpmnParser.class.getName()); 

    private static final String[] DEFAULT_ACTIVITIES_RESOURCES = { "jbpm.bpmn.flownodes.xml" }; 
    private static final String CATEGORY_ACTIVITY = "activity"; 
    private static final String[] SCHEMA_RESOURCES = { "BPMN20.xsd", "DiagramDefinition.xsd", 
    "DiagramInterchange.xsd", "BpmnDi.xsd" }; 

    static BindingsParser bindingsParser = new BindingsParser(); 

    public BpmnParser() { 
    // initialises bindings 
    parseBindings(); 
    // Setting BPMN2 xsd schema 
    setSchemaResources(SCHEMA_RESOURCES); 
    } 

    public Object parseDocumentElement(Element documentElement, Parse parse) { 
    List<ProcessDefinitionImpl> processDefinitions = new ArrayList<ProcessDefinitionImpl>(); 

    parseDefinition(documentElement, parse); 

    for (Element processElement : XmlUtil.elements(documentElement, "process")) { 
     ProcessDefinitionImpl processDefinition = parseProcess(processElement, parse); 
     processDefinitions.add(processDefinition); 
    } 

    return processDefinitions; 
    } 

    public ProcessDefinitionImpl parseProcess(Element processElement, Parse parse) { 
    BpmnProcessDefinition processDefinition = new BpmnProcessDefinition(); 

    parse.contextStackPush(processDefinition); 
    try { 

     String id = XmlUtil.attribute(processElement, "id", parse); 
     String name = XmlUtil.attribute(processElement, "name"); 

     if (id != null && !"".equals(id)) { 
     processDefinition.setName(id); 
     } else { 
     parse.addProblem("Process has no or an empty id"); 
     } 

     if (name != null) { 
     processDefinition.setKey(name); 
     } 

     Element descriptionElement = XmlUtil.element(processElement, "documentation"); 
     if (descriptionElement != null) { 
     String description = XmlUtil.getContentText(descriptionElement); 
     processDefinition.setDescription(description); 
     } 

     parseResources((Element)processElement.getParentNode(), parse, processDefinition); 

     parseInterfaces((Element)processElement.getParentNode(), parse, processDefinition); 

     parseItemDefinitions((Element)processElement.getParentNode(), parse, processDefinition); 

     parseMessages((Element)processElement.getParentNode(), parse, processDefinition); 

     parseDataObjects(processElement, parse, processDefinition); 

     // activities 
     parseActivities(processElement, parse, processDefinition); 

     // bind activities to their destinations 
     parseSequenceFlow(processElement, parse, processDefinition); 

    } finally { 
     parse.contextStackPop(); 
    } 

    return processDefinition; 
    } 

    // ///////////////////////////////////////////////////////////////////////////////////////// 

    protected void parseBindings() { 
    Bindings bindings = new Bindings(); 
    setBindings(bindings); 

    for (String activityResource : DEFAULT_ACTIVITIES_RESOURCES) { 
     Enumeration<URL> resourceUrls = getResources(activityResource); 
     if (resourceUrls.hasMoreElements()) { 
     while (resourceUrls.hasMoreElements()) { 
      URL resourceUrl = resourceUrls.nextElement(); 
      log.trace("loading bpmn activities from resource: " + resourceUrl); 
      List<?> activityBindings = (List<?>) bindingsParser.createParse() 
      .setUrl(resourceUrl) 
      .execute() 
      .checkErrors("bpmn activities from " + resourceUrl.toString()) 
      .getDocumentObject(); 

      for (TagBinding binding: CollectionUtil.checkList(activityBindings, TagBinding.class)) { 
      binding.setCategory(CATEGORY_ACTIVITY); 
      bindings.addBinding(binding); 
      } 
     } 
     } else { 
     log.trace("skipping unavailable activities resource: " + activityResource); 
     } 
    } 
    } 

    protected Enumeration<URL> getResources(String resourceName) { 
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
    Enumeration<URL> resourceUrls; 
    try { 
     resourceUrls = classLoader.getResources(resourceName); 

     if (!resourceUrls.hasMoreElements()) { 
     resourceUrls = BpmnParser.class.getClassLoader().getResources(resourceName); 
     } 
    } catch (Exception e) { 
     throw new JbpmException("couldn't get resource urls for "+resourceName, e); 
    } 
    return resourceUrls; 
    } 

    private void parseDataObjects(Element element, Parse parse, BpmnProcessDefinition processDefinition) { 
    List<VariableDefinitionImpl> variableDefinitions = new ArrayList<VariableDefinitionImpl>(); 

    for (Element dataElement : XmlUtil.elements(element, "dataObject")) { 
     VariableDefinitionImpl variableDefinition = new VariableDefinitionImpl(); 

     String name = XmlUtil.attribute(dataElement, "id", parse); 
     variableDefinition.setName(name); 

     String typeRef = XmlUtil.attribute(dataElement, "itemSubjectRef"); 
     variableDefinition.setTypeName(processDefinition.getType(typeRef)); 

     variableDefinitions.add(variableDefinition); 
    } 

    processDefinition.setVariableDefinition(variableDefinitions); 
    } 

    public void parseActivities(Element element, Parse parse, CompositeElementImpl compositeElement) { 
    List<Element> elements = XmlUtil.elements(element); 
    for (Element nestedElement : elements) { 
     String tagName = nestedElement.getLocalName(); 
     String name = XmlUtil.attribute(nestedElement, "name"); 
     String id = XmlUtil.attribute(nestedElement, "id", parse); 

     TagBinding activityBinding = (TagBinding) getBinding(nestedElement, CATEGORY_ACTIVITY); 
     if (activityBinding == null) { 
     if (!"sequenceFlow".equals(tagName)) { 
      log.debug("unrecognized activity: " + tagName); 
     } 
     continue; 
     } 

     ActivityImpl activity = compositeElement.createActivity(); 
     parse.contextStackPush(activity); 
     try { 
     activity.setType(activityBinding.getTagName()); 
     activity.setName(id); 
     activity.setDescription(name); 

     if (log.isDebugEnabled()) { 
      log.debug("Parsing Activity: " + name + "(id=" + id + ")"); 
     } 

     ActivityBehaviour activityBehaviour = (ActivityBehaviour) activityBinding.parse(nestedElement, parse, this); 
     activity.setActivityBehaviour(activityBehaviour); 
     } finally { 
     parse.contextStackPop(); 
     } 
    } 
    } 

    public void parseSequenceFlow(Element element, Parse parse, BpmnProcessDefinition processDefinition) { 
    List<Element> transitionElements = XmlUtil.elements(element, "sequenceFlow"); 
    for (Element transitionElement : transitionElements) { 

     // Parse attributes 
     String transitionName = XmlUtil.attribute(transitionElement, "name"); 
     String transitionId = XmlUtil.attribute(transitionElement, "id", parse); 
     String sourceRef = XmlUtil.attribute(transitionElement, "sourceRef", parse); 
     String targetRef = XmlUtil.attribute(transitionElement, "targetRef", parse); 

     if (log.isDebugEnabled()) { 
     log.debug(transitionId + ": " + sourceRef + " -> " + targetRef); 
     } 

     // Create new outgoing transition on sourceActivity 
     ActivityImpl sourceActivity = processDefinition.findActivity(sourceRef); 
     TransitionImpl transition = null; 
     if (sourceActivity != null) { 
     transition = sourceActivity.createOutgoingTransition(); 
     transition.setName(transitionId); 
     transition.setDescription(transitionName); 
     } else { 
     parse.addProblem("SourceRef " + sourceRef + " cannot be found"); 
     } 

     // Create incoming transition on targetActivity 
     ActivityImpl destinationActivity = processDefinition.findActivity(targetRef); 
     if (destinationActivity != null) { 
     destinationActivity.addIncomingTransition(transition); 
     } else { 
     parse.addProblem("TargetRef '" + targetRef + "' cannot be found"); 
     } 

     // Set default sequence flow if applicable 
     try { 
     // If something went wrong parsing the activity, there is no behaviour and an exception is thrown in .getBehaviour() 
     ActivityBehaviour behaviour = sourceActivity.getActivityBehaviour(); 
     if (behaviour instanceof BpmnActivity) { 
      BpmnActivity bpmnActivity = (BpmnActivity) behaviour; 
      String defaultSeqFlow = bpmnActivity.getDefault(); 
      if (bpmnActivity.isDefaultEnabled() && defaultSeqFlow != null) { 
      if (transitionId.equals(defaultSeqFlow)) { 
       processDefinition.findActivity(sourceRef).setDefaultOutgoingTransition(transition); 
      } 
      } else { 
      processDefinition.findActivity(sourceRef).setDefaultOutgoingTransition(null); 
      } 
     } else { 
      // Other flownodes do not have default sequenceFlows, so set it to null 
      processDefinition.findActivity(sourceRef).setDefaultOutgoingTransition(null); 
     } 

     } catch (JbpmException je) { 
     // catch it and only re-throw if not this specific exception. 
     if (!je.getMessage().contains("no behaviour on")) { 
      throw je; 
     } 
     } 

     parseConditionOnSequenceFlow(parse, transitionElement, transitionId, transition); 

     processDefinition.addSequenceFlow(transitionId, transition); 
    } 
    } 

    public void parseConditionOnSequenceFlow(Parse parse, Element transitionElement, String transitionId, TransitionImpl transition) { 
    Element conditionElement = XmlUtil.element(transitionElement, "conditionExpression"); 
    if (conditionElement != null) { 
     String type = conditionElement.getAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "type"); 
     if ("bpmn:tFormalExpression".equals(type) || "tFormalExpression".equals(type)) { 

     String expr = conditionElement.getTextContent(); 
     String lang = XmlUtil.attribute(conditionElement, "language"); 
     // TODO: add looking up the default language in the document under definitions if lang is null. 

     if (expr != null) { 
      expr = expr.trim(); 
     } 

     SequenceflowCondition condition = new SequenceflowCondition(); 
     condition.setExpression(expr); 
     condition.setLanguage(lang); 
     transition.setCondition(condition); 

     } else { 
     parse.addProblem("Type of the conditionExpression on sequenceFlow with id=" + 
       transitionId + " is of onsupported type 'bpmn:tExpression'", transitionElement); 
     } 
    } 
    } 

    public void parseDefinition(Element documentElement, Parse parse) { 
    parseImports(documentElement, parse); 
    } 

    public TaskDefinitionImpl parseTaskDefinition(Element element, Parse parse, ScopeElementImpl scopeElement) { 
    TaskDefinitionImpl taskDefinition = new TaskDefinitionImpl(); 

    String taskName = XmlUtil.attribute(element, "name"); 
    taskDefinition.setName(taskName); 

    BpmnProcessDefinition processDefinition = parse.contextStackFind(BpmnProcessDefinition.class); 
    if (processDefinition.getTaskDefinition(taskName) != null) { 
     parse.addProblem("duplicate task name " + taskName, element); 
    } else { 
     processDefinition.addTaskDefinitionImpl(taskDefinition); 
    } 

    return taskDefinition; 
    } 

    /** 
    * Parses a <timerEventDefinition> element: 
    * * sets dueDate if 'timeDate' is used 
    * * sets duedateDescription if a duration expression is used 
    * * set cronExpression if a cron expression is used 
    * 
    * @param timerEventDefinitionElement The XML element that defines the timer definition 
    * @param activity The activity on which the timer definition must be created 
    * @param eventId The id of the event on which the timer is defined 
    */ 
    public TimerDefinitionImpl parseTimerEventDefinition(Element timerEventDefinitionElement, Parse parse, String eventId) { 

    Element timeDate = XmlUtil.element(timerEventDefinitionElement, "timeDate"); 
    Element timeCycle = XmlUtil.element(timerEventDefinitionElement, "timeCycle"); 

    if ((timeDate != null && timeCycle != null) 
      || (timeDate == null && timeCycle == null)) { 
     parse.addProblem("timerEventDefinition for event '" + eventId + 
       "' requires either a timeDate or a timeCycle definition (but not both)"); 
     return null; 
    } 

    TimerDefinitionImpl timerDefinition = new TimerDefinitionImpl(); 

    if (timeDate != null) { 
     parseTimeDate(eventId, parse, timeDate, timerDefinition); 
    } 

    if (timeCycle != null) { 
     parseTimeCycle(eventId, parse, timeCycle, timerDefinition); 
    } 

    return timerDefinition; 
    } 

    protected void parseTimeDate(String catchEventId, Parse parse, Element timeDate, TimerDefinitionImpl timerDefinition) { 
    String dueDateTime = timeDate.getTextContent(); 
    String dueDateTimeFormatText = (String) EnvironmentImpl.getFromCurrent("jbpm.duedatetime.format", false); 
    if (dueDateTimeFormatText==null) { 
     dueDateTimeFormatText = "dd/MM/yyyy HH:mm:ss"; 
    } 
    SimpleDateFormat dateFormat = new SimpleDateFormat(dueDateTimeFormatText); 
    try { 
     Date duedatetimeDate = dateFormat.parse(dueDateTime); 
     timerDefinition.setDueDate(duedatetimeDate); 
    } catch (ParseException e) { 
     parse.addProblem("couldn't parse timeDate '"+ dueDateTime 
       + "' on intermediate catch timer event " + catchEventId, e); 
    } 
    } 

    protected void parseTimeCycle(String catchEventId, Parse parse, Element timeCycle, TimerDefinitionImpl timerDefinition) { 
    String cycleExpression = timeCycle.getTextContent(); 
    if (Duration.isValidExpression(cycleExpression)) { 
     timerDefinition.setDueDateDescription(cycleExpression); 
    } else if (CronExpression.isValidExpression(cycleExpression)) { 
     timerDefinition.setCronExpression(cycleExpression); 
    } else { 
     parse.addProblem("couldn't parse timeDate duration '"+ cycleExpression 
       + "' on intermediate catch timer event " + catchEventId); 
    } 
    } 

    public void parseResources(Element documentElement, Parse parse, BpmnProcessDefinition processDefinition) { 

    for (Element resourceElement : XmlUtil.elements(documentElement, "resource")) { 

     Resource resource = new Resource(); 

     resource.setId(XmlUtil.attribute(resourceElement, "id")); 
     resource.setName(XmlUtil.attribute(resourceElement, "name")); 

     for (Element resourceParameterElement : XmlUtil.elements(documentElement, "resourceParameter")) { 

     ResourceParameter resourceParameter = new ResourceParameter(); 
     resourceParameter.setId(XmlUtil.attribute(resourceParameterElement, "id")); 
     resourceParameter.setName(XmlUtil.attribute(resourceParameterElement, "name")); 
     resourceParameter.setType(QName.valueOf(XmlUtil.attribute(resourceParameterElement, "name"))); 

     resource.getParameters().put(XmlUtil.attribute(resourceParameterElement, "name"), resourceParameter); 
     } 

     processDefinition.getResources().put(resource.getName(), resource); 
    } 

    } 

    public void parseInterfaces(Element documentElement, Parse parse, BpmnProcessDefinition processDefinition) { 

    for (Element interfaceElement : XmlUtil.elements(documentElement, "interface")) { 
     for (Element operationElement : XmlUtil.elements(interfaceElement, "operation")) { 
     processDefinition.getOperations().put(XmlUtil.attribute(operationElement, "id"), operationElement); 
     } 
     processDefinition.getInterfaces().put(XmlUtil.attribute(interfaceElement, "id"), interfaceElement); 
    } 
    } 

    public void parseMessages(Element documentElement, Parse parse, BpmnProcessDefinition processDefinition) { 

    for (Element messageElement : XmlUtil.elements(documentElement, "message")) { 
     processDefinition.getMessages().put(XmlUtil.attribute(messageElement, "id"), messageElement); 
    } 
    } 

    public void parseItemDefinitions(Element documentElement, Parse parse, BpmnProcessDefinition processDefinition) { 

    for (Element itemDefinitionElement : XmlUtil.elements(documentElement, "itemDefinition")) { 
     processDefinition.getItemDefinitions().put(XmlUtil.attribute(itemDefinitionElement, "id"), itemDefinitionElement); 
    } 

    } 

    public void parseImports(Element documentElement, Parse parse) { 

    } 

} 

答えて

0

BPMNは、(あなたがJAXP tutorialを参照することができます)あなたが任意の標準的なJava XMLパーサーを使用することができ、相互運用性のためのXMLファイルを使用しています。

すべてのXMLスキーマは、BPMN specification pageから取得できます。

+0

ありがとうございます。問題は、bpmn用に設計されたすべてのソフトウェアがXMLファイルでモデルをエクスポートできるわけではありません。同じ質問をする未来のユーザーのために、私は解決策を見つけました。あなたは 'camunda bpm'を使うことができます – Mehdi

+0

解決策を見つけたら、誰でもそれを見ることができるように投稿してください。 – Suncatcher

0

BPMNファイルを解析するためにseveral productsがあります。 jBPMは、オープンソースのJavaオプションの1つです。

本物の質問は、一度解析した後にそれでやりたいことです。実際にはビジネスプロセスを実際に実行したいと思うでしょうし、私は前述の製品の1つを利用して、ホイールを再開発するのではなく、そうしていきます。