赵冬冬 3 роки тому
батько
коміт
8ab00df05b

+ 36 - 23
pom.xml

@@ -19,10 +19,11 @@
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 		<java.version>1.8</java.version>
 		<druid.version>1.1.6</druid.version>
-        <activiti.version>6.0.0</activiti.version>
+        <activiti.version>5.22.0</activiti.version>
         <apache.xmlgraphics.version>1.7</apache.xmlgraphics.version>
 		<fastjson.version>1.2.47</fastjson.version>
 
+
 	</properties>
 
 	<dependencies>
@@ -75,6 +76,18 @@
 			<artifactId>activiti-spring-boot-starter-basic</artifactId>
 			<version>${activiti.version}</version>
 		</dependency>
+		<!--集成diagram-view5.22跟踪流程-->
+		<dependency>
+			<groupId>org.activiti</groupId>
+			<artifactId>activiti-spring-boot-starter-rest-api</artifactId>
+			<version>${activiti.version}</version>
+		</dependency>
+		<!--集成diagram-view5.22跟踪流程-->
+		<dependency>
+			<groupId>org.activiti</groupId>
+			<artifactId>activiti-diagram-rest</artifactId>
+			<version>${activiti.version}</version>
+		</dependency>
 
 		<dependency>
 			<groupId>org.activiti</groupId>
@@ -93,28 +106,28 @@
 				</exclusion>
 		     </exclusions>
     	</dependency>
-    	
-	    <dependency> 
-		    <groupId>org.apache.xmlgraphics</groupId> 
-		    <artifactId>batik-codec</artifactId> 
-		    <version>${apache.xmlgraphics.version}</version> 
-	    </dependency> 
-	    <dependency> 
-		    <groupId>org.apache.xmlgraphics</groupId> 
-		    <artifactId>batik-css</artifactId> 
-		    <version>${apache.xmlgraphics.version}</version> 
-	    </dependency> 
-	    <dependency> 
-		    <groupId>org.apache.xmlgraphics</groupId> 
-		    <artifactId>batik-svg-dom</artifactId> 
-		    <version>${apache.xmlgraphics.version}</version> 
-	    </dependency> 
-	    <dependency> 
-		    <groupId>org.apache.xmlgraphics</groupId> 
-		    <artifactId>batik-svggen</artifactId> 
-		    <version>${apache.xmlgraphics.version}</version> 
+
+	    <dependency>
+		    <groupId>org.apache.xmlgraphics</groupId>
+		    <artifactId>batik-codec</artifactId>
+		    <version>${apache.xmlgraphics.version}</version>
+	    </dependency>
+	    <dependency>
+		    <groupId>org.apache.xmlgraphics</groupId>
+		    <artifactId>batik-css</artifactId>
+		    <version>${apache.xmlgraphics.version}</version>
 	    </dependency>
-	   
+	    <dependency>
+		    <groupId>org.apache.xmlgraphics</groupId>
+		    <artifactId>batik-svg-dom</artifactId>
+		    <version>${apache.xmlgraphics.version}</version>
+	    </dependency>
+	    <dependency>
+		    <groupId>org.apache.xmlgraphics</groupId>
+		    <artifactId>batik-svggen</artifactId>
+		    <version>${apache.xmlgraphics.version}</version>
+	    </dependency>
+
 	</dependencies>
 
 	<build>
@@ -126,4 +139,4 @@
 		</plugins>
 	</build>
 
-</project>
+</project>

+ 49 - 2
src/main/java/com/activiti6/Activiti6DemoApplication.java

@@ -1,15 +1,62 @@
 package com.activiti6;
 
+import org.activiti.rest.common.application.ContentTypeResolver;
+import org.activiti.rest.common.application.DefaultContentTypeResolver;
+import org.activiti.rest.service.api.RestResponseFactory;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 
-@SpringBootApplication
+@RestController
+@SpringBootApplication(exclude = {
+        org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class,
+        org.activiti.spring.boot.SecurityAutoConfiguration.class,
+})
 @MapperScan("com.activiti6.mapper")
-public class Activiti6DemoApplication {
+@ComponentScan(basePackages = {"org.activiti.rest"})
+public class Activiti6DemoApplication extends WebMvcConfigurerAdapter {
+    @Override
+    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
+        configurer.favorPathExtension(false);
+    }
 
     public static void main(String[] args) {
         SpringApplication.run(Activiti6DemoApplication.class, args);
     }
 
+    @Bean
+    public RestResponseFactory createRestResponseFactory() {
+        return new RestResponseFactory();
+    }
+
+    @Bean
+    public ContentTypeResolver createContentTypeResolver() {
+        return new DefaultContentTypeResolver();
+    }
+
+    @Bean
+    public FilterRegistrationBean corsFilter() {
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true);
+//        config.addAllowedOrigin("http://localhost:8081");
+        config.addAllowedOrigin("*");
+        config.addAllowedHeader("*");
+        config.addAllowedMethod("*");
+        source.registerCorsConfiguration("/**", config); // CORS 配置对所有接口都有效
+        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
+        bean.setOrder(0);
+        return bean;
+    }
+
+
 }

+ 0 - 26
src/main/java/com/activiti6/config/CorsConfig.java

@@ -1,26 +0,0 @@
-package com.activiti6.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import org.springframework.web.filter.CorsFilter;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class CorsConfig {
-    private CorsConfiguration buildConfig() {
-        CorsConfiguration corsConfiguration = new CorsConfiguration();
-        corsConfiguration.addAllowedOrigin("*"); //允许任何域名
-        corsConfiguration.addAllowedHeader("*"); //允许任何头
-        corsConfiguration.addAllowedMethod("*"); //允许任何方法
-        return corsConfiguration;
-    }
-
-    @Bean
-    public CorsFilter corsFilter() {
-        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
-        source.registerCorsConfiguration("/**", buildConfig()); //注册
-        return new CorsFilter(source);
-    }
-}

+ 11 - 9
src/main/java/com/activiti6/config/ActivitiConfig.java → src/main/java/com/activiti6/config/ScanConfig.java

@@ -1,22 +1,24 @@
 package com.activiti6.config;
 
-import javax.sql.DataSource;
-
 import org.activiti.engine.ProcessEngineConfiguration;
 import org.activiti.engine.impl.history.HistoryLevel;
 import org.activiti.spring.SpringProcessEngineConfiguration;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
 import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.sql.DataSource;
 
-/**
- * activiti 配置类
- * liuzhize 2019年3月7日下午3:26:56
- */
-@Configuration
-public class ActivitiConfig {
 
+@Configuration
+@ComponentScan(basePackages = {"org.activiti.rest.diagram", "org.activiti.rest"}, includeFilters = {
+        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {
+                RestController.class})}, useDefaultFilters = false, lazyInit = false)
+public class ScanConfig {
     @Autowired
     private DataSource dataSource;
     @Autowired
@@ -33,7 +35,7 @@ public class ActivitiConfig {
         // 执行工作流对应的数据源
         configuration.setDataSource(dataSource);
         // 是否自动创建流程引擎表
-        configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
+        configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE);
         configuration.setAsyncExecutorActivate(false);
         // 流程历史等级
         configuration.setHistoryLevel(HistoryLevel.FULL);

+ 5 - 3
src/main/java/com/activiti6/config/WebMvcConfigurer.java

@@ -15,8 +15,10 @@ public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
 
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry) {
-        registry.addResourceHandler("/static/**")
-                .addResourceLocations("classpath:/static/");
+        String[] resourceHandler={"/static/**","/templates/**"};
+        String[] resourceLocations={"classpath:/static/","classpath:/templates/"};
+        registry.addResourceHandler(resourceHandler)
+                .addResourceLocations(resourceLocations);
         super.addResourceHandlers(registry);
     }
 
@@ -28,4 +30,4 @@ public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
     }
 
 
-}
+}

+ 0 - 5
src/main/java/com/activiti6/controller/ModelerController.java

@@ -52,11 +52,6 @@ public class ModelerController extends BaseController {
     private RepositoryService repositoryService;
     @Autowired
     private ObjectMapper objectMapper;
-    @Autowired
-    private HistoryService historyService;
-    @Autowired
-    private RuntimeService runtimeService;
-
 
     @RequestMapping("index")
     public ModelAndView index(ModelAndView modelAndView) {

+ 2 - 1
src/main/java/com/activiti6/controller/ZipFileController.java

@@ -20,6 +20,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -37,7 +38,7 @@ import java.util.List;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
-@RestController
+@Controller
 @RequestMapping("zip")
 public class ZipFileController extends BaseController {
 

+ 492 - 0
src/main/java/com/activiti6/controller/image/BaseProcessDefinitionDiagramLayoutResource.java

@@ -0,0 +1,492 @@
+/* Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.activiti6.controller.image;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.activiti.engine.*;
+import org.activiti.engine.history.HistoricActivityInstance;
+import org.activiti.engine.impl.bpmn.behavior.BoundaryEventActivityBehavior;
+import org.activiti.engine.impl.bpmn.behavior.CallActivityBehavior;
+import org.activiti.engine.impl.bpmn.parser.BpmnParse;
+import org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition;
+import org.activiti.engine.impl.bpmn.parser.EventSubscriptionDeclaration;
+import org.activiti.engine.impl.jobexecutor.TimerDeclarationImpl;
+import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
+import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
+import org.activiti.engine.impl.pvm.PvmTransition;
+import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
+import org.activiti.engine.impl.pvm.process.*;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.Execution;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.*;
+
+public class BaseProcessDefinitionDiagramLayoutResource {
+
+  @Autowired
+  private RuntimeService runtimeService;
+
+  @Autowired
+  private RepositoryService repositoryService;
+
+  @Autowired
+  private HistoryService historyService;
+
+  public ObjectNode getDiagramNode(String processInstanceId, String processDefinitionId) {
+
+    List<String> highLightedFlows = Collections.<String> emptyList();
+    List<String> highLightedActivities = Collections.<String> emptyList();
+
+    Map<String, ObjectNode> subProcessInstanceMap = new HashMap<String, ObjectNode>();
+
+    ProcessInstance processInstance = null;
+    if (processInstanceId != null) {
+      processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+      if (processInstance == null) {
+        throw new ActivitiObjectNotFoundException("Process instance could not be found");
+      }
+      processDefinitionId = processInstance.getProcessDefinitionId();
+
+      List<ProcessInstance> subProcessInstances = runtimeService
+          .createProcessInstanceQuery()
+          .superProcessInstanceId(processInstanceId).list();
+
+      for (ProcessInstance subProcessInstance : subProcessInstances) {
+        String subDefId = subProcessInstance.getProcessDefinitionId();
+
+        String superExecutionId = ((ExecutionEntity) subProcessInstance)
+            .getSuperExecutionId();
+        ProcessDefinitionEntity subDef = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(subDefId);
+
+        ObjectNode processInstanceJSON = new ObjectMapper().createObjectNode();
+        processInstanceJSON.put("processInstanceId", subProcessInstance.getId());
+        processInstanceJSON.put("superExecutionId", superExecutionId);
+        processInstanceJSON.put("processDefinitionId", subDef.getId());
+        processInstanceJSON.put("processDefinitionKey", subDef.getKey());
+        processInstanceJSON.put("processDefinitionName", subDef.getName());
+
+        subProcessInstanceMap.put(superExecutionId, processInstanceJSON);
+      }
+    }
+
+    if (processDefinitionId == null) {
+      throw new ActivitiObjectNotFoundException("No process definition id provided");
+    }
+
+    ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId);
+
+    if (processDefinition == null) {
+      throw new ActivitiException("Process definition " + processDefinitionId + " could not be found");
+    }
+
+    ObjectNode responseJSON = new ObjectMapper().createObjectNode();
+
+    // Process definition
+    JsonNode pdrJSON = getProcessDefinitionResponse(processDefinition);
+
+    if (pdrJSON != null) {
+      responseJSON.put("processDefinition", pdrJSON);
+    }
+
+    // Highlighted activities
+    if (processInstance != null) {
+      ArrayNode activityArray = new ObjectMapper().createArrayNode();
+      ArrayNode flowsArray = new ObjectMapper().createArrayNode();
+
+      highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
+      highLightedFlows = getHighLightedFlows(processInstanceId, processDefinition);
+
+      for (String activityName : highLightedActivities) {
+        activityArray.add(activityName);
+      }
+
+      for (String flow : highLightedFlows) {
+        flowsArray.add(flow);
+      }
+
+      responseJSON.put("highLightedActivities", activityArray);
+      responseJSON.put("highLightedFlows", flowsArray);
+    }
+
+    // Pool shape, if process is participant in collaboration
+    if (processDefinition.getParticipantProcess() != null) {
+      ParticipantProcess pProc = processDefinition.getParticipantProcess();
+
+      ObjectNode participantProcessJSON = new ObjectMapper().createObjectNode();
+      participantProcessJSON.put("id", pProc.getId());
+      if (StringUtils.isNotEmpty(pProc.getName())) {
+        participantProcessJSON.put("name", pProc.getName());
+      } else {
+        participantProcessJSON.put("name", "");
+      }
+      participantProcessJSON.put("x", pProc.getX());
+      participantProcessJSON.put("y", pProc.getY());
+      participantProcessJSON.put("width", pProc.getWidth());
+      participantProcessJSON.put("height", pProc.getHeight());
+
+      responseJSON.put("participantProcess", participantProcessJSON);
+    }
+
+    // Draw lanes
+
+    if (processDefinition.getLaneSets() != null && !processDefinition.getLaneSets().isEmpty()) {
+      ArrayNode laneSetArray = new ObjectMapper().createArrayNode();
+      for (LaneSet laneSet : processDefinition.getLaneSets()) {
+        ArrayNode laneArray = new ObjectMapper().createArrayNode();
+        if (laneSet.getLanes() != null && !laneSet.getLanes().isEmpty()) {
+          for (Lane lane : laneSet.getLanes()) {
+            ObjectNode laneJSON = new ObjectMapper().createObjectNode();
+            laneJSON.put("id", lane.getId());
+            if (StringUtils.isNotEmpty(lane.getName())) {
+              laneJSON.put("name", lane.getName());
+            } else {
+              laneJSON.put("name", "");
+            }
+            laneJSON.put("x", lane.getX());
+            laneJSON.put("y", lane.getY());
+            laneJSON.put("width", lane.getWidth());
+            laneJSON.put("height", lane.getHeight());
+
+            List<String> flowNodeIds = lane.getFlowNodeIds();
+            ArrayNode flowNodeIdsArray = new ObjectMapper().createArrayNode();
+            for (String flowNodeId : flowNodeIds) {
+              flowNodeIdsArray.add(flowNodeId);
+            }
+            laneJSON.put("flowNodeIds", flowNodeIdsArray);
+
+            laneArray.add(laneJSON);
+          }
+        }
+        ObjectNode laneSetJSON = new ObjectMapper().createObjectNode();
+        laneSetJSON.put("id", laneSet.getId());
+        if (StringUtils.isNotEmpty(laneSet.getName())) {
+          laneSetJSON.put("name", laneSet.getName());
+        } else {
+          laneSetJSON.put("name", "");
+        }
+        laneSetJSON.put("lanes", laneArray);
+
+        laneSetArray.add(laneSetJSON);
+      }
+
+      if (laneSetArray.size() > 0)
+        responseJSON.put("laneSets", laneSetArray);
+    }
+
+    ArrayNode sequenceFlowArray = new ObjectMapper().createArrayNode();
+    ArrayNode activityArray = new ObjectMapper().createArrayNode();
+
+    // Activities and their sequence-flows
+
+    for (ActivityImpl activity : processDefinition.getActivities()) {
+      getActivity(processInstanceId, activity, activityArray, sequenceFlowArray,
+          processInstance, highLightedFlows, subProcessInstanceMap);
+    }
+
+    responseJSON.put("activities", activityArray);
+    responseJSON.put("sequenceFlows", sequenceFlowArray);
+
+    return responseJSON;
+  }
+
+  private List<String> getHighLightedFlows(String processInstanceId, ProcessDefinitionEntity processDefinition) {
+
+    List<String> highLightedFlows = new ArrayList<String>();
+    List<HistoricActivityInstance> historicActivityInstances = historyService
+        .createHistoricActivityInstanceQuery()
+        .processInstanceId(processInstanceId)
+        .orderByHistoricActivityInstanceStartTime().asc().list();
+
+    List<String> historicActivityInstanceList = new ArrayList<String>();
+    for (HistoricActivityInstance hai : historicActivityInstances) {
+      historicActivityInstanceList.add(hai.getActivityId());
+    }
+
+    // add current activities to list
+    List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
+    historicActivityInstanceList.addAll(highLightedActivities);
+
+    // activities and their sequence-flows
+    for (ActivityImpl activity : processDefinition.getActivities()) {
+      int index = historicActivityInstanceList.indexOf(activity.getId());
+
+      if (index >= 0 && index + 1 < historicActivityInstanceList.size()) {
+        List<PvmTransition> pvmTransitionList = activity
+            .getOutgoingTransitions();
+        for (PvmTransition pvmTransition : pvmTransitionList) {
+          String destinationFlowId = pvmTransition.getDestination().getId();
+          if (destinationFlowId.equals(historicActivityInstanceList.get(index + 1))) {
+            highLightedFlows.add(pvmTransition.getId());
+          }
+        }
+      }
+    }
+    return highLightedFlows;
+  }
+
+  private void getActivity(String processInstanceId, ActivityImpl activity, ArrayNode activityArray,
+      ArrayNode sequenceFlowArray, ProcessInstance processInstance, List<String> highLightedFlows,
+      Map<String, ObjectNode> subProcessInstanceMap) {
+
+    ObjectNode activityJSON = new ObjectMapper().createObjectNode();
+
+    // Gather info on the multi instance marker
+    String multiInstance = (String) activity.getProperty("multiInstance");
+    if (multiInstance != null) {
+      if (!"sequential".equals(multiInstance)) {
+        multiInstance = "parallel";
+      }
+    }
+
+    ActivityBehavior activityBehavior = activity.getActivityBehavior();
+    // Gather info on the collapsed marker
+    Boolean collapsed = (activityBehavior instanceof CallActivityBehavior);
+    Boolean expanded = (Boolean) activity.getProperty(BpmnParse.PROPERTYNAME_ISEXPANDED);
+    if (expanded != null) {
+      collapsed = !expanded;
+    }
+
+    Boolean isInterrupting = null;
+    if (activityBehavior instanceof BoundaryEventActivityBehavior) {
+      isInterrupting = ((BoundaryEventActivityBehavior) activityBehavior).isInterrupting();
+    }
+
+    // Outgoing transitions of activity
+    for (PvmTransition sequenceFlow : activity.getOutgoingTransitions()) {
+      String flowName = (String) sequenceFlow.getProperty("name");
+      boolean isHighLighted = (highLightedFlows.contains(sequenceFlow.getId()));
+      boolean isConditional = sequenceFlow.getProperty(BpmnParse.PROPERTYNAME_CONDITION) != null &&
+          !((String) activity.getProperty("type")).toLowerCase().contains("gateway");
+      boolean isDefault = sequenceFlow.getId().equals(activity.getProperty("default"))
+          && ((String) activity.getProperty("type")).toLowerCase().contains("gateway");
+
+      List<Integer> waypoints = ((TransitionImpl) sequenceFlow).getWaypoints();
+      ArrayNode xPointArray = new ObjectMapper().createArrayNode();
+      ArrayNode yPointArray = new ObjectMapper().createArrayNode();
+      for (int i = 0; i < waypoints.size(); i += 2) { // waypoints.size()
+                                                      // minimally 4: x1, y1,
+                                                      // x2, y2
+        xPointArray.add(waypoints.get(i));
+        yPointArray.add(waypoints.get(i + 1));
+      }
+
+      ObjectNode flowJSON = new ObjectMapper().createObjectNode();
+      flowJSON.put("id", sequenceFlow.getId());
+      flowJSON.put("name", flowName);
+      flowJSON.put("flow", "(" + sequenceFlow.getSource().getId() + ")--"
+          + sequenceFlow.getId() + "-->("
+          + sequenceFlow.getDestination().getId() + ")");
+
+      if (isConditional)
+        flowJSON.put("isConditional", isConditional);
+      if (isDefault)
+        flowJSON.put("isDefault", isDefault);
+      if (isHighLighted)
+        flowJSON.put("isHighLighted", isHighLighted);
+
+      flowJSON.put("xPointArray", xPointArray);
+      flowJSON.put("yPointArray", yPointArray);
+
+      sequenceFlowArray.add(flowJSON);
+    }
+
+    // Nested activities (boundary events)
+    ArrayNode nestedActivityArray = new ObjectMapper().createArrayNode();
+    for (ActivityImpl nestedActivity : activity.getActivities()) {
+      nestedActivityArray.add(nestedActivity.getId());
+    }
+
+    Map<String, Object> properties = activity.getProperties();
+    ObjectNode propertiesJSON = new ObjectMapper().createObjectNode();
+    for (String key : properties.keySet()) {
+      Object prop = properties.get(key);
+      if (prop instanceof String)
+        propertiesJSON.put(key, (String) properties.get(key));
+      else if (prop instanceof Integer)
+        propertiesJSON.put(key, (Integer) properties.get(key));
+      else if (prop instanceof Boolean)
+        propertiesJSON.put(key, (Boolean) properties.get(key));
+      else if ("initial".equals(key)) {
+        ActivityImpl act = (ActivityImpl) properties.get(key);
+        propertiesJSON.put(key, act.getId());
+      } else if ("timerDeclarations".equals(key)) {
+        ArrayList<TimerDeclarationImpl> timerDeclarations = (ArrayList<TimerDeclarationImpl>) properties.get(key);
+        ArrayNode timerDeclarationArray = new ObjectMapper().createArrayNode();
+
+        if (timerDeclarations != null)
+          for (TimerDeclarationImpl timerDeclaration : timerDeclarations) {
+            ObjectNode timerDeclarationJSON = new ObjectMapper().createObjectNode();
+
+            timerDeclarationJSON.put("isExclusive", timerDeclaration.isExclusive());
+            if (timerDeclaration.getRepeat() != null)
+              timerDeclarationJSON.put("repeat", timerDeclaration.getRepeat());
+
+            timerDeclarationJSON.put("retries", String.valueOf(timerDeclaration.getRetries()));
+            timerDeclarationJSON.put("type", timerDeclaration.getJobHandlerType());
+            timerDeclarationJSON.put("configuration", timerDeclaration.getJobHandlerConfiguration());
+            //timerDeclarationJSON.put("expression", timerDeclaration.getDescription());
+
+            timerDeclarationArray.add(timerDeclarationJSON);
+          }
+        if (timerDeclarationArray.size() > 0)
+          propertiesJSON.put(key, timerDeclarationArray);
+        // TODO: implement getting description
+      } else if ("eventDefinitions".equals(key)) {
+        ArrayList<EventSubscriptionDeclaration> eventDefinitions = (ArrayList<EventSubscriptionDeclaration>) properties.get(key);
+        ArrayNode eventDefinitionsArray = new ObjectMapper().createArrayNode();
+
+        if (eventDefinitions != null) {
+          for (EventSubscriptionDeclaration eventDefinition : eventDefinitions) {
+            ObjectNode eventDefinitionJSON = new ObjectMapper().createObjectNode();
+
+            if (eventDefinition.getActivityId() != null)
+              eventDefinitionJSON.put("activityId",eventDefinition.getActivityId());
+
+            eventDefinitionJSON.put("eventName", eventDefinition.getEventName());
+            eventDefinitionJSON.put("eventType", eventDefinition.getEventType());
+            eventDefinitionJSON.put("isAsync", eventDefinition.isAsync());
+            eventDefinitionJSON.put("isStartEvent", eventDefinition.isStartEvent());
+            eventDefinitionsArray.add(eventDefinitionJSON);
+          }
+        }
+
+        if (eventDefinitionsArray.size() > 0)
+          propertiesJSON.put(key, eventDefinitionsArray);
+
+      // TODO: implement it
+      } else if ("errorEventDefinitions".equals(key)) {
+        ArrayList<ErrorEventDefinition> errorEventDefinitions = (ArrayList<ErrorEventDefinition>) properties.get(key);
+        ArrayNode errorEventDefinitionsArray = new ObjectMapper().createArrayNode();
+
+        if (errorEventDefinitions != null) {
+          for (ErrorEventDefinition errorEventDefinition : errorEventDefinitions) {
+            ObjectNode errorEventDefinitionJSON = new ObjectMapper().createObjectNode();
+
+            if (errorEventDefinition.getErrorCode() != null)
+              errorEventDefinitionJSON.put("errorCode", errorEventDefinition.getErrorCode());
+            else
+              errorEventDefinitionJSON.putNull("errorCode");
+
+            errorEventDefinitionJSON.put("handlerActivityId",
+            errorEventDefinition.getHandlerActivityId());
+
+            errorEventDefinitionsArray.add(errorEventDefinitionJSON);
+          }
+        }
+
+        if (errorEventDefinitionsArray.size() > 0)
+          propertiesJSON.put(key, errorEventDefinitionsArray);
+      }
+
+    }
+
+    if ("callActivity".equals(properties.get("type"))) {
+      CallActivityBehavior callActivityBehavior = null;
+
+      if (activityBehavior instanceof CallActivityBehavior) {
+        callActivityBehavior = (CallActivityBehavior) activityBehavior;
+      }
+
+      if (callActivityBehavior != null) {
+        propertiesJSON.put("processDefinitonKey", callActivityBehavior.getProcessDefinitonKey());
+
+        // get processDefinitonId from execution or get last processDefinitonId
+        // by key
+        ArrayNode processInstanceArray = new ObjectMapper().createArrayNode();
+        if (processInstance != null) {
+          List<Execution> executionList = runtimeService.createExecutionQuery()
+              .processInstanceId(processInstanceId)
+              .activityId(activity.getId()).list();
+          if (!executionList.isEmpty()) {
+            for (Execution execution : executionList) {
+              ObjectNode processInstanceJSON = subProcessInstanceMap.get(execution.getId());
+              processInstanceArray.add(processInstanceJSON);
+            }
+          }
+        }
+
+        // If active activities nas no instance of this callActivity then add
+        // last definition
+        if (processInstanceArray.size() == 0 && StringUtils.isNotEmpty(callActivityBehavior.getProcessDefinitonKey())) {
+          // Get last definition by key
+          ProcessDefinition lastProcessDefinition = repositoryService
+              .createProcessDefinitionQuery()
+              .processDefinitionKey(callActivityBehavior.getProcessDefinitonKey())
+              .latestVersion().singleResult();
+
+          // TODO: unuseful fields there are processDefinitionName, processDefinitionKey
+          if (lastProcessDefinition != null) {
+            ObjectNode processInstanceJSON = new ObjectMapper().createObjectNode();
+            processInstanceJSON.put("processDefinitionId", lastProcessDefinition.getId());
+            processInstanceJSON.put("processDefinitionKey", lastProcessDefinition.getKey());
+            processInstanceJSON.put("processDefinitionName", lastProcessDefinition.getName());
+            processInstanceArray.add(processInstanceJSON);
+          }
+        }
+
+        if (processInstanceArray.size() > 0) {
+          propertiesJSON.put("processDefinitons", processInstanceArray);
+        }
+      }
+    }
+
+    activityJSON.put("activityId", activity.getId());
+    activityJSON.put("properties", propertiesJSON);
+    if (multiInstance != null)
+      activityJSON.put("multiInstance", multiInstance);
+    if (collapsed)
+      activityJSON.put("collapsed", collapsed);
+    if (nestedActivityArray.size() > 0)
+      activityJSON.put("nestedActivities", nestedActivityArray);
+    if (isInterrupting != null)
+      activityJSON.put("isInterrupting", isInterrupting);
+
+    activityJSON.put("x", activity.getX());
+    activityJSON.put("y", activity.getY());
+    activityJSON.put("width", activity.getWidth());
+    activityJSON.put("height", activity.getHeight());
+
+    activityArray.add(activityJSON);
+
+    // Nested activities (boundary events)
+    for (ActivityImpl nestedActivity : activity.getActivities()) {
+      getActivity(processInstanceId, nestedActivity, activityArray, sequenceFlowArray,
+          processInstance, highLightedFlows, subProcessInstanceMap);
+    }
+  }
+
+  private JsonNode getProcessDefinitionResponse(ProcessDefinitionEntity processDefinition) {
+    ObjectMapper mapper = new ObjectMapper();
+    ObjectNode pdrJSON = mapper.createObjectNode();
+    pdrJSON.put("id", processDefinition.getId());
+    pdrJSON.put("name", processDefinition.getName());
+    pdrJSON.put("key", processDefinition.getKey());
+    pdrJSON.put("version", processDefinition.getVersion());
+    pdrJSON.put("deploymentId", processDefinition.getDeploymentId());
+    pdrJSON.put("isGraphicNotationDefined", isGraphicNotationDefined(processDefinition));
+    return pdrJSON;
+  }
+
+  private boolean isGraphicNotationDefined(ProcessDefinitionEntity processDefinition) {
+    return ((ProcessDefinitionEntity) repositoryService
+        .getProcessDefinition(processDefinition.getId()))
+        .isGraphicalNotationDefined();
+  }
+}

+ 27 - 0
src/main/java/com/activiti6/controller/image/ProcessDefinitionDiagramLayoutResource.java

@@ -0,0 +1,27 @@
+/* Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.activiti6.controller.image;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+public class ProcessDefinitionDiagramLayoutResource extends BaseProcessDefinitionDiagramLayoutResource {
+    @CrossOrigin
+    @RequestMapping(value = "/process-definition/{processDefinitionId}/diagram-layout", method = RequestMethod.GET, produces = "application/json")
+    public ObjectNode getDiagram(@PathVariable String processDefinitionId) {
+        ObjectNode diagramNode = getDiagramNode(null, processDefinitionId);
+        return diagramNode;
+    }
+}

+ 29 - 0
src/main/java/com/activiti6/controller/image/ProcessInstanceDiagramLayoutResource.java

@@ -0,0 +1,29 @@
+/* Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.activiti6.controller.image;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class ProcessInstanceDiagramLayoutResource extends BaseProcessDefinitionDiagramLayoutResource {
+
+  @RequestMapping(value="/process-instance/{processInstanceId}/diagram-layout", method = RequestMethod.GET, produces = "application/json")
+  public ObjectNode getDiagram(@PathVariable String processInstanceId) {
+    return getDiagramNode(processInstanceId, null);
+  }
+}

+ 252 - 0
src/main/java/com/activiti6/controller/image/ProcessInstanceHighlightsResource.java

@@ -0,0 +1,252 @@
+/* Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.activiti6.controller.image;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.history.HistoricActivityInstance;
+import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
+import org.activiti.engine.impl.pvm.PvmTransition;
+import org.activiti.engine.impl.pvm.process.ActivityImpl;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.*;
+
+@RestController
+public class ProcessInstanceHighlightsResource {
+
+  @Autowired
+	private RuntimeService runtimeService;
+
+  @Autowired
+	private RepositoryService repositoryService;
+
+  @Autowired
+	private HistoryService historyService;
+
+	protected ObjectMapper objectMapper = new ObjectMapper();
+
+	@RequestMapping(value="/process-instance/{processInstanceId}/highlights", method = RequestMethod.GET, produces = "application/json")
+	public ObjectNode getHighlighted(@PathVariable String processInstanceId) {
+
+	  ObjectNode responseJSON = objectMapper.createObjectNode();
+
+		responseJSON.put("processInstanceId", processInstanceId);
+
+		ArrayNode activitiesArray = objectMapper.createArrayNode();
+		ArrayNode flowsArray = objectMapper.createArrayNode();
+
+		try {
+			ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+			ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId());
+
+			responseJSON.put("processDefinitionId", processInstance.getProcessDefinitionId());
+
+			List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
+			List<String> highLightedFlows = getHighLightedFlows(processDefinition, processInstanceId);
+
+			for (String activityId : highLightedActivities) {
+				activitiesArray.add(activityId);
+			}
+
+			for (String flow : highLightedFlows) {
+				flowsArray.add(flow);
+			}
+
+		} catch (Exception e) {
+		  e.printStackTrace();
+		}
+
+		responseJSON.put("activities", activitiesArray);
+		responseJSON.put("flows", flowsArray);
+
+		return responseJSON;
+	}
+
+
+	/**
+	 * getHighLightedFlows
+	 *
+	 * @param processDefinition
+	 * @param processInstanceId
+	 * @return
+	 */
+	private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinition, String processInstanceId) {
+
+    List<String> highLightedFlows = new ArrayList<String>();
+
+    List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
+        .processInstanceId(processInstanceId)
+        //order by startime asc is not correct. use default order is correct.
+        //.orderByHistoricActivityInstanceStartTime().asc()/*.orderByActivityId().asc()*/
+        .list();
+
+    LinkedList<HistoricActivityInstance> hisActInstList = new LinkedList<HistoricActivityInstance>();
+    hisActInstList.addAll(historicActivityInstances);
+
+    getHighlightedFlows(processDefinition.getActivities(), hisActInstList, highLightedFlows);
+
+    return highLightedFlows;
+	}
+
+	/**
+	 * getHighlightedFlows
+	 *
+	 * code logic:
+	 * 1. Loop all activities by id asc order;
+	 * 2. Check each activity's outgoing transitions and eventBoundery outgoing transitions, if outgoing transitions's destination.id is in other executed activityIds, add this transition to highLightedFlows List;
+	 * 3. But if activity is not a parallelGateway or inclusiveGateway, only choose the earliest flow.
+	 *
+	 * @param activityList
+	 * @param hisActInstList
+	 * @param highLightedFlows
+	 */
+	private void getHighlightedFlows(List<ActivityImpl> activityList, LinkedList<HistoricActivityInstance> hisActInstList, List<String> highLightedFlows){
+
+    //check out startEvents in activityList
+    List<ActivityImpl> startEventActList = new ArrayList<ActivityImpl>();
+    Map<String, ActivityImpl> activityMap = new HashMap<String, ActivityImpl>(activityList.size());
+    for(ActivityImpl activity : activityList){
+
+      activityMap.put(activity.getId(), activity);
+
+      String actType = (String) activity.getProperty("type");
+      if (actType != null && actType.toLowerCase().indexOf("startevent") >= 0){
+        startEventActList.add(activity);
+      }
+    }
+
+    //These codes is used to avoid a bug:
+    //ACT-1728 If the process instance was started by a callActivity, it will be not have the startEvent activity in ACT_HI_ACTINST table
+    //Code logic:
+    //Check the first activity if it is a startEvent, if not check out the startEvent's highlight outgoing flow.
+    HistoricActivityInstance firstHistActInst = hisActInstList.getFirst();
+    String firstActType = (String) firstHistActInst.getActivityType();
+    if (firstActType != null && firstActType.toLowerCase().indexOf("startevent") < 0){
+      PvmTransition startTrans = getStartTransaction(startEventActList, firstHistActInst);
+      if (startTrans != null){
+        highLightedFlows.add(startTrans.getId());
+      }
+    }
+
+    while (!hisActInstList.isEmpty()) {
+      HistoricActivityInstance histActInst = hisActInstList.removeFirst();
+      ActivityImpl activity = activityMap.get(histActInst.getActivityId());
+      if (activity != null) {
+        boolean isParallel = false;
+        String type = histActInst.getActivityType();
+        if ("parallelGateway".equals(type) || "inclusiveGateway".equals(type)){
+          isParallel = true;
+        } else if ("subProcess".equals(histActInst.getActivityType())){
+          getHighlightedFlows(activity.getActivities(), hisActInstList, highLightedFlows);
+        }
+
+        List<PvmTransition> allOutgoingTrans = new ArrayList<PvmTransition>();
+        allOutgoingTrans.addAll(activity.getOutgoingTransitions());
+        allOutgoingTrans.addAll(getBoundaryEventOutgoingTransitions(activity));
+        List<String> activityHighLightedFlowIds = getHighlightedFlows(allOutgoingTrans, hisActInstList, isParallel);
+        highLightedFlows.addAll(activityHighLightedFlowIds);
+      }
+    }
+	}
+
+	/**
+	 * Check out the outgoing transition connected to firstActInst from startEventActList
+	 *
+	 * @param startEventActList
+	 * @param firstActInst
+	 * @return
+	 */
+	private PvmTransition getStartTransaction(List<ActivityImpl> startEventActList, HistoricActivityInstance firstActInst){
+    for (ActivityImpl startEventAct: startEventActList) {
+      for (PvmTransition trans : startEventAct.getOutgoingTransitions()) {
+        if (trans.getDestination().getId().equals(firstActInst.getActivityId())) {
+          return trans;
+        }
+      }
+    }
+    return null;
+	}
+
+	/**
+	 * getBoundaryEventOutgoingTransitions
+	 *
+	 * @param activity
+	 * @return
+	 */
+	private List<PvmTransition> getBoundaryEventOutgoingTransitions(ActivityImpl activity){
+    List<PvmTransition> boundaryTrans = new ArrayList<PvmTransition>();
+    for(ActivityImpl subActivity : activity.getActivities()){
+      String type = (String)subActivity.getProperty("type");
+      if(type!=null && type.toLowerCase().indexOf("boundary")>=0){
+        boundaryTrans.addAll(subActivity.getOutgoingTransitions());
+      }
+    }
+    return boundaryTrans;
+	}
+
+	/**
+	 * find out single activity's highlighted flowIds
+	 *
+	 * @param activity
+	 * @param hisActInstList
+	 * @param isExclusive if true only return one flowId(Such as exclusiveGateway, BoundaryEvent On Task)
+	 * @return
+	 */
+	private List<String> getHighlightedFlows(List<PvmTransition> pvmTransitionList, LinkedList<HistoricActivityInstance> hisActInstList, boolean isParallel){
+
+    List<String> highLightedFlowIds = new ArrayList<String>();
+
+    PvmTransition earliestTrans = null;
+    HistoricActivityInstance earliestHisActInst = null;
+
+    for (PvmTransition pvmTransition : pvmTransitionList) {
+
+      String destActId = pvmTransition.getDestination().getId();
+      HistoricActivityInstance destHisActInst = findHisActInst(hisActInstList, destActId);
+      if (destHisActInst != null) {
+        if (isParallel) {
+          highLightedFlowIds.add(pvmTransition.getId());
+        } else if (earliestHisActInst == null || (earliestHisActInst.getId().compareTo(destHisActInst.getId()) > 0)) {
+          earliestTrans = pvmTransition;
+          earliestHisActInst = destHisActInst;
+        }
+      }
+    }
+
+    if ((!isParallel) && earliestTrans!=null){
+      highLightedFlowIds.add(earliestTrans.getId());
+    }
+
+    return highLightedFlowIds;
+	}
+
+	private HistoricActivityInstance findHisActInst(LinkedList<HistoricActivityInstance> hisActInstList, String actId){
+    for (HistoricActivityInstance hisActInst : hisActInstList){
+      if (hisActInst.getActivityId().equals(actId)){
+        return hisActInst;
+      }
+    }
+    return null;
+	}
+}

+ 4 - 0
src/main/resources/application.yml

@@ -4,6 +4,9 @@ server:
   port: 8081
 #环境
 spring:
+  #启动不检查流程文件
+  activiti:
+    check-process-definitions: false
   #数据源配置
   datasource:
     url: jdbc:mysql://49.235.127.212:3306/ry_activiti?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
@@ -12,6 +15,7 @@ spring:
     type: com.alibaba.druid.pool.DruidDataSource
     #freemarker模板配置
     freemarker:
+      request-context-attribute: req  #req访问request
       suffix: .ftl
       cache: false
       charset: UTF-8

+ 97 - 90
src/main/resources/static/diagram-viewer/index.html

@@ -1,15 +1,15 @@
 <html>
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-  
+
   <link rel="stylesheet" href="style.css" type="text/css" media="screen">
   <script src="js/jstools.js" type="text/javascript" charset="utf-8"></script>
   <script src="js/raphael.js" type="text/javascript" charset="utf-8"></script>
-  
+
   <script src="js/jquery/jquery.js" type="text/javascript" charset="utf-8"></script>
   <script src="js/jquery/jquery.progressbar.js" type="text/javascript" charset="utf-8"></script>
   <script src="js/jquery/jquery.asyncqueue.js" type="text/javascript" charset="utf-8"></script>
-  
+
   <script src="js/Color.js" type="text/javascript" charset="utf-8"></script>
   <script src="js/Polyline.js" type="text/javascript" charset="utf-8"></script>
   <script src="js/ActivityImpl.js" type="text/javascript" charset="utf-8"></script>
@@ -17,9 +17,9 @@
   <script src="js/LineBreakMeasurer.js" type="text/javascript" charset="utf-8"></script>
   <script src="js/ProcessDiagramGenerator.js" type="text/javascript" charset="utf-8"></script>
   <script src="js/ProcessDiagramCanvas.js" type="text/javascript" charset="utf-8"></script>
-  
+
   <style type="text/css" media="screen">
-    
+
   </style>
 </head>
 <body>
@@ -32,97 +32,104 @@
   </div>
 </div>
 <script language='javascript'>
-var DiagramGenerator = {};
-var pb1;
-$(document).ready(function(){
-  var query_string = {};
-  var query = window.location.search.substring(1);
-  var vars = query.split("&");
-  for (var i=0;i<vars.length;i++) {
-    var pair = vars[i].split("=");
-    query_string[pair[0]] = pair[1];
-  } 
-  
-  var processDefinitionId = query_string["processDefinitionId"];
-  var processInstanceId = query_string["processInstanceId"];
-  
-  console.log("Initialize progress bar");
-  
-  pb1 = new $.ProgressBar({
-    boundingBox: '#pb1',
-    label: 'Progressbar!',
-    on: {
-      complete: function() {
-        console.log("Progress Bar COMPLETE");
-        this.set('label', 'complete!');
-        if (processInstanceId) {
-          ProcessDiagramGenerator.drawHighLights(processInstanceId);
-        }
-      },
-      valueChange: function(e) {
-        this.set('label', e.newVal + '%');
-      }
-    },
-    value: 0
-  });
-  console.log("Progress bar inited");
-  
-  ProcessDiagramGenerator.options = {
-    diagramBreadCrumbsId: "diagramBreadCrumbs",
-    diagramHolderId: "diagramHolder",
-    diagramInfoId: "diagramInfo",
-    on: {
-      click: function(canvas, element, contextObject){
-        var mouseEvent = this;
-        console.log("[CLICK] mouseEvent: %o, canvas: %o, clicked element: %o, contextObject: %o", mouseEvent, canvas, element, contextObject);
-
-        if (contextObject.getProperty("type") == "callActivity") {
-          var processDefinitonKey = contextObject.getProperty("processDefinitonKey");
-          var processDefinitons = contextObject.getProperty("processDefinitons");
-          var processDefiniton = processDefinitons[0];
-          console.log("Load callActivity '" + processDefiniton.processDefinitionKey + "', contextObject: ", contextObject);
-
-          // Load processDefinition
-        ProcessDiagramGenerator.drawDiagram(processDefiniton.processDefinitionId);
+  var DiagramGenerator = {};
+  var pb1;
+  $(document).ready(function(){
+    var query_string = {};
+    var query = window.location.search.substring(1);
+    var vars = query.split("&");
+    for (var i=0;i<vars.length;i++) {
+      var pair = vars[i].split("=");
+      query_string[pair[0]] = pair[1];
+    }
+
+    var processDefinitionId = query_string["processDefinitionId"];
+    var processInstanceId = query_string["processInstanceId"];
+
+    console.log("Initialize progress bar");
+
+    pb1 = new $.ProgressBar({
+      boundingBox: '#pb1',
+      label: 'Progressbar!',
+      on: {
+        complete: function() {
+          console.log("Progress Bar COMPLETE");
+          this.set('label', 'complete!');
+          if (processInstanceId) {
+            ProcessDiagramGenerator.drawHighLights(processInstanceId);
+          }
+        },
+        valueChange: function(e) {
+          this.set('label', e.newVal + '%');
         }
       },
-      rightClick: function(canvas, element, contextObject){
-        var mouseEvent = this;
-        console.log("[RIGHTCLICK] mouseEvent: %o, canvas: %o, clicked element: %o, contextObject: %o", mouseEvent, canvas, element, contextObject);
-      },
-      over: function(canvas, element, contextObject){
-        var mouseEvent = this;
-        //console.log("[OVER] mouseEvent: %o, canvas: %o, clicked element: %o, contextObject: %o", mouseEvent, canvas, element, contextObject);
+      value: 0
+    });
+    console.log("Progress bar inited");
 
-        // TODO: show tooltip-window with contextObject info
-        ProcessDiagramGenerator.showActivityInfo(contextObject);
-      },
-      out: function(canvas, element, contextObject){
-        var mouseEvent = this;
-        //console.log("[OUT] mouseEvent: %o, canvas: %o, clicked element: %o, contextObject: %o", mouseEvent, canvas, element, contextObject);
+    ProcessDiagramGenerator.options = {
+      diagramBreadCrumbsId: "diagramBreadCrumbs",
+      diagramHolderId: "diagramHolder",
+      diagramInfoId: "diagramInfo",
+      on: {
+        click: function(canvas, element, contextObject){
+          var mouseEvent = this;
+          console.log("[CLICK] mouseEvent: %o, canvas: %o, clicked element: %o, contextObject: %o", mouseEvent, canvas, element, contextObject);
+
+          if (contextObject.getProperty("type") == "callActivity") {
+            var processDefinitonKey = contextObject.getProperty("processDefinitonKey");
+            var processDefinitons = contextObject.getProperty("processDefinitons");
+            var processDefiniton = processDefinitons[0];
+            console.log("Load callActivity '" + processDefiniton.processDefinitionKey + "', contextObject: ", contextObject);
 
-        ProcessDiagramGenerator.hideInfo();
+            // Load processDefinition
+            ProcessDiagramGenerator.drawDiagram(processDefiniton.processDefinitionId);
+          }
+        },
+        rightClick: function(canvas, element, contextObject){
+          var mouseEvent = this;
+          console.log("[RIGHTCLICK] mouseEvent: %o, canvas: %o, clicked element: %o, contextObject: %o", mouseEvent, canvas, element, contextObject);
+        },
+        over: function(canvas, element, contextObject){
+          var mouseEvent = this;
+          //console.log("[OVER] mouseEvent: %o, canvas: %o, clicked element: %o, contextObject: %o", mouseEvent, canvas, element, contextObject);
+
+          // TODO: show tooltip-window with contextObject info
+          ProcessDiagramGenerator.showActivityInfo(contextObject);
+        },
+        out: function(canvas, element, contextObject){
+          var mouseEvent = this;
+          //console.log("[OUT] mouseEvent: %o, canvas: %o, clicked element: %o, contextObject: %o", mouseEvent, canvas, element, contextObject);
+
+          ProcessDiagramGenerator.hideInfo();
+        }
       }
+    };
+
+    var baseUrl = window.document.location.protocol + "//" + window.document.location.host + "/";
+    var shortenedUrl = window.document.location.href.replace(baseUrl, "");
+    baseUrl = baseUrl + shortenedUrl.substring(0, shortenedUrl.indexOf("/"));
+
+    // ActivitiRest.options = {
+    //   processInstanceHighLightsUrl: baseUrl + "/trace/process-instance/{processInstanceId}/highlights?callback=?",
+    //   processDefini
+    //      tionUrl: baseUrl + "/trace/process-definition/{processDefinitionId}/diagram-layout?callback=?",
+    //   processDefin7itionByKeyUrl: baseUrl + "/trace/process-definition/{processDefinitionKey}/diagram-layout?callback=?"
+    // };
+
+    ActivitiRest.options = {
+      processInstanceHighLightsUrl:  "http://172.16.90.11:8081/process-instance/{processInstanceId}/highlights?callback=?",
+      processDefinitionUrl: "http://172.16.90.11:8081/process-definition/{processDefinitionId}/diagram-layout?callback=?",
+      processDefinitionByKeyUrl: "http://172.16.90.11:8081/process-definition/{processDefinitionKey}/diagram-layout?callback=?"
+    };
+
+    if (processDefinitionId) {
+      ProcessDiagramGenerator.drawDiagram(processDefinitionId);
+
+    } else {
+      alert("processDefinitionId parameter is required");
     }
-  };
-  
-  var baseUrl = window.document.location.protocol + "//" + window.document.location.host + "/";
-  var shortenedUrl = window.document.location.href.replace(baseUrl, "");
-  baseUrl = baseUrl + shortenedUrl.substring(0, shortenedUrl.indexOf("/"));
-  
-  ActivitiRest.options = {
-    processInstanceHighLightsUrl: baseUrl + "/service/process-instance/{processInstanceId}/highlights?callback=?",
-    processDefinitionUrl: baseUrl + "/service/process-definition/{processDefinitionId}/diagram-layout?callback=?",
-    processDefinitionByKeyUrl: baseUrl + "/service/process-definition/{processDefinitionKey}/diagram-layout?callback=?"
-  };
-  
-  if (processDefinitionId) {
-    ProcessDiagramGenerator.drawDiagram(processDefinitionId);
-    
-  } else {
-    alert("processDefinitionId parameter is required");
-  }
-});
+  });
 
 
 </script>

+ 115 - 73
src/main/resources/static/diagram-viewer/js/ActivitiRest.js

@@ -1,74 +1,116 @@
 var ActivitiRest = {
-	options: {},
-	getProcessDefinitionByKey: function(processDefinitionKey, callback) {
-		var url = Lang.sub(this.options.processDefinitionByKeyUrl, {processDefinitionKey: processDefinitionKey});
-		
-		$.ajax({
-			url: url,
-			dataType: 'jsonp',
-			cache: false,
-			async: true,
-			success: function(data, textStatus) {
-				var processDefinition = data;
-				if (!processDefinition) {
-					console.error("Process definition '" + processDefinitionKey + "' not found");
-				} else {
-				  callback.apply({processDefinitionId: processDefinition.id});
-				}
-			}
-		}).done(function(data, textStatus) {
-			console.log("ajax done");
-		}).fail(function(jqXHR, textStatus, error){
-			console.error('Get diagram layout['+processDefinitionKey+'] failure: ', textStatus, 'error: ', error, jqXHR);
-		});
-	},
-	
-	getProcessDefinition: function(processDefinitionId, callback) {
-		var url = Lang.sub(this.options.processDefinitionUrl, {processDefinitionId: processDefinitionId});
-		
-		$.ajax({
-			url: url,
-			dataType: 'jsonp',
-			cache: false,
-			async: true,
-			success: function(data, textStatus) {
-				var processDefinitionDiagramLayout = data;
-				if (!processDefinitionDiagramLayout) {
-					console.error("Process definition diagram layout '" + processDefinitionId + "' not found");
-					return;
-				} else {
-					callback.apply({processDefinitionDiagramLayout: processDefinitionDiagramLayout});
-				}
-			}
-		}).done(function(data, textStatus) {
-			console.log("ajax done");
-		}).fail(function(jqXHR, textStatus, error){
-			console.log('Get diagram layout['+processDefinitionId+'] failure: ', textStatus, jqXHR);
-		});
-	},
-	
-	getHighLights: function(processInstanceId, callback) {
-		var url = Lang.sub(this.options.processInstanceHighLightsUrl, {processInstanceId: processInstanceId});
-		
-		$.ajax({
-			url: url,
-			dataType: 'jsonp',
-			cache: false,
-			async: true,
-			success: function(data, textStatus) {
-				console.log("ajax returned data");
-				var highLights = data;
-				if (!highLights) {
-					console.log("highLights not found");
-					return;
-				} else {
-					callback.apply({highLights: highLights});
-				}
-			}
-		}).done(function(data, textStatus) {
-			console.log("ajax done");
-		}).fail(function(jqXHR, textStatus, error){
-		  console.log('Get HighLights['+processInstanceId+'] failure: ', textStatus, jqXHR);
-		});
-	}
-};
+    options: {},
+    getProcessDefinitionByKey: function (processDefinitionKey, callback) {
+        var url = Lang.sub(this.options.processDefinitionByKeyUrl, {processDefinitionKey: processDefinitionKey});
+        $.ajax({
+            url: url,
+            type: "GET",
+            success: function (data) {
+                console.log(data);
+                var processDefinition = data;
+                if (!processDefinition) {
+                    console.error("Process definition '" + processDefinitionKey + "' not found");
+                } else {
+                    callback.apply({processDefinitionId: processDefinition.id});
+                }
+            }
+        })
+
+        // $.ajax({
+        //     url: url,
+        //     dataType: 'json',
+        //     cache: false,
+        //     async: true,
+        //     success: function (data, textStatus) {
+        //         console.log(data);
+        //         var processDefinition = data;
+        //         if (!processDefinition) {
+        //             console.error("Process definition '" + processDefinitionKey + "' not found");
+        //         } else {
+        //             callback.apply({processDefinitionId: processDefinition.id});
+        //         }
+        //     }
+        // }).done(function (data, textStatus) {
+        //     console.log("ajax done");
+        // }).fail(function (jqXHR, textStatus, error) {
+        //         console.error('Get diagram layout[' + processDefinitionKey + '] failure: ', textStatus, 'error: ', error, jqXHR);
+        //     });
+
+
+    },
+
+    getProcessDefinition: function (processDefinitionId, callback) {
+        var url = Lang.sub(this.options.processDefinitionUrl, {processDefinitionId: processDefinitionId});
+        $.ajax({
+            url: url,
+            type: "GET",
+            success: function (data) {
+                var processDefinitionDiagramLayout = data;
+                if (!processDefinitionDiagramLayout) {
+                    console.error("Process definition diagram layout '" + processDefinitionId + "' not found");
+                    return;
+                } else {
+                    callback.apply({processDefinitionDiagramLayout: processDefinitionDiagramLayout});
+                }
+            }
+        })
+        // $.ajax({
+        //     url: url,
+        //     dataType: 'json',
+        //     cache: false,
+        //     async: true,
+        //     success: function (data, textStatus) {
+        //         var processDefinitionDiagramLayout = data;
+        //         if (!processDefinitionDiagramLayout) {
+        //             console.error("Process definition diagram layout '" + processDefinitionId + "' not found");
+        //             return;
+        //         } else {
+        //             callback.apply({processDefinitionDiagramLayout: processDefinitionDiagramLayout});
+        //         }
+        //     }
+        // }).done(function (data, textStatus) {
+        //     console.log("ajax done");
+        // }).fail(function (jqXHR, textStatus, error) {
+        //     console.log('Get diagram layout[' + processDefinitionId + '] failure: ', textStatus, jqXHR);
+        // });
+    },
+
+    getHighLights: function (processInstanceId, callback) {
+        var url = Lang.sub(this.options.processInstanceHighLightsUrl, {processInstanceId: processInstanceId});
+        $.ajax({
+            url: url,
+            type: "GET",
+            success: function (data) {
+                console.log(data);
+                console.log("ajax returned data");
+                var highLights = data;
+                if (!highLights) {
+                    console.log("highLights not found");
+                    return;
+                } else {
+                    callback.apply({highLights: highLights});
+                }
+            }
+        })
+        // $.ajax({
+        //     url: url,
+        //     dataType: 'json',
+        //     cache: false,
+        //     async: true,
+        //     success: function (data, textStatus) {
+        //         console.log("ajax returned data");
+        //         var highLights = data;
+        //         if (!highLights) {
+        //             console.log("highLights not found");
+        //             return;
+        //         } else {
+        //             callback.apply({highLights: highLights});
+        //         }
+        //     }
+        // }).done(function (data, textStatus) {
+        //     console.log("ajax done");
+        // }).fail(function (jqXHR, textStatus, error) {
+        //     console.log('Get HighLights[' + processInstanceId + '] failure: ', textStatus, jqXHR);
+        // });
+    }
+};

+ 2 - 15
src/main/resources/static/diagram-viewer/js/ProcessDiagramCanvas.js

@@ -120,7 +120,7 @@ var CONNECTION_TYPE = {
 var ProcessDiagramCanvas = function(){
 };
 ProcessDiagramCanvas.prototype = {
-// var DefaultProcessDiagramCanvas = {
+// var ProcessDiagramCanvas = {
 	canvasHolder: "holder",
 	canvasWidth: 0, 
 	canvasHeight: 0,
@@ -968,19 +968,6 @@ ProcessDiagramCanvas.prototype = {
 		if (conditional) {
 			conditionalSequenceFlowIndicator = this._drawConditionalSequenceFlowIndicator(firstLine);
 		}
-
-        // draw flow name
-        var flowName = contextObject.name;
-        if (flowName) {
-            var xPointArray = contextObject.xPointArray;
-            var yPointArray = contextObject.yPointArray;
-            var textX = xPointArray[0] < xPointArray[1] ? xPointArray[0] : xPointArray[1];
-            var textY = yPointArray[0] < yPointArray[1] ? yPointArray[1] : yPointArray[0];
-            // fix xy
-            textX += 20;
-            textY -= 10;
-            this.g.text(textX, textY, flowName).attr(LABEL_FONT);
-        }
 		
 		var st = this.g.set();
 		st.push(polyline.element, arrowHead, circleTail, conditionalSequenceFlowIndicator);
@@ -1124,7 +1111,7 @@ ProcessDiagramCanvas.prototype = {
 		//var arrowHead = this.g.path("M-" + ARROW_WIDTH/2 + " -" + doubleArrowWidth + "L0 0" + "L" + ARROW_WIDTH/2 + " -" + doubleArrowWidth + "z");
 		
 		var arrowHead = this.g.path("M0 0L-" + ARROW_WIDTH/1.5 + " -" + doubleArrowWidth + "L" + ARROW_WIDTH/1.5 + " -" + doubleArrowWidth + "z");
-		//var c = DefaultProcessDiagramCanvas.g.ellipse(0, 0, 3, 3);
+		//var c = ProcessDiagramCanvas.g.ellipse(0, 0, 3, 3);
 		//c.transform("t"+targetX+","+targetY+"");
 		
 		var angle = Math.atan2(targetY - srcY, targetX - srcX);

+ 1 - 1
src/main/resources/static/diagram-viewer/js/ProcessDiagramGenerator.js

@@ -741,7 +741,7 @@ var ProcessDiagramGenerator = {
 			};
 		}
 		return this.getProcessDiagram(processDefinitionDiagramLayout.processDefinition.id);
-		//return new DefaultProcessDiagramCanvas(maxX + 10, maxY + 10, minX, minY);
+		//return new ProcessDiagramCanvas(maxX + 10, maxY + 10, minX, minY);
 	},
 	
 	drawActivity: function(processDiagramCanvas, activity, highLightedActivities) {