Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
JeeSpringCloud
Commits
20e6484f
Commit
20e6484f
authored
Oct 12, 2018
by
HuangBingGui
Browse files
no commit message
parent
22579f13
Changes
37
Show whitespace changes
Inline
Side-by-side
JeeSpringCloud/src/main/java/com/jeespring/modules/act/ActConfig.java
0 → 100644
View file @
20e6484f
package
com.jeespring.modules.act
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.ImportResource
;
@Configuration
@ImportResource
(
locations
=
{
"classpath:spring-context-activiti.xml"
})
public
class
ActConfig
{
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/dao/ActDao.java
0 → 100644
View file @
20e6484f
/**
* Copyright © 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
*/
package
com.jeespring.modules.act.dao
;
import
com.jeespring.common.persistence.InterfaceBaseDao
;
import
com.jeespring.common.persistence.annotation.MyBatisDao
;
import
com.jeespring.modules.act.entity.Act
;
import
org.apache.ibatis.annotations.Mapper
;
/**
* 审批DAO接口
* @author thinkgem
* @version 2014-05-16
*/
@Mapper
public
interface
ActDao
extends
InterfaceBaseDao
<
Act
>
{
public
int
updateProcInsIdByBusinessId
(
Act
act
);
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/entity/Act.java
0 → 100644
View file @
20e6484f
/**
* Copyright © 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
*/
package
com.jeespring.modules.act.entity
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
import
org.activiti.engine.history.HistoricActivityInstance
;
import
org.activiti.engine.history.HistoricTaskInstance
;
import
org.activiti.engine.repository.ProcessDefinition
;
import
org.activiti.engine.runtime.ProcessInstance
;
import
org.activiti.engine.task.Task
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
com.fasterxml.jackson.annotation.JsonIgnore
;
import
com.jeespring.common.persistence.AbstractBaseEntity
;
import
com.jeespring.common.utils.StringUtils
;
import
com.jeespring.common.utils.TimeUtils
;
import
com.jeespring.modules.act.utils.Variable
;
/**
* 工作流Entity
* @author ThinkGem
* @version 2013-11-03
*/
public
class
Act
extends
AbstractBaseEntity
<
Act
>
{
private
static
final
long
serialVersionUID
=
1L
;
private
String
taskId
;
// 任务编号
private
String
taskName
;
// 任务名称
private
String
taskDefKey
;
// 任务定义Key(任务环节标识)
private
String
procInsId
;
// 流程实例ID
private
String
procDefId
;
// 流程定义ID
private
String
procDefKey
;
// 流程定义Key(流程定义标识)
private
String
businessTable
;
// 业务绑定Table
private
String
businessId
;
// 业务绑定ID
private
String
title
;
// 任务标题
private
String
status
;
// 任务状态(todo/claim/finish)
// private String procExecUrl; // 流程执行(办理)RUL
private
String
comment
;
// 任务意见
private
String
flag
;
// 意见状态
private
Task
task
;
// 任务对象
private
ProcessDefinition
procDef
;
// 流程定义对象
private
ProcessInstance
procIns
;
// 流程实例对象
private
HistoricTaskInstance
histTask
;
// 历史任务
private
HistoricActivityInstance
histIns
;
//历史活动任务
private
String
assignee
;
// 任务执行人编号
private
String
assigneeName
;
// 任务执行人名称
private
Variable
vars
;
// 流程变量
// private Variable taskVars; // 流程任务变量
private
Date
beginDate
;
// 开始查询日期
private
Date
endDate
;
// 结束查询日期
private
List
<
Act
>
list
;
// 任务列表
public
Act
()
{
super
();
}
public
String
getTaskId
()
{
if
(
taskId
==
null
&&
task
!=
null
){
taskId
=
task
.
getId
();
}
return
taskId
;
}
public
void
setTaskId
(
String
taskId
)
{
this
.
taskId
=
taskId
;
}
public
String
getTaskName
()
{
if
(
taskName
==
null
&&
task
!=
null
){
taskName
=
task
.
getName
();
}
return
taskName
;
}
public
void
setTaskName
(
String
taskName
)
{
this
.
taskName
=
taskName
;
}
public
String
getTaskDefKey
()
{
if
(
taskDefKey
==
null
&&
task
!=
null
){
taskDefKey
=
task
.
getTaskDefinitionKey
();
}
return
taskDefKey
;
}
public
void
setTaskDefKey
(
String
taskDefKey
)
{
this
.
taskDefKey
=
taskDefKey
;
}
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
public
Date
getTaskCreateDate
()
{
if
(
task
!=
null
){
return
task
.
getCreateTime
();
}
return
null
;
}
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
public
Date
getTaskEndDate
()
{
if
(
histTask
!=
null
){
return
histTask
.
getEndTime
();
}
return
null
;
}
@JsonIgnore
public
Task
getTask
()
{
return
task
;
}
public
void
setTask
(
Task
task
)
{
this
.
task
=
task
;
}
@JsonIgnore
public
ProcessDefinition
getProcDef
()
{
return
procDef
;
}
public
void
setProcDef
(
ProcessDefinition
procDef
)
{
this
.
procDef
=
procDef
;
}
public
String
getProcDefName
()
{
return
procDef
.
getName
();
}
@JsonIgnore
public
ProcessInstance
getProcIns
()
{
return
procIns
;
}
public
void
setProcIns
(
ProcessInstance
procIns
)
{
this
.
procIns
=
procIns
;
if
(
procIns
!=
null
&&
procIns
.
getBusinessKey
()
!=
null
){
String
[]
ss
=
procIns
.
getBusinessKey
().
split
(
":"
);
setBusinessTable
(
ss
[
0
]);
setBusinessId
(
ss
[
1
]);
}
}
// public String getProcExecUrl() {
// return procExecUrl;
// }
//
// public void setProcExecUrl(String procExecUrl) {
// this.procExecUrl = procExecUrl;
// }
public
String
getTitle
()
{
return
title
;
}
public
void
setTitle
(
String
title
)
{
this
.
title
=
title
;
}
public
String
getStatus
()
{
return
status
;
}
public
void
setStatus
(
String
status
)
{
this
.
status
=
status
;
}
@JsonIgnore
public
HistoricTaskInstance
getHistTask
()
{
return
histTask
;
}
public
void
setHistTask
(
HistoricTaskInstance
histTask
)
{
this
.
histTask
=
histTask
;
}
@JsonIgnore
public
HistoricActivityInstance
getHistIns
()
{
return
histIns
;
}
public
void
setHistIns
(
HistoricActivityInstance
histIns
)
{
this
.
histIns
=
histIns
;
}
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
public
Date
getBeginDate
()
{
return
beginDate
;
}
public
void
setBeginDate
(
Date
beginDate
)
{
this
.
beginDate
=
beginDate
;
}
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
public
Date
getEndDate
()
{
return
endDate
;
}
public
void
setEndDate
(
Date
endDate
)
{
this
.
endDate
=
endDate
;
}
public
String
getComment
()
{
return
comment
;
}
public
void
setComment
(
String
comment
)
{
this
.
comment
=
comment
;
}
public
String
getFlag
()
{
return
flag
;
}
public
void
setFlag
(
String
flag
)
{
this
.
flag
=
flag
;
}
public
String
getProcDefId
()
{
if
(
procDefId
==
null
&&
task
!=
null
){
procDefId
=
task
.
getProcessDefinitionId
();
}
return
procDefId
;
}
public
void
setProcDefId
(
String
procDefId
)
{
this
.
procDefId
=
procDefId
;
}
public
String
getProcInsId
()
{
if
(
procInsId
==
null
&&
task
!=
null
){
procInsId
=
task
.
getProcessInstanceId
();
}
return
procInsId
;
}
public
void
setProcInsId
(
String
procInsId
)
{
this
.
procInsId
=
procInsId
;
}
public
String
getBusinessId
()
{
return
businessId
;
}
public
void
setBusinessId
(
String
businessId
)
{
this
.
businessId
=
businessId
;
}
public
String
getBusinessTable
()
{
return
businessTable
;
}
public
void
setBusinessTable
(
String
businessTable
)
{
this
.
businessTable
=
businessTable
;
}
public
String
getAssigneeName
()
{
return
assigneeName
;
}
public
void
setAssigneeName
(
String
assigneeName
)
{
this
.
assigneeName
=
assigneeName
;
}
public
String
getAssignee
()
{
if
(
assignee
==
null
&&
task
!=
null
){
assignee
=
task
.
getAssignee
();
}
return
assignee
;
}
public
void
setAssignee
(
String
assignee
)
{
this
.
assignee
=
assignee
;
}
public
List
<
Act
>
getList
()
{
return
list
;
}
public
void
setList
(
List
<
Act
>
list
)
{
this
.
list
=
list
;
}
public
Variable
getVars
()
{
return
vars
;
}
public
void
setVars
(
Variable
vars
)
{
this
.
vars
=
vars
;
}
/**
* 通过Map设置流程变量值
* @param map
*/
public
void
setVars
(
Map
<
String
,
Object
>
map
)
{
this
.
vars
=
new
Variable
(
map
);
}
// public Variable getTaskVars() {
// return taskVars;
// }
//
// public void setTaskVars(Variable taskVars) {
// this.taskVars = taskVars;
// }
//
// /**
// * 通过Map设置流程任务变量值
// * @param map
// */
// public void setTaskVars(Map<String, Object> map) {
// this.taskVars = new Variable(map);
// }
/**
* 获取流程定义KEY
* @return
*/
public
String
getProcDefKey
()
{
if
(
StringUtils
.
isBlank
(
procDefKey
)
&&
StringUtils
.
isNotBlank
(
procDefId
)){
procDefKey
=
StringUtils
.
split
(
procDefId
,
":"
)[
0
];
}
return
procDefKey
;
}
public
void
setProcDefKey
(
String
procDefKey
)
{
this
.
procDefKey
=
procDefKey
;
}
/**
* 获取过去的任务历时
* @return
*/
public
String
getDurationTime
(){
if
(
histIns
!=
null
&&
histIns
.
getDurationInMillis
()
!=
null
){
return
TimeUtils
.
toTimeString
(
histIns
.
getDurationInMillis
());
}
return
""
;
}
/**
* 是否是一个待办任务
* @return
*/
public
boolean
isTodoTask
(){
return
"todo"
.
equals
(
status
)
||
"claim"
.
equals
(
status
);
}
/**
* 是否是已完成任务
* @return
*/
public
boolean
isFinishTask
(){
return
"finish"
.
equals
(
status
)
||
StringUtils
.
isBlank
(
taskId
);
}
@Override
public
void
preInsert
()
{
}
@Override
public
void
preUpdate
()
{
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/rest/diagram/services/BaseProcessDefinitionDiagramLayoutResource.java
0 → 100644
View file @
20e6484f
/* 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.jeespring.modules.act.rest.diagram.services
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.activiti.engine.ActivitiException
;
import
org.activiti.engine.ActivitiObjectNotFoundException
;
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.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.ActivityImpl
;
import
org.activiti.engine.impl.pvm.process.Lane
;
import
org.activiti.engine.impl.pvm.process.LaneSet
;
import
org.activiti.engine.impl.pvm.process.ParticipantProcess
;
import
org.activiti.engine.impl.pvm.process.TransitionImpl
;
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
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
;
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
();
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/rest/diagram/services/ProcessDefinitionDiagramLayoutResource.java
0 → 100644
View file @
20e6484f
/* 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.jeespring.modules.act.rest.diagram.services
;
import
org.apache.shiro.authz.annotation.RequiresUser
;
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
com.fasterxml.jackson.databind.node.ObjectNode
;
@RestController
public
class
ProcessDefinitionDiagramLayoutResource
extends
BaseProcessDefinitionDiagramLayoutResource
{
@RequiresUser
@RequestMapping
(
value
=
"/act/service/process-definition/{processDefinitionId}/diagram-layout"
,
method
=
RequestMethod
.
GET
,
produces
=
"application/json"
)
public
ObjectNode
getDiagram
(
@PathVariable
String
processDefinitionId
)
{
return
getDiagramNode
(
null
,
processDefinitionId
);
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/rest/diagram/services/ProcessInstanceDiagramLayoutResource.java
0 → 100644
View file @
20e6484f
/* 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.jeespring.modules.act.rest.diagram.services
;
import
org.apache.shiro.authz.annotation.RequiresUser
;
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
com.fasterxml.jackson.databind.node.ObjectNode
;
@RestController
public
class
ProcessInstanceDiagramLayoutResource
extends
BaseProcessDefinitionDiagramLayoutResource
{
@RequiresUser
@RequestMapping
(
value
=
"/act/service/process-instance/{processInstanceId}/diagram-layout"
,
method
=
RequestMethod
.
GET
,
produces
=
"application/json"
)
public
ObjectNode
getDiagram
(
@PathVariable
String
processInstanceId
)
{
return
getDiagramNode
(
processInstanceId
,
null
);
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/rest/diagram/services/ProcessInstanceHighlightsResource.java
0 → 100644
View file @
20e6484f
/* 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.jeespring.modules.act.rest.diagram.services
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
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.apache.shiro.authz.annotation.RequiresUser
;
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
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.node.ArrayNode
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
@RestController
public
class
ProcessInstanceHighlightsResource
{
@Autowired
private
RuntimeService
runtimeService
;
@Autowired
private
RepositoryService
repositoryService
;
@Autowired
private
HistoryService
historyService
;
protected
ObjectMapper
objectMapper
=
new
ObjectMapper
();
@RequiresUser
@RequestMapping
(
value
=
"/act/service/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
;
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/rest/editor/main/StencilsetRestResource.java
0 → 100644
View file @
20e6484f
/* 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.jeespring.modules.act.rest.editor.main
;
import
java.io.InputStream
;
import
org.activiti.engine.ActivitiException
;
import
org.apache.commons.io.IOUtils
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
org.springframework.web.bind.annotation.RestController
;
/**
* @author Tijs Rademakers
*/
@RestController
public
class
StencilsetRestResource
{
@RequestMapping
(
value
=
"/act/service/editor/stencilset"
,
method
=
RequestMethod
.
GET
,
produces
=
"application/json;charset=utf-8"
)
public
@ResponseBody
String
getStencilset
()
{
InputStream
stencilsetStream
=
this
.
getClass
().
getClassLoader
().
getResourceAsStream
(
"stencilset.json"
);
try
{
return
IOUtils
.
toString
(
stencilsetStream
,
"utf-8"
);
}
catch
(
Exception
e
)
{
throw
new
ActivitiException
(
"Error while loading stencil set"
,
e
);
}
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/rest/editor/model/ModelEditorJsonRestResource.java
0 → 100644
View file @
20e6484f
/* 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.jeespring.modules.act.rest.editor.model
;
import
org.activiti.editor.constants.ModelDataJsonConstants
;
import
org.activiti.engine.ActivitiException
;
import
org.activiti.engine.RepositoryService
;
import
org.activiti.engine.repository.Model
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.shiro.authz.annotation.RequiresPermissions
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
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
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
/**
* @author Tijs Rademakers
*/
@RestController
public
class
ModelEditorJsonRestResource
implements
ModelDataJsonConstants
{
protected
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
ModelEditorJsonRestResource
.
class
);
@Autowired
private
RepositoryService
repositoryService
;
// @Autowired
// private ObjectMapper objectMapper;
protected
ObjectMapper
objectMapper
=
new
ObjectMapper
();
@RequiresPermissions
(
"act:model:edit"
)
@RequestMapping
(
value
=
"/act/service/model/{modelId}/json"
,
method
=
RequestMethod
.
GET
,
produces
=
"application/json"
)
public
ObjectNode
getEditorJson
(
@PathVariable
String
modelId
)
{
ObjectNode
modelNode
=
null
;
Model
model
=
repositoryService
.
getModel
(
modelId
);
if
(
model
!=
null
)
{
try
{
if
(
StringUtils
.
isNotEmpty
(
model
.
getMetaInfo
()))
{
modelNode
=
(
ObjectNode
)
objectMapper
.
readTree
(
model
.
getMetaInfo
());
}
else
{
modelNode
=
objectMapper
.
createObjectNode
();
modelNode
.
put
(
MODEL_NAME
,
model
.
getName
());
}
modelNode
.
put
(
MODEL_ID
,
model
.
getId
());
ObjectNode
editorJsonNode
=
(
ObjectNode
)
objectMapper
.
readTree
(
new
String
(
repositoryService
.
getModelEditorSource
(
model
.
getId
()),
"utf-8"
));
modelNode
.
put
(
"model"
,
editorJsonNode
);
}
catch
(
Exception
e
)
{
LOGGER
.
error
(
"Error creating model JSON"
,
e
);
throw
new
ActivitiException
(
"Error creating model JSON"
,
e
);
}
}
return
modelNode
;
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/rest/editor/model/ModelSaveRestResource.java
0 → 100644
View file @
20e6484f
/* 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.jeespring.modules.act.rest.editor.model
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.InputStream
;
import
org.activiti.editor.constants.ModelDataJsonConstants
;
import
org.activiti.engine.ActivitiException
;
import
org.activiti.engine.RepositoryService
;
import
org.activiti.engine.repository.Model
;
import
org.apache.batik.transcoder.TranscoderInput
;
import
org.apache.batik.transcoder.TranscoderOutput
;
import
org.apache.batik.transcoder.image.PNGTranscoder
;
import
org.apache.log4j.Logger
;
import
org.apache.shiro.authz.annotation.RequiresPermissions
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.web.bind.annotation.*
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
/**
* @author Tijs Rademakers
*/
@RestController
public
class
ModelSaveRestResource
implements
ModelDataJsonConstants
{
protected
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
ModelSaveRestResource
.
class
);
@Autowired
private
RepositoryService
repositoryService
;
// @Autowired
// private ObjectMapper objectMapper;
protected
ObjectMapper
objectMapper
=
new
ObjectMapper
();
@RequiresPermissions
(
"act:model:edit"
)
@RequestMapping
(
value
=
"/act/service/model/{modelId}/save"
,
method
={
RequestMethod
.
POST
,
RequestMethod
.
GET
,
RequestMethod
.
PUT
})
@ResponseStatus
(
value
=
HttpStatus
.
OK
)
// @RequestBody MultiValueMap<String, String> values,MultiValueMap<String, String> valuesa
public
void
saveModel
(
@PathVariable
String
modelId
,
HttpServletRequest
request
,
HttpServletResponse
response
)
{
try
{
MultiValueMap
<
String
,
String
>
values
=
new
LinkedMultiValueMap
<>();;
Model
model
=
repositoryService
.
getModel
(
modelId
);
String
name
=
""
,
description
=
""
,
json_xml
=
""
,
svg_xml
=
""
;
values
.
add
(
"name"
,
request
.
getParameter
(
"name"
));
values
.
add
(
"description"
,
request
.
getParameter
(
"description"
));
values
.
add
(
"json_xml"
,
request
.
getParameter
(
"json_xml"
));
values
.
add
(
"svg_xml"
,
request
.
getParameter
(
"svg_xml"
));
ObjectNode
modelJson
=
(
ObjectNode
)
objectMapper
.
readTree
(
model
.
getMetaInfo
());
modelJson
.
put
(
MODEL_NAME
,
values
.
getFirst
(
"name"
));
modelJson
.
put
(
MODEL_DESCRIPTION
,
values
.
getFirst
(
"description"
));
model
.
setMetaInfo
(
modelJson
.
toString
());
model
.
setName
(
values
.
getFirst
(
"name"
));
repositoryService
.
saveModel
(
model
);
repositoryService
.
addModelEditorSource
(
model
.
getId
(),
values
.
getFirst
(
"json_xml"
).
getBytes
(
"utf-8"
));
InputStream
svgStream
=
new
ByteArrayInputStream
(
values
.
getFirst
(
"svg_xml"
).
getBytes
(
"utf-8"
));
TranscoderInput
input
=
new
TranscoderInput
(
svgStream
);
PNGTranscoder
transcoder
=
new
PNGTranscoder
();
// Setup output
ByteArrayOutputStream
outStream
=
new
ByteArrayOutputStream
();
TranscoderOutput
output
=
new
TranscoderOutput
(
outStream
);
// Do the transformation
transcoder
.
transcode
(
input
,
output
);
final
byte
[]
result
=
outStream
.
toByteArray
();
repositoryService
.
addModelEditorSourceExtra
(
model
.
getId
(),
result
);
outStream
.
close
();
}
catch
(
Exception
e
)
{
LOGGER
.
error
(
"Error saving model"
,
e
);
throw
new
ActivitiException
(
"Error saving model"
,
e
);
}
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/rest/servlet/FilterServletOutputStream.java
0 → 100644
View file @
20e6484f
package
com.jeespring.modules.act.rest.servlet
;
import
java.io.DataOutputStream
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
javax.servlet.ServletOutputStream
;
import
javax.servlet.WriteListener
;
public
class
FilterServletOutputStream
extends
ServletOutputStream
{
private
DataOutputStream
stream
;
public
FilterServletOutputStream
(
OutputStream
output
)
{
stream
=
new
DataOutputStream
(
output
);
}
public
void
write
(
int
b
)
throws
IOException
{
stream
.
write
(
b
);
}
public
void
write
(
byte
[]
b
)
throws
IOException
{
stream
.
write
(
b
);
}
public
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
stream
.
write
(
b
,
off
,
len
);
}
@Override
public
boolean
isReady
()
{
return
false
;
}
@Override
public
void
setWriteListener
(
WriteListener
writeListener
)
{
}
}
\ No newline at end of file
JeeSpringCloud/src/main/java/com/jeespring/modules/act/rest/servlet/GenericResponseWrapper.java
0 → 100644
View file @
20e6484f
package
com.jeespring.modules.act.rest.servlet
;
import
java.io.ByteArrayOutputStream
;
import
java.io.PrintWriter
;
import
javax.servlet.ServletOutputStream
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpServletResponseWrapper
;
public
class
GenericResponseWrapper
extends
HttpServletResponseWrapper
{
private
ByteArrayOutputStream
output
;
private
int
contentLength
;
private
String
contentType
;
public
GenericResponseWrapper
(
HttpServletResponse
response
)
{
super
(
response
);
output
=
new
ByteArrayOutputStream
();
}
public
byte
[]
getData
()
{
return
output
.
toByteArray
();
}
public
ServletOutputStream
getOutputStream
()
{
return
new
FilterServletOutputStream
(
output
);
}
public
PrintWriter
getWriter
()
{
return
new
PrintWriter
(
getOutputStream
(),
true
);
}
public
void
setContentLength
(
int
length
)
{
this
.
contentLength
=
length
;
super
.
setContentLength
(
length
);
}
public
int
getContentLength
()
{
return
contentLength
;
}
public
void
setContentType
(
String
type
)
{
this
.
contentType
=
type
;
super
.
setContentType
(
type
);
}
public
String
getContentType
()
{
return
contentType
;
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/rest/servlet/JsonpCallbackFilter.java
0 → 100644
View file @
20e6484f
package
com.jeespring.modules.act.rest.servlet
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.util.Map
;
import
javax.servlet.Filter
;
import
javax.servlet.FilterChain
;
import
javax.servlet.FilterConfig
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.annotation.WebFilter
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
@WebFilter
(
urlPatterns
={
"/act/service/*"
})
public
class
JsonpCallbackFilter
implements
Filter
{
private
static
Logger
log
=
LoggerFactory
.
getLogger
(
JsonpCallbackFilter
.
class
);
public
void
init
(
FilterConfig
fConfig
)
throws
ServletException
{}
public
void
doFilter
(
ServletRequest
request
,
ServletResponse
response
,
FilterChain
chain
)
throws
IOException
,
ServletException
{
HttpServletRequest
httpRequest
=
(
HttpServletRequest
)
request
;
HttpServletResponse
httpResponse
=
(
HttpServletResponse
)
response
;
@SuppressWarnings
(
"unchecked"
)
Map
<
String
,
String
[]>
parms
=
httpRequest
.
getParameterMap
();
if
(
parms
.
containsKey
(
"callback"
))
{
if
(
log
.
isDebugEnabled
())
log
.
debug
(
"Wrapping response with JSONP callback '"
+
parms
.
get
(
"callback"
)[
0
]
+
"'"
);
OutputStream
out
=
httpResponse
.
getOutputStream
();
GenericResponseWrapper
wrapper
=
new
GenericResponseWrapper
(
httpResponse
);
chain
.
doFilter
(
request
,
wrapper
);
//handles the content-size truncation
ByteArrayOutputStream
outputStream
=
new
ByteArrayOutputStream
();
outputStream
.
write
(
new
String
(
parms
.
get
(
"callback"
)[
0
]
+
"("
).
getBytes
());
outputStream
.
write
(
wrapper
.
getData
());
outputStream
.
write
(
new
String
(
");"
).
getBytes
());
byte
jsonpResponse
[]
=
outputStream
.
toByteArray
();
wrapper
.
setContentType
(
"text/javascript;charset=UTF-8"
);
wrapper
.
setContentLength
(
jsonpResponse
.
length
);
out
.
write
(
jsonpResponse
);
out
.
close
();
}
else
{
chain
.
doFilter
(
request
,
response
);
}
}
public
void
destroy
()
{}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/service/ActModelService.java
0 → 100644
View file @
20e6484f
/**
* Copyright © 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
*/
package
com.jeespring.modules.act.service
;
import
java.io.ByteArrayInputStream
;
import
java.io.IOException
;
import
java.io.UnsupportedEncodingException
;
import
java.util.List
;
import
javax.servlet.http.HttpServletResponse
;
import
org.activiti.bpmn.converter.BpmnXMLConverter
;
import
org.activiti.bpmn.model.BpmnModel
;
import
org.activiti.editor.constants.ModelDataJsonConstants
;
import
org.activiti.editor.language.json.converter.BpmnJsonConverter
;
import
org.activiti.engine.ActivitiException
;
import
org.activiti.engine.RepositoryService
;
import
org.activiti.engine.repository.Deployment
;
import
org.activiti.engine.repository.Model
;
import
org.activiti.engine.repository.ModelQuery
;
import
org.activiti.engine.repository.ProcessDefinition
;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
import
com.jeespring.common.persistence.Page
;
import
com.jeespring.common.service.AbstractService
;
/**
* 流程模型相关Controller
* @author ThinkGem
* @version 2013-11-03
*/
@Service
@Transactional
(
readOnly
=
true
)
public
class
ActModelService
extends
AbstractService
{
@Autowired
private
RepositoryService
repositoryService
;
// @Autowired
// private ObjectMapper objectMapper;
protected
ObjectMapper
objectMapper
=
new
ObjectMapper
();
/**
* 流程模型列表
*/
public
Page
<
Model
>
modelList
(
Page
<
Model
>
page
,
String
category
)
{
ModelQuery
modelQuery
=
repositoryService
.
createModelQuery
().
latestVersion
().
orderByLastUpdateTime
().
desc
();
if
(
StringUtils
.
isNotEmpty
(
category
)){
modelQuery
.
modelCategory
(
category
);
}
page
.
setCount
(
modelQuery
.
count
());
page
.
setList
(
modelQuery
.
listPage
(
page
.
getFirstResult
(),
page
.
getMaxResults
()));
return
page
;
}
/**
* 创建模型
* @throws UnsupportedEncodingException
*/
@Transactional
(
readOnly
=
false
)
public
Model
create
(
String
name
,
String
key
,
String
description
,
String
category
)
throws
UnsupportedEncodingException
{
ObjectNode
editorNode
=
objectMapper
.
createObjectNode
();
editorNode
.
put
(
"id"
,
"canvas"
);
editorNode
.
put
(
"resourceId"
,
"canvas"
);
ObjectNode
properties
=
objectMapper
.
createObjectNode
();
properties
.
put
(
"process_author"
,
"jeesite"
);
editorNode
.
put
(
"properties"
,
properties
);
ObjectNode
stencilset
=
objectMapper
.
createObjectNode
();
stencilset
.
put
(
"namespace"
,
"http://b3mn.org/stencilset/bpmn2.0#"
);
editorNode
.
put
(
"stencilset"
,
stencilset
);
Model
modelData
=
repositoryService
.
newModel
();
description
=
StringUtils
.
defaultString
(
description
);
modelData
.
setKey
(
StringUtils
.
defaultString
(
key
));
modelData
.
setName
(
name
);
modelData
.
setCategory
(
category
);
modelData
.
setVersion
(
Integer
.
parseInt
(
String
.
valueOf
(
repositoryService
.
createModelQuery
().
modelKey
(
modelData
.
getKey
()).
count
()+
1
)));
ObjectNode
modelObjectNode
=
objectMapper
.
createObjectNode
();
modelObjectNode
.
put
(
ModelDataJsonConstants
.
MODEL_NAME
,
name
);
modelObjectNode
.
put
(
ModelDataJsonConstants
.
MODEL_REVISION
,
modelData
.
getVersion
());
modelObjectNode
.
put
(
ModelDataJsonConstants
.
MODEL_DESCRIPTION
,
description
);
modelData
.
setMetaInfo
(
modelObjectNode
.
toString
());
repositoryService
.
saveModel
(
modelData
);
repositoryService
.
addModelEditorSource
(
modelData
.
getId
(),
editorNode
.
toString
().
getBytes
(
"utf-8"
));
return
modelData
;
}
/**
* 根据Model部署流程
*/
@Transactional
(
readOnly
=
false
)
public
String
deploy
(
String
id
)
{
String
message
=
""
;
try
{
Model
modelData
=
repositoryService
.
getModel
(
id
);
BpmnJsonConverter
jsonConverter
=
new
BpmnJsonConverter
();
JsonNode
editorNode
=
new
ObjectMapper
().
readTree
(
repositoryService
.
getModelEditorSource
(
modelData
.
getId
()));
BpmnModel
bpmnModel
=
jsonConverter
.
convertToBpmnModel
(
editorNode
);
BpmnXMLConverter
xmlConverter
=
new
BpmnXMLConverter
();
byte
[]
bpmnBytes
=
xmlConverter
.
convertToXML
(
bpmnModel
);
String
processName
=
modelData
.
getName
();
if
(!
StringUtils
.
endsWith
(
processName
,
".bpmn20.xml"
)){
processName
+=
".bpmn20.xml"
;
}
// System.out.println("========="+processName+"============"+modelData.getName());
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
bpmnBytes
);
Deployment
deployment
=
repositoryService
.
createDeployment
().
name
(
modelData
.
getName
())
.
addInputStream
(
processName
,
in
).
deploy
();
// .addString(processName, new String(bpmnBytes)).deploy();
// 设置流程分类
List
<
ProcessDefinition
>
list
=
repositoryService
.
createProcessDefinitionQuery
().
deploymentId
(
deployment
.
getId
()).
list
();
for
(
ProcessDefinition
processDefinition
:
list
)
{
repositoryService
.
setProcessDefinitionCategory
(
processDefinition
.
getId
(),
modelData
.
getCategory
());
message
=
"部署成功,流程ID="
+
processDefinition
.
getId
();
}
if
(
list
.
size
()
==
0
){
message
=
"部署失败,没有流程。"
;
}
}
catch
(
Exception
e
)
{
throw
new
ActivitiException
(
"设计模型图不正确,检查模型正确性,模型ID="
+
id
,
e
);
}
return
message
;
}
/**
* 导出model的xml文件
* @throws IOException
* @throws JsonProcessingException
*/
public
void
export
(
String
id
,
HttpServletResponse
response
)
{
try
{
Model
modelData
=
repositoryService
.
getModel
(
id
);
BpmnJsonConverter
jsonConverter
=
new
BpmnJsonConverter
();
JsonNode
editorNode
=
new
ObjectMapper
().
readTree
(
repositoryService
.
getModelEditorSource
(
modelData
.
getId
()));
BpmnModel
bpmnModel
=
jsonConverter
.
convertToBpmnModel
(
editorNode
);
BpmnXMLConverter
xmlConverter
=
new
BpmnXMLConverter
();
byte
[]
bpmnBytes
=
xmlConverter
.
convertToXML
(
bpmnModel
);
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
bpmnBytes
);
IOUtils
.
copy
(
in
,
response
.
getOutputStream
());
String
filename
=
bpmnModel
.
getMainProcess
().
getId
()
+
".bpmn20.xml"
;
response
.
setHeader
(
"Content-Disposition"
,
"attachment; filename="
+
filename
);
response
.
flushBuffer
();
}
catch
(
Exception
e
)
{
throw
new
ActivitiException
(
"导出model的xml文件失败,模型ID="
+
id
,
e
);
}
}
/**
* 更新Model分类
*/
@Transactional
(
readOnly
=
false
)
public
void
updateCategory
(
String
id
,
String
category
)
{
Model
modelData
=
repositoryService
.
getModel
(
id
);
modelData
.
setCategory
(
category
);
repositoryService
.
saveModel
(
modelData
);
}
/**
* 删除模型
* @param id
* @return
*/
@Transactional
(
readOnly
=
false
)
public
void
delete
(
String
id
)
{
repositoryService
.
deleteModel
(
id
);
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/service/ActProcessService.java
0 → 100644
View file @
20e6484f
/**
* Copyright © 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
*/
package
com.jeespring.modules.act.service
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.io.UnsupportedEncodingException
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.zip.ZipInputStream
;
import
javax.xml.stream.XMLInputFactory
;
import
javax.xml.stream.XMLStreamException
;
import
javax.xml.stream.XMLStreamReader
;
import
org.activiti.bpmn.converter.BpmnXMLConverter
;
import
org.activiti.bpmn.model.BpmnModel
;
import
org.activiti.editor.constants.ModelDataJsonConstants
;
import
org.activiti.editor.language.json.converter.BpmnJsonConverter
;
import
org.activiti.engine.ActivitiException
;
import
org.activiti.engine.RepositoryService
;
import
org.activiti.engine.RuntimeService
;
import
org.activiti.engine.repository.Deployment
;
import
org.activiti.engine.repository.ProcessDefinition
;
import
org.activiti.engine.repository.ProcessDefinitionQuery
;
import
org.activiti.engine.runtime.ProcessInstance
;
import
org.activiti.engine.runtime.ProcessInstanceQuery
;
import
org.apache.commons.io.FileUtils
;
import
org.apache.commons.io.FilenameUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.multipart.MultipartFile
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
import
com.jeespring.common.persistence.Page
;
import
com.jeespring.common.service.AbstractService
;
import
com.jeespring.common.utils.StringUtils
;
/**
* 流程定义相关Controller
* @author ThinkGem
* @version 2013-11-03
*/
@Service
@Transactional
(
readOnly
=
true
)
public
class
ActProcessService
extends
AbstractService
{
@Autowired
private
RepositoryService
repositoryService
;
@Autowired
private
RuntimeService
runtimeService
;
/**
* 流程定义列表
*/
public
Page
<
Object
[]>
processList
(
Page
<
Object
[]>
page
,
String
category
)
{
ProcessDefinitionQuery
processDefinitionQuery
=
repositoryService
.
createProcessDefinitionQuery
()
.
latestVersion
().
orderByProcessDefinitionKey
().
asc
();
if
(
StringUtils
.
isNotEmpty
(
category
)){
processDefinitionQuery
.
processDefinitionCategory
(
category
);
}
page
.
setCount
(
processDefinitionQuery
.
count
());
List
<
ProcessDefinition
>
processDefinitionList
=
processDefinitionQuery
.
listPage
(
page
.
getFirstResult
(),
page
.
getMaxResults
());
for
(
ProcessDefinition
processDefinition
:
processDefinitionList
)
{
String
deploymentId
=
processDefinition
.
getDeploymentId
();
Deployment
deployment
=
repositoryService
.
createDeploymentQuery
().
deploymentId
(
deploymentId
).
singleResult
();
page
.
getList
().
add
(
new
Object
[]{
processDefinition
,
deployment
});
}
return
page
;
}
/**
* 流程定义列表
*/
public
Page
<
ProcessInstance
>
runningList
(
Page
<
ProcessInstance
>
page
,
String
procInsId
,
String
procDefKey
)
{
ProcessInstanceQuery
processInstanceQuery
=
runtimeService
.
createProcessInstanceQuery
();
if
(
StringUtils
.
isNotBlank
(
procInsId
)){
processInstanceQuery
.
processInstanceId
(
procInsId
);
}
if
(
StringUtils
.
isNotBlank
(
procDefKey
)){
processInstanceQuery
.
processDefinitionKey
(
procDefKey
);
}
page
.
setCount
(
processInstanceQuery
.
count
());
page
.
setList
(
processInstanceQuery
.
listPage
(
page
.
getFirstResult
(),
page
.
getMaxResults
()));
return
page
;
}
/**
* 读取资源,通过部署ID
* @param processDefinitionId 流程定义ID
* @param processInstanceId 流程实例ID
* @param resourceType 资源类型(xml|image)
*/
public
InputStream
resourceRead
(
String
procDefId
,
String
proInsId
,
String
resType
)
throws
Exception
{
if
(
StringUtils
.
isBlank
(
procDefId
)){
ProcessInstance
processInstance
=
runtimeService
.
createProcessInstanceQuery
().
processInstanceId
(
proInsId
).
singleResult
();
procDefId
=
processInstance
.
getProcessDefinitionId
();
}
ProcessDefinition
processDefinition
=
repositoryService
.
createProcessDefinitionQuery
().
processDefinitionId
(
procDefId
).
singleResult
();
String
resourceName
=
""
;
if
(
resType
.
equals
(
"image"
))
{
resourceName
=
processDefinition
.
getDiagramResourceName
();
}
else
if
(
resType
.
equals
(
"xml"
))
{
resourceName
=
processDefinition
.
getResourceName
();
}
InputStream
resourceAsStream
=
repositoryService
.
getResourceAsStream
(
processDefinition
.
getDeploymentId
(),
resourceName
);
return
resourceAsStream
;
}
/**
* 部署流程 - 保存
* @param file
* @return
*/
@Transactional
(
readOnly
=
false
)
public
String
deploy
(
String
exportDir
,
String
category
,
MultipartFile
file
)
{
String
message
=
""
;
String
fileName
=
file
.
getOriginalFilename
();
try
{
InputStream
fileInputStream
=
file
.
getInputStream
();
Deployment
deployment
;
String
extension
=
FilenameUtils
.
getExtension
(
fileName
);
if
(
extension
.
equals
(
"zip"
)
||
extension
.
equals
(
"bar"
))
{
ZipInputStream
zip
=
new
ZipInputStream
(
fileInputStream
);
deployment
=
repositoryService
.
createDeployment
().
addZipInputStream
(
zip
).
deploy
();
}
else
if
(
extension
.
equals
(
"png"
))
{
deployment
=
repositoryService
.
createDeployment
().
addInputStream
(
fileName
,
fileInputStream
).
deploy
();
}
else
if
(
fileName
.
indexOf
(
"bpmn20.xml"
)
!=
-
1
)
{
deployment
=
repositoryService
.
createDeployment
().
addInputStream
(
fileName
,
fileInputStream
).
deploy
();
}
else
if
(
extension
.
equals
(
"bpmn"
))
{
// bpmn扩展名特殊处理,转换为bpmn20.xml
String
baseName
=
FilenameUtils
.
getBaseName
(
fileName
);
deployment
=
repositoryService
.
createDeployment
().
addInputStream
(
baseName
+
".bpmn20.xml"
,
fileInputStream
).
deploy
();
}
else
{
message
=
"不支持的文件类型:"
+
extension
;
return
message
;
}
List
<
ProcessDefinition
>
list
=
repositoryService
.
createProcessDefinitionQuery
().
deploymentId
(
deployment
.
getId
()).
list
();
// 设置流程分类
for
(
ProcessDefinition
processDefinition
:
list
)
{
// ActUtils.exportDiagramToFile(repositoryService, processDefinition, exportDir);
repositoryService
.
setProcessDefinitionCategory
(
processDefinition
.
getId
(),
category
);
message
+=
"部署成功,流程ID="
+
processDefinition
.
getId
()
+
"<br/>"
;
}
if
(
list
.
size
()
==
0
){
message
=
"部署失败,没有流程。"
;
}
}
catch
(
Exception
e
)
{
throw
new
ActivitiException
(
"部署失败!"
,
e
);
}
return
message
;
}
/**
* 设置流程分类
*/
@Transactional
(
readOnly
=
false
)
public
void
updateCategory
(
String
procDefId
,
String
category
)
{
repositoryService
.
setProcessDefinitionCategory
(
procDefId
,
category
);
}
/**
* 挂起、激活流程实例
*/
@Transactional
(
readOnly
=
false
)
public
String
updateState
(
String
state
,
String
procDefId
)
{
if
(
state
.
equals
(
"active"
))
{
repositoryService
.
activateProcessDefinitionById
(
procDefId
,
true
,
null
);
return
"已激活ID为["
+
procDefId
+
"]的流程定义。"
;
}
else
if
(
state
.
equals
(
"suspend"
))
{
repositoryService
.
suspendProcessDefinitionById
(
procDefId
,
true
,
null
);
return
"已挂起ID为["
+
procDefId
+
"]的流程定义。"
;
}
return
"无操作"
;
}
/**
* 将部署的流程转换为模型
* @param procDefId
* @throws UnsupportedEncodingException
* @throws XMLStreamException
*/
@Transactional
(
readOnly
=
false
)
public
org
.
activiti
.
engine
.
repository
.
Model
convertToModel
(
String
procDefId
)
throws
UnsupportedEncodingException
,
XMLStreamException
{
ProcessDefinition
processDefinition
=
repositoryService
.
createProcessDefinitionQuery
().
processDefinitionId
(
procDefId
).
singleResult
();
InputStream
bpmnStream
=
repositoryService
.
getResourceAsStream
(
processDefinition
.
getDeploymentId
(),
processDefinition
.
getResourceName
());
XMLInputFactory
xif
=
XMLInputFactory
.
newInstance
();
InputStreamReader
in
=
new
InputStreamReader
(
bpmnStream
,
"UTF-8"
);
XMLStreamReader
xtr
=
xif
.
createXMLStreamReader
(
in
);
BpmnModel
bpmnModel
=
new
BpmnXMLConverter
().
convertToBpmnModel
(
xtr
);
BpmnJsonConverter
converter
=
new
BpmnJsonConverter
();
ObjectNode
modelNode
=
converter
.
convertToJson
(
bpmnModel
);
org
.
activiti
.
engine
.
repository
.
Model
modelData
=
repositoryService
.
newModel
();
modelData
.
setKey
(
processDefinition
.
getKey
());
modelData
.
setName
(
processDefinition
.
getResourceName
());
modelData
.
setCategory
(
processDefinition
.
getCategory
());
//.getDeploymentId());
modelData
.
setDeploymentId
(
processDefinition
.
getDeploymentId
());
modelData
.
setVersion
(
Integer
.
parseInt
(
String
.
valueOf
(
repositoryService
.
createModelQuery
().
modelKey
(
modelData
.
getKey
()).
count
()+
1
)));
ObjectNode
modelObjectNode
=
new
ObjectMapper
().
createObjectNode
();
modelObjectNode
.
put
(
ModelDataJsonConstants
.
MODEL_NAME
,
processDefinition
.
getName
());
modelObjectNode
.
put
(
ModelDataJsonConstants
.
MODEL_REVISION
,
modelData
.
getVersion
());
modelObjectNode
.
put
(
ModelDataJsonConstants
.
MODEL_DESCRIPTION
,
processDefinition
.
getDescription
());
modelData
.
setMetaInfo
(
modelObjectNode
.
toString
());
repositoryService
.
saveModel
(
modelData
);
repositoryService
.
addModelEditorSource
(
modelData
.
getId
(),
modelNode
.
toString
().
getBytes
(
"utf-8"
));
return
modelData
;
}
/**
* 导出图片文件到硬盘
*/
public
List
<
String
>
exportDiagrams
(
String
exportDir
)
throws
IOException
{
List
<
String
>
files
=
new
ArrayList
<
String
>();
List
<
ProcessDefinition
>
list
=
repositoryService
.
createProcessDefinitionQuery
().
list
();
for
(
ProcessDefinition
processDefinition
:
list
)
{
String
diagramResourceName
=
processDefinition
.
getDiagramResourceName
();
String
key
=
processDefinition
.
getKey
();
int
version
=
processDefinition
.
getVersion
();
String
diagramPath
=
""
;
InputStream
resourceAsStream
=
repositoryService
.
getResourceAsStream
(
processDefinition
.
getDeploymentId
(),
diagramResourceName
);
byte
[]
b
=
new
byte
[
resourceAsStream
.
available
()];
@SuppressWarnings
(
"unused"
)
int
len
=
-
1
;
resourceAsStream
.
read
(
b
,
0
,
b
.
length
);
// create file if not exist
String
diagramDir
=
exportDir
+
"/"
+
key
+
"/"
+
version
;
File
diagramDirFile
=
new
File
(
diagramDir
);
if
(!
diagramDirFile
.
exists
())
{
diagramDirFile
.
mkdirs
();
}
diagramPath
=
diagramDir
+
"/"
+
diagramResourceName
;
File
file
=
new
File
(
diagramPath
);
// 文件存在退出
if
(
file
.
exists
())
{
// 文件大小相同时直接返回否则重新创建文件(可能损坏)
logger
.
debug
(
"diagram exist, ignore... : {}"
,
diagramPath
);
files
.
add
(
diagramPath
);
}
else
{
file
.
createNewFile
();
logger
.
debug
(
"export diagram to : {}"
,
diagramPath
);
// wirte bytes to file
FileUtils
.
writeByteArrayToFile
(
file
,
b
,
true
);
files
.
add
(
diagramPath
);
}
}
return
files
;
}
/**
* 删除部署的流程,级联删除流程实例
* @param deploymentId 流程部署ID
*/
@Transactional
(
readOnly
=
false
)
public
void
deleteDeployment
(
String
deploymentId
)
{
repositoryService
.
deleteDeployment
(
deploymentId
,
true
);
}
/**
* 删除部署的流程实例
* @param procInsId 流程实例ID
* @param deleteReason 删除原因,可为空
*/
@Transactional
(
readOnly
=
false
)
public
void
deleteProcIns
(
String
procInsId
,
String
deleteReason
)
{
runtimeService
.
deleteProcessInstance
(
procInsId
,
deleteReason
);
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/service/ActTaskService.java
0 → 100644
View file @
20e6484f
/**
* Copyright © 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
*/
package
com.jeespring.modules.act.service
;
import
java.io.InputStream
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
org.activiti.bpmn.model.BpmnModel
;
import
org.activiti.engine.FormService
;
import
org.activiti.engine.HistoryService
;
import
org.activiti.engine.IdentityService
;
import
org.activiti.engine.ProcessEngine
;
import
org.activiti.engine.RepositoryService
;
import
org.activiti.engine.RuntimeService
;
import
org.activiti.engine.TaskService
;
import
org.activiti.engine.delegate.Expression
;
import
org.activiti.engine.history.HistoricActivityInstance
;
import
org.activiti.engine.history.HistoricProcessInstance
;
import
org.activiti.engine.history.HistoricTaskInstance
;
import
org.activiti.engine.history.HistoricTaskInstanceQuery
;
import
org.activiti.engine.impl.RepositoryServiceImpl
;
import
org.activiti.engine.impl.RuntimeServiceImpl
;
import
org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior
;
import
org.activiti.engine.impl.context.Context
;
import
org.activiti.engine.impl.identity.Authentication
;
import
org.activiti.engine.impl.interceptor.CommandExecutor
;
import
org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity
;
import
org.activiti.engine.impl.persistence.entity.TaskEntity
;
import
org.activiti.engine.impl.pvm.delegate.ActivityBehavior
;
import
org.activiti.engine.impl.pvm.process.ActivityImpl
;
import
org.activiti.engine.impl.task.TaskDefinition
;
import
org.activiti.engine.repository.Deployment
;
import
org.activiti.engine.repository.ProcessDefinition
;
import
org.activiti.engine.repository.ProcessDefinitionQuery
;
import
org.activiti.engine.runtime.Execution
;
import
org.activiti.engine.runtime.ProcessInstance
;
import
org.activiti.engine.task.Comment
;
import
org.activiti.engine.task.Task
;
import
org.activiti.engine.task.TaskQuery
;
import
org.activiti.spring.ProcessEngineFactoryBean
;
import
org.apache.commons.beanutils.PropertyUtils
;
import
org.apache.commons.lang3.builder.ToStringBuilder
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.util.CollectionUtils
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
com.jeespring.common.persistence.Page
;
import
com.jeespring.common.service.AbstractService
;
import
com.jeespring.common.utils.StringUtils
;
import
com.jeespring.modules.act.dao.ActDao
;
import
com.jeespring.modules.act.entity.Act
;
import
com.jeespring.modules.act.service.cmd.CreateAndTakeTransitionCmd
;
import
com.jeespring.modules.act.service.cmd.JumpTaskCmd
;
import
com.jeespring.modules.act.service.creator.ChainedActivitiesCreator
;
import
com.jeespring.modules.act.service.creator.MultiInstanceActivityCreator
;
import
com.jeespring.modules.act.service.creator.RuntimeActivityDefinitionEntityIntepreter
;
import
com.jeespring.modules.act.service.creator.SimpleRuntimeActivityDefinitionEntity
;
import
com.jeespring.modules.act.utils.ActUtils
;
import
com.jeespring.modules.act.utils.ProcessDefCache
;
import
com.jeespring.modules.act.utils.ProcessDefUtils
;
import
com.jeespring.modules.sys.entity.User
;
import
com.jeespring.modules.sys.utils.UserUtils
;
/**
* 流程定义相关Service
* @author ThinkGem
* @version 2013-11-03
*/
@Service
@Transactional
(
readOnly
=
true
)
public
class
ActTaskService
extends
AbstractService
{
@Autowired
private
ActDao
actDao
;
@Autowired
private
ProcessEngineFactoryBean
processEngineFactory
;
@Autowired
private
ProcessEngine
processEngine
;
@Autowired
private
RuntimeService
runtimeService
;
@Autowired
private
TaskService
taskService
;
@Autowired
private
FormService
formService
;
@Autowired
private
HistoryService
historyService
;
@Autowired
private
RepositoryService
repositoryService
;
@Autowired
private
IdentityService
identityService
;
/**
* 获取待办列表
* @param procDefKey 流程定义标识
* @return
*/
public
List
<
Act
>
todoList
(
Act
act
){
String
userId
=
UserUtils
.
getUser
().
getLoginName
();
//ObjectUtils.toString(UserUtils.getUser().getId());
List
<
Act
>
result
=
new
ArrayList
<
Act
>();
// =============== 已经签收的任务 ===============
TaskQuery
todoTaskQuery
=
taskService
.
createTaskQuery
().
taskAssignee
(
userId
).
active
()
.
includeProcessVariables
().
orderByTaskCreateTime
().
desc
();
// 设置查询条件
if
(
StringUtils
.
isNotBlank
(
act
.
getProcDefKey
())){
todoTaskQuery
.
processDefinitionKey
(
act
.
getProcDefKey
());
}
if
(
act
.
getBeginDate
()
!=
null
){
todoTaskQuery
.
taskCreatedAfter
(
act
.
getBeginDate
());
}
if
(
act
.
getEndDate
()
!=
null
){
todoTaskQuery
.
taskCreatedBefore
(
act
.
getEndDate
());
}
// 查询列表
List
<
Task
>
todoList
=
todoTaskQuery
.
list
();
for
(
Task
task
:
todoList
)
{
Act
e
=
new
Act
();
e
.
setTask
(
task
);
e
.
setVars
(
task
.
getProcessVariables
());
// e.setTaskVars(task.getTaskLocalVariables());
// System.out.println(task.getId()+" = "+task.getProcessVariables() + " ========== " + task.getTaskLocalVariables());
e
.
setProcDef
(
ProcessDefCache
.
get
(
task
.
getProcessDefinitionId
()));
// e.setProcIns(runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult());
// e.setProcExecUrl(ActUtils.getProcExeUrl(task.getProcessDefinitionId()));
e
.
setStatus
(
"todo"
);
result
.
add
(
e
);
}
// =============== 等待签收的任务 ===============
TaskQuery
toClaimQuery
=
taskService
.
createTaskQuery
().
taskCandidateUser
(
userId
)
.
includeProcessVariables
().
active
().
orderByTaskCreateTime
().
desc
();
// 设置查询条件
if
(
StringUtils
.
isNotBlank
(
act
.
getProcDefKey
())){
toClaimQuery
.
processDefinitionKey
(
act
.
getProcDefKey
());
}
if
(
act
.
getBeginDate
()
!=
null
){
toClaimQuery
.
taskCreatedAfter
(
act
.
getBeginDate
());
}
if
(
act
.
getEndDate
()
!=
null
){
toClaimQuery
.
taskCreatedBefore
(
act
.
getEndDate
());
}
// 查询列表
List
<
Task
>
toClaimList
=
toClaimQuery
.
list
();
for
(
Task
task
:
toClaimList
)
{
Act
e
=
new
Act
();
e
.
setTask
(
task
);
e
.
setVars
(
task
.
getProcessVariables
());
// e.setTaskVars(task.getTaskLocalVariables());
// System.out.println(task.getId()+" = "+task.getProcessVariables() + " ========== " + task.getTaskLocalVariables());
e
.
setProcDef
(
ProcessDefCache
.
get
(
task
.
getProcessDefinitionId
()));
// e.setProcIns(runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult());
// e.setProcExecUrl(ActUtils.getProcExeUrl(task.getProcessDefinitionId()));
e
.
setStatus
(
"claim"
);
result
.
add
(
e
);
}
return
result
;
}
/**
* 获取已办任务
* @param page
* @param procDefKey 流程定义标识
* @return
*/
public
Page
<
Act
>
historicList
(
Page
<
Act
>
page
,
Act
act
){
String
userId
=
UserUtils
.
getUser
().
getLoginName
();
//ObjectUtils.toString(UserUtils.getUser().getId());
HistoricTaskInstanceQuery
histTaskQuery
=
historyService
.
createHistoricTaskInstanceQuery
().
taskAssignee
(
userId
).
finished
()
.
includeProcessVariables
().
orderByHistoricTaskInstanceEndTime
().
desc
();
// 设置查询条件
if
(
StringUtils
.
isNotBlank
(
act
.
getProcDefKey
())){
histTaskQuery
.
processDefinitionKey
(
act
.
getProcDefKey
());
}
if
(
act
.
getBeginDate
()
!=
null
){
histTaskQuery
.
taskCompletedAfter
(
act
.
getBeginDate
());
}
if
(
act
.
getEndDate
()
!=
null
){
histTaskQuery
.
taskCompletedBefore
(
act
.
getEndDate
());
}
// 查询总数
page
.
setCount
(
histTaskQuery
.
count
());
// 查询列表
List
<
HistoricTaskInstance
>
histList
=
histTaskQuery
.
listPage
(
page
.
getFirstResult
(),
page
.
getMaxResults
());
//处理分页问题
List
<
Act
>
actList
=
Lists
.
newArrayList
();
for
(
HistoricTaskInstance
histTask
:
histList
)
{
Act
e
=
new
Act
();
e
.
setHistTask
(
histTask
);
e
.
setVars
(
histTask
.
getProcessVariables
());
// e.setTaskVars(histTask.getTaskLocalVariables());
// System.out.println(histTask.getId()+" = "+histTask.getProcessVariables() + " ========== " + histTask.getTaskLocalVariables());
e
.
setProcDef
(
ProcessDefCache
.
get
(
histTask
.
getProcessDefinitionId
()));
// e.setProcIns(runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult());
// e.setProcExecUrl(ActUtils.getProcExeUrl(task.getProcessDefinitionId()));
e
.
setStatus
(
"finish"
);
actList
.
add
(
e
);
//page.getList().add(e);
}
page
.
setList
(
actList
);
return
page
;
}
/**
* 获取流转历史列表
* @param procInsId 流程实例
* @param startAct 开始活动节点名称
* @param endAct 结束活动节点名称
*/
public
List
<
Act
>
histoicFlowList
(
String
procInsId
,
String
startAct
,
String
endAct
){
List
<
Act
>
actList
=
Lists
.
newArrayList
();
List
<
HistoricActivityInstance
>
list
=
historyService
.
createHistoricActivityInstanceQuery
().
processInstanceId
(
procInsId
)
.
orderByHistoricActivityInstanceStartTime
().
asc
().
orderByHistoricActivityInstanceEndTime
().
asc
().
list
();
boolean
start
=
false
;
Map
<
String
,
Integer
>
actMap
=
Maps
.
newHashMap
();
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++){
HistoricActivityInstance
histIns
=
list
.
get
(
i
);
// 过滤开始节点前的节点
if
(
StringUtils
.
isNotBlank
(
startAct
)
&&
startAct
.
equals
(
histIns
.
getActivityId
())){
start
=
true
;
}
if
(
StringUtils
.
isNotBlank
(
startAct
)
&&
!
start
){
continue
;
}
// 只显示开始节点和结束节点,并且执行人不为空的任务
if
(
StringUtils
.
isNotBlank
(
histIns
.
getAssignee
())
||
"startEvent"
.
equals
(
histIns
.
getActivityType
())
||
"endEvent"
.
equals
(
histIns
.
getActivityType
())){
// 给节点增加一个序号
Integer
actNum
=
actMap
.
get
(
histIns
.
getActivityId
());
if
(
actNum
==
null
){
actMap
.
put
(
histIns
.
getActivityId
(),
actMap
.
size
());
}
Act
e
=
new
Act
();
e
.
setHistIns
(
histIns
);
// 获取流程发起人名称
if
(
"startEvent"
.
equals
(
histIns
.
getActivityType
())){
List
<
HistoricProcessInstance
>
il
=
historyService
.
createHistoricProcessInstanceQuery
().
processInstanceId
(
procInsId
).
orderByProcessInstanceStartTime
().
asc
().
list
();
// List<HistoricIdentityLink> il = historyService.getHistoricIdentityLinksForProcessInstance(procInsId);
if
(
il
.
size
()
>
0
){
if
(
StringUtils
.
isNotBlank
(
il
.
get
(
0
).
getStartUserId
())){
User
user
=
UserUtils
.
getByLoginName
(
il
.
get
(
0
).
getStartUserId
());
if
(
user
!=
null
){
e
.
setAssignee
(
histIns
.
getAssignee
());
e
.
setAssigneeName
(
user
.
getName
());
}
}
}
}
// 获取任务执行人名称
if
(
StringUtils
.
isNotEmpty
(
histIns
.
getAssignee
())){
User
user
=
UserUtils
.
getByLoginName
(
histIns
.
getAssignee
());
if
(
user
!=
null
){
e
.
setAssignee
(
histIns
.
getAssignee
());
e
.
setAssigneeName
(
user
.
getName
());
}
}
// 获取意见评论内容
if
(
StringUtils
.
isNotBlank
(
histIns
.
getTaskId
())){
List
<
Comment
>
commentList
=
taskService
.
getTaskComments
(
histIns
.
getTaskId
());
if
(
commentList
.
size
()>
0
){
e
.
setComment
(
commentList
.
get
(
0
).
getFullMessage
());
}
}
actList
.
add
(
e
);
}
// 过滤结束节点后的节点
if
(
StringUtils
.
isNotBlank
(
endAct
)
&&
endAct
.
equals
(
histIns
.
getActivityId
())){
boolean
bl
=
false
;
Integer
actNum
=
actMap
.
get
(
histIns
.
getActivityId
());
// 该活动节点,后续节点是否在结束节点之前,在后续节点中是否存在
for
(
int
j
=
i
+
1
;
j
<
list
.
size
();
j
++){
HistoricActivityInstance
hi
=
list
.
get
(
j
);
Integer
actNumA
=
actMap
.
get
(
hi
.
getActivityId
());
if
((
actNumA
!=
null
&&
actNumA
<
actNum
)
||
StringUtils
.
equals
(
hi
.
getActivityId
(),
histIns
.
getActivityId
())){
bl
=
true
;
}
}
if
(!
bl
){
break
;
}
}
}
return
actList
;
}
/**
* 获取流程列表
* @param category 流程分类
*/
public
Page
<
Object
[]>
processList
(
Page
<
Object
[]>
page
,
String
category
)
{
/*
* 保存两个对象,一个是ProcessDefinition(流程定义),一个是Deployment(流程部署)
*/
ProcessDefinitionQuery
processDefinitionQuery
=
repositoryService
.
createProcessDefinitionQuery
()
.
latestVersion
().
active
().
orderByProcessDefinitionKey
().
asc
();
if
(
StringUtils
.
isNotEmpty
(
category
)){
processDefinitionQuery
.
processDefinitionCategory
(
category
);
}
page
.
setCount
(
processDefinitionQuery
.
count
());
List
<
ProcessDefinition
>
processDefinitionList
=
processDefinitionQuery
.
listPage
(
page
.
getFirstResult
(),
page
.
getMaxResults
());
for
(
ProcessDefinition
processDefinition
:
processDefinitionList
)
{
String
deploymentId
=
processDefinition
.
getDeploymentId
();
Deployment
deployment
=
repositoryService
.
createDeploymentQuery
().
deploymentId
(
deploymentId
).
singleResult
();
page
.
getList
().
add
(
new
Object
[]{
processDefinition
,
deployment
});
}
return
page
;
}
/**
* 获取流程表单(首先获取任务节点表单KEY,如果没有则取流程开始节点表单KEY)
* @return
*/
public
String
getFormKey
(
String
procDefId
,
String
taskDefKey
){
String
formKey
=
""
;
if
(
StringUtils
.
isNotBlank
(
procDefId
)){
if
(
StringUtils
.
isNotBlank
(
taskDefKey
)){
try
{
formKey
=
formService
.
getTaskFormKey
(
procDefId
,
taskDefKey
);
}
catch
(
Exception
e
)
{
formKey
=
""
;
}
}
if
(
StringUtils
.
isBlank
(
formKey
)){
formKey
=
formService
.
getStartFormKey
(
procDefId
);
}
if
(
StringUtils
.
isBlank
(
formKey
)){
formKey
=
"/404"
;
}
}
logger
.
debug
(
"getFormKey: {}"
,
formKey
);
return
formKey
;
}
/**
* 获取流程实例对象
* @param procInsId
* @return
*/
@Transactional
(
readOnly
=
false
)
public
ProcessInstance
getProcIns
(
String
procInsId
)
{
return
runtimeService
.
createProcessInstanceQuery
().
processInstanceId
(
procInsId
).
singleResult
();
}
/**
* 启动流程
* @param procDefKey 流程定义KEY
* @param businessTable 业务表表名
* @param businessId 业务表编号
* @return 流程实例ID
*/
@Transactional
(
readOnly
=
false
)
public
String
startProcess
(
String
procDefKey
,
String
businessTable
,
String
businessId
)
{
return
startProcess
(
procDefKey
,
businessTable
,
businessId
,
""
);
}
/**
* 启动流程
* @param procDefKey 流程定义KEY
* @param businessTable 业务表表名
* @param businessId 业务表编号
* @param title 流程标题,显示在待办任务标题
* @return 流程实例ID
*/
@Transactional
(
readOnly
=
false
)
public
String
startProcess
(
String
procDefKey
,
String
businessTable
,
String
businessId
,
String
title
)
{
Map
<
String
,
Object
>
vars
=
Maps
.
newHashMap
();
return
startProcess
(
procDefKey
,
businessTable
,
businessId
,
title
,
vars
);
}
/**
* 启动流程
* @param procDefKey 流程定义KEY
* @param businessTable 业务表表名
* @param businessId 业务表编号
* @param title 流程标题,显示在待办任务标题
* @param vars 流程变量
* @return 流程实例ID
*/
@Transactional
(
readOnly
=
false
)
public
String
startProcess
(
String
procDefKey
,
String
businessTable
,
String
businessId
,
String
title
,
Map
<
String
,
Object
>
vars
)
{
String
userId
=
UserUtils
.
getUser
().
getLoginName
();
//ObjectUtils.toString(UserUtils.getUser().getId())
// 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
identityService
.
setAuthenticatedUserId
(
userId
);
// 设置流程变量
if
(
vars
==
null
){
vars
=
Maps
.
newHashMap
();
}
// 设置流程标题
if
(
StringUtils
.
isNotBlank
(
title
)){
vars
.
put
(
"title"
,
title
);
}
// 启动流程
ProcessInstance
procIns
=
runtimeService
.
startProcessInstanceByKey
(
procDefKey
,
businessTable
+
":"
+
businessId
,
vars
);
// 更新业务表流程实例ID
Act
act
=
new
Act
();
act
.
setBusinessTable
(
businessTable
);
// 业务表名
act
.
setBusinessId
(
businessId
);
// 业务表ID
act
.
setProcInsId
(
procIns
.
getId
());
actDao
.
updateProcInsIdByBusinessId
(
act
);
return
act
.
getProcInsId
();
}
/**
* 获取任务
* @param taskId 任务ID
*/
public
Task
getTask
(
String
taskId
){
return
taskService
.
createTaskQuery
().
taskId
(
taskId
).
singleResult
();
}
/**
* 删除任务
* @param taskId 任务ID
* @param deleteReason 删除原因
*/
@Transactional
(
readOnly
=
false
)
public
void
deleteTask
(
String
taskId
,
String
deleteReason
){
taskService
.
deleteTask
(
taskId
,
deleteReason
);
}
/**
* 签收任务
* @param taskId 任务ID
* @param userId 签收用户ID(用户登录名)
*/
@Transactional
(
readOnly
=
false
)
public
void
claim
(
String
taskId
,
String
userId
){
taskService
.
claim
(
taskId
,
userId
);
}
/**
* 提交任务, 并保存意见
* @param taskId 任务ID
* @param procInsId 流程实例ID,如果为空,则不保存任务提交意见
* @param comment 任务提交意见的内容
* @param vars 任务变量
*/
@Transactional
(
readOnly
=
false
)
public
void
complete
(
String
taskId
,
String
procInsId
,
String
comment
,
Map
<
String
,
Object
>
vars
){
complete
(
taskId
,
procInsId
,
comment
,
""
,
vars
);
}
/**
* 提交任务, 并保存意见
* @param taskId 任务ID
* @param procInsId 流程实例ID,如果为空,则不保存任务提交意见
* @param comment 任务提交意见的内容
* @param title 流程标题,显示在待办任务标题
* @param vars 任务变量
*/
@Transactional
(
readOnly
=
false
)
public
void
complete
(
String
taskId
,
String
procInsId
,
String
comment
,
String
title
,
Map
<
String
,
Object
>
vars
){
// 添加意见
if
(
StringUtils
.
isNotBlank
(
procInsId
)
&&
StringUtils
.
isNotBlank
(
comment
)){
taskService
.
addComment
(
taskId
,
procInsId
,
comment
);
}
// 设置流程变量
if
(
vars
==
null
){
vars
=
Maps
.
newHashMap
();
}
// 设置流程标题
if
(
StringUtils
.
isNotBlank
(
title
)){
vars
.
put
(
"title"
,
title
);
}
// 提交任务
taskService
.
complete
(
taskId
,
vars
);
}
/**
* 完成第一个任务
* @param procInsId
*/
@Transactional
(
readOnly
=
false
)
public
void
completeFirstTask
(
String
procInsId
){
completeFirstTask
(
procInsId
,
null
,
null
,
null
);
}
/**
* 完成第一个任务
* @param procInsId
* @param comment
* @param title
* @param vars
*/
@Transactional
(
readOnly
=
false
)
public
void
completeFirstTask
(
String
procInsId
,
String
comment
,
String
title
,
Map
<
String
,
Object
>
vars
){
String
userId
=
UserUtils
.
getUser
().
getLoginName
();
Task
task
=
taskService
.
createTaskQuery
().
taskAssignee
(
userId
).
processInstanceId
(
procInsId
).
active
().
singleResult
();
if
(
task
!=
null
){
complete
(
task
.
getId
(),
procInsId
,
comment
,
title
,
vars
);
}
}
// /**
// * 委派任务
// * @param taskId 任务ID
// * @param userId 被委派人
// */
// public void delegateTask(String taskId, String userId){
// taskService.delegateTask(taskId, userId);
// }
//
// /**
// * 被委派人完成任务
// * @param taskId 任务ID
// */
// public void resolveTask(String taskId){
// taskService.resolveTask(taskId);
// }
//
// /**
// * 回退任务
// * @param taskId
// */
// public void backTask(String taskId){
// taskService.
// }
/**
* 添加任务意见
*/
public
void
addTaskComment
(
String
taskId
,
String
procInsId
,
String
comment
){
taskService
.
addComment
(
taskId
,
procInsId
,
comment
);
}
////////////////// 回退、前进、跳转、前加签、后加签、分裂 移植 https://github.com/bluejoe2008/openwebflow //////////////////////////////////////////////////
/**
* 任务后退一步
*/
public
void
taskBack
(
String
procInsId
,
Map
<
String
,
Object
>
variables
)
{
taskBack
(
getCurrentTask
(
procInsId
),
variables
);
}
/**
* 任务后退至指定活动
*/
public
void
taskBack
(
TaskEntity
currentTaskEntity
,
Map
<
String
,
Object
>
variables
)
{
ActivityImpl
activity
=
(
ActivityImpl
)
ProcessDefUtils
.
getActivity
(
processEngine
,
currentTaskEntity
.
getProcessDefinitionId
(),
currentTaskEntity
.
getTaskDefinitionKey
())
.
getIncomingTransitions
().
get
(
0
).
getSource
();
jumpTask
(
currentTaskEntity
,
activity
,
variables
);
}
/**
* 任务前进一步
*/
public
void
taskForward
(
String
procInsId
,
Map
<
String
,
Object
>
variables
)
{
taskForward
(
getCurrentTask
(
procInsId
),
variables
);
}
/**
* 任务前进至指定活动
*/
public
void
taskForward
(
TaskEntity
currentTaskEntity
,
Map
<
String
,
Object
>
variables
)
{
ActivityImpl
activity
=
(
ActivityImpl
)
ProcessDefUtils
.
getActivity
(
processEngine
,
currentTaskEntity
.
getProcessDefinitionId
(),
currentTaskEntity
.
getTaskDefinitionKey
())
.
getOutgoingTransitions
().
get
(
0
).
getDestination
();
jumpTask
(
currentTaskEntity
,
activity
,
variables
);
}
/**
* 跳转(包括回退和向前)至指定活动节点
*/
public
void
jumpTask
(
String
procInsId
,
String
targetTaskDefinitionKey
,
Map
<
String
,
Object
>
variables
)
{
jumpTask
(
getCurrentTask
(
procInsId
),
targetTaskDefinitionKey
,
variables
);
}
/**
* 跳转(包括回退和向前)至指定活动节点
*/
public
void
jumpTask
(
String
procInsId
,
String
currentTaskId
,
String
targetTaskDefinitionKey
,
Map
<
String
,
Object
>
variables
)
{
jumpTask
(
getTaskEntity
(
currentTaskId
),
targetTaskDefinitionKey
,
variables
);
}
/**
* 跳转(包括回退和向前)至指定活动节点
* @param currentTaskEntity 当前任务节点
* @param targetTaskDefinitionKey 目标任务节点(在模型定义里面的节点名称)
* @throws Exception
*/
public
void
jumpTask
(
TaskEntity
currentTaskEntity
,
String
targetTaskDefinitionKey
,
Map
<
String
,
Object
>
variables
)
{
ActivityImpl
activity
=
ProcessDefUtils
.
getActivity
(
processEngine
,
currentTaskEntity
.
getProcessDefinitionId
(),
targetTaskDefinitionKey
);
jumpTask
(
currentTaskEntity
,
activity
,
variables
);
}
/**
* 跳转(包括回退和向前)至指定活动节点
* @param currentTaskEntity 当前任务节点
* @param targetActivity 目标任务节点(在模型定义里面的节点名称)
* @throws Exception
*/
private
void
jumpTask
(
TaskEntity
currentTaskEntity
,
ActivityImpl
targetActivity
,
Map
<
String
,
Object
>
variables
)
{
CommandExecutor
commandExecutor
=
((
RuntimeServiceImpl
)
runtimeService
).
getCommandExecutor
();
commandExecutor
.
execute
(
new
JumpTaskCmd
(
currentTaskEntity
,
targetActivity
,
variables
));
}
/**
* 后加签
*/
@SuppressWarnings
(
"unchecked"
)
public
ActivityImpl
[]
insertTasksAfter
(
String
procDefId
,
String
procInsId
,
String
targetTaskDefinitionKey
,
Map
<
String
,
Object
>
variables
,
String
...
assignees
)
{
List
<
String
>
assigneeList
=
new
ArrayList
<
String
>();
assigneeList
.
add
(
Authentication
.
getAuthenticatedUserId
());
assigneeList
.
addAll
(
CollectionUtils
.
arrayToList
(
assignees
));
String
[]
newAssignees
=
assigneeList
.
toArray
(
new
String
[
0
]);
ProcessDefinitionEntity
processDefinition
=
(
ProcessDefinitionEntity
)
repositoryService
.
getProcessDefinition
(
procDefId
);
ActivityImpl
prototypeActivity
=
ProcessDefUtils
.
getActivity
(
processEngine
,
processDefinition
.
getId
(),
targetTaskDefinitionKey
);
return
cloneAndMakeChain
(
processDefinition
,
procInsId
,
targetTaskDefinitionKey
,
prototypeActivity
.
getOutgoingTransitions
().
get
(
0
).
getDestination
().
getId
(),
variables
,
newAssignees
);
}
/**
* 前加签
*/
public
ActivityImpl
[]
insertTasksBefore
(
String
procDefId
,
String
procInsId
,
String
targetTaskDefinitionKey
,
Map
<
String
,
Object
>
variables
,
String
...
assignees
)
{
ProcessDefinitionEntity
procDef
=
(
ProcessDefinitionEntity
)
repositoryService
.
getProcessDefinition
(
procDefId
);
return
cloneAndMakeChain
(
procDef
,
procInsId
,
targetTaskDefinitionKey
,
targetTaskDefinitionKey
,
variables
,
assignees
);
}
/**
* 分裂某节点为多实例节点
*/
public
ActivityImpl
splitTask
(
String
procDefId
,
String
procInsId
,
String
targetTaskDefinitionKey
,
Map
<
String
,
Object
>
variables
,
String
...
assignee
)
{
return
splitTask
(
procDefId
,
procInsId
,
targetTaskDefinitionKey
,
variables
,
true
,
assignee
);
}
/**
* 分裂某节点为多实例节点
*/
@SuppressWarnings
(
"unchecked"
)
public
ActivityImpl
splitTask
(
String
procDefId
,
String
procInsId
,
String
targetTaskDefinitionKey
,
Map
<
String
,
Object
>
variables
,
boolean
isSequential
,
String
...
assignees
)
{
SimpleRuntimeActivityDefinitionEntity
info
=
new
SimpleRuntimeActivityDefinitionEntity
();
info
.
setProcessDefinitionId
(
procDefId
);
info
.
setProcessInstanceId
(
procInsId
);
RuntimeActivityDefinitionEntityIntepreter
radei
=
new
RuntimeActivityDefinitionEntityIntepreter
(
info
);
radei
.
setPrototypeActivityId
(
targetTaskDefinitionKey
);
radei
.
setAssignees
(
CollectionUtils
.
arrayToList
(
assignees
));
radei
.
setSequential
(
isSequential
);
ProcessDefinitionEntity
processDefinition
=
(
ProcessDefinitionEntity
)
repositoryService
.
getProcessDefinition
(
procDefId
);
ActivityImpl
clone
=
new
MultiInstanceActivityCreator
().
createActivities
(
processEngine
,
processDefinition
,
info
)[
0
];
TaskEntity
currentTaskEntity
=
this
.
getCurrentTask
(
procInsId
);
CommandExecutor
commandExecutor
=
((
RuntimeServiceImpl
)
runtimeService
).
getCommandExecutor
();
commandExecutor
.
execute
(
new
CreateAndTakeTransitionCmd
(
currentTaskEntity
,
clone
,
variables
));
// recordActivitiesCreation(info);
return
clone
;
}
private
TaskEntity
getCurrentTask
(
String
procInsId
)
{
return
(
TaskEntity
)
taskService
.
createTaskQuery
().
processInstanceId
(
procInsId
).
active
().
singleResult
();
}
private
TaskEntity
getTaskEntity
(
String
taskId
)
{
return
(
TaskEntity
)
taskService
.
createTaskQuery
().
taskId
(
taskId
).
singleResult
();
}
@SuppressWarnings
(
"unchecked"
)
private
ActivityImpl
[]
cloneAndMakeChain
(
ProcessDefinitionEntity
procDef
,
String
procInsId
,
String
prototypeActivityId
,
String
nextActivityId
,
Map
<
String
,
Object
>
variables
,
String
...
assignees
)
{
SimpleRuntimeActivityDefinitionEntity
info
=
new
SimpleRuntimeActivityDefinitionEntity
();
info
.
setProcessDefinitionId
(
procDef
.
getId
());
info
.
setProcessInstanceId
(
procInsId
);
RuntimeActivityDefinitionEntityIntepreter
radei
=
new
RuntimeActivityDefinitionEntityIntepreter
(
info
);
radei
.
setPrototypeActivityId
(
prototypeActivityId
);
radei
.
setAssignees
(
CollectionUtils
.
arrayToList
(
assignees
));
radei
.
setNextActivityId
(
nextActivityId
);
ActivityImpl
[]
activities
=
new
ChainedActivitiesCreator
().
createActivities
(
processEngine
,
procDef
,
info
);
jumpTask
(
procInsId
,
activities
[
0
].
getId
(),
variables
);
// recordActivitiesCreation(info);
return
activities
;
}
// private void recordActivitiesCreation(SimpleRuntimeActivityDefinitionEntity info) {
// info.serializeProperties();
// _activitiesCreationStore.save(info);
// }
////////////////////////////////////////////////////////////////////
// private void recordActivitiesCreation(SimpleRuntimeActivityDefinitionEntity info) throws Exception {
// info.serializeProperties();
// _activitiesCreationStore.save(info);
// }
//
// /**
// * 分裂某节点为多实例节点
// *
// * @param targetTaskDefinitionKey
// * @param assignee
// * @throws IOException
// * @throws IllegalAccessException
// * @throws IllegalArgumentException
// */
// public ActivityImpl split(String targetTaskDefinitionKey, boolean isSequential, String... assignees) throws Exception {
// SimpleRuntimeActivityDefinitionEntity info = new SimpleRuntimeActivityDefinitionEntity();
// info.setProcessDefinitionId(processDefinition.getId());
// info.setProcessInstanceId(_processInstanceId);
//
// RuntimeActivityDefinitionEntityIntepreter radei = new RuntimeActivityDefinitionEntityIntepreter(info);
//
// radei.setPrototypeActivityId(targetTaskDefinitionKey);
// radei.setAssignees(CollectionUtils.arrayToList(assignees));
// radei.setSequential(isSequential);
//
// ActivityImpl clone = new MultiInstanceActivityCreator().createActivities(_processEngine, processDefinition, info)[0];
//
// TaskEntity currentTaskEntity = getCurrentTask();
// executeCommand(new CreateAndTakeTransitionCmd(currentTaskEntity.getExecutionId(), clone));
// executeCommand(new DeleteRunningTaskCmd(currentTaskEntity));
//
// recordActivitiesCreation(info);
// return clone;
// }
//
// public ActivityImpl split(String targetTaskDefinitionKey, String... assignee) throws Exception {
// return split(targetTaskDefinitionKey, true, assignee);
// }
////////////////////////////////////////////////////////////////////
/**
* 读取带跟踪的图片
* @param executionId 环节ID
* @return 封装了各种节点信息
*/
public
InputStream
tracePhoto
(
String
processDefinitionId
,
String
executionId
)
{
// ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(executionId).singleResult();
BpmnModel
bpmnModel
=
repositoryService
.
getBpmnModel
(
processDefinitionId
);
List
<
String
>
activeActivityIds
=
Lists
.
newArrayList
();
if
(
runtimeService
.
createExecutionQuery
().
executionId
(
executionId
).
count
()
>
0
){
activeActivityIds
=
runtimeService
.
getActiveActivityIds
(
executionId
);
}
// 不使用spring请使用下面的两行代码
// ProcessEngineImpl defaultProcessEngine = (ProcessEngineImpl)ProcessEngines.getDefaultProcessEngine();
// Context.setProcessEngineConfiguration(defaultProcessEngine.getProcessEngineConfiguration());
// 使用spring注入引擎请使用下面的这行代码
Context
.
setProcessEngineConfiguration
(
processEngineFactory
.
getProcessEngineConfiguration
());
// return ProcessDiagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds);
return
processEngine
.
getProcessEngineConfiguration
().
getProcessDiagramGenerator
()
.
generateDiagram
(
bpmnModel
,
"png"
,
activeActivityIds
);
}
/**
* 流程跟踪图信息
* @param processInstanceId 流程实例ID
* @return 封装了各种节点信息
*/
public
List
<
Map
<
String
,
Object
>>
traceProcess
(
String
processInstanceId
)
throws
Exception
{
Execution
execution
=
runtimeService
.
createExecutionQuery
().
executionId
(
processInstanceId
).
singleResult
();
//执行实例
Object
property
=
PropertyUtils
.
getProperty
(
execution
,
"activityId"
);
String
activityId
=
""
;
if
(
property
!=
null
)
{
activityId
=
property
.
toString
();
}
ProcessInstance
processInstance
=
runtimeService
.
createProcessInstanceQuery
().
processInstanceId
(
processInstanceId
)
.
singleResult
();
ProcessDefinitionEntity
processDefinition
=
(
ProcessDefinitionEntity
)
((
RepositoryServiceImpl
)
repositoryService
)
.
getDeployedProcessDefinition
(
processInstance
.
getProcessDefinitionId
());
List
<
ActivityImpl
>
activitiList
=
processDefinition
.
getActivities
();
//获得当前任务的所有节点
List
<
Map
<
String
,
Object
>>
activityInfos
=
new
ArrayList
<
Map
<
String
,
Object
>>();
for
(
ActivityImpl
activity
:
activitiList
)
{
boolean
currentActiviti
=
false
;
String
id
=
activity
.
getId
();
// 当前节点
if
(
id
.
equals
(
activityId
))
{
currentActiviti
=
true
;
}
Map
<
String
,
Object
>
activityImageInfo
=
packageSingleActivitiInfo
(
activity
,
processInstance
,
currentActiviti
);
activityInfos
.
add
(
activityImageInfo
);
}
return
activityInfos
;
}
/**
* 封装输出信息,包括:当前节点的X、Y坐标、变量信息、任务类型、任务描述
* @param activity
* @param processInstance
* @param currentActiviti
* @return
*/
private
Map
<
String
,
Object
>
packageSingleActivitiInfo
(
ActivityImpl
activity
,
ProcessInstance
processInstance
,
boolean
currentActiviti
)
throws
Exception
{
Map
<
String
,
Object
>
vars
=
new
HashMap
<
String
,
Object
>();
Map
<
String
,
Object
>
activityInfo
=
new
HashMap
<
String
,
Object
>();
activityInfo
.
put
(
"currentActiviti"
,
currentActiviti
);
setPosition
(
activity
,
activityInfo
);
setWidthAndHeight
(
activity
,
activityInfo
);
Map
<
String
,
Object
>
properties
=
activity
.
getProperties
();
vars
.
put
(
"节点名称"
,
properties
.
get
(
"name"
));
vars
.
put
(
"任务类型"
,
ActUtils
.
parseToZhType
(
properties
.
get
(
"type"
).
toString
()));
ActivityBehavior
activityBehavior
=
activity
.
getActivityBehavior
();
logger
.
debug
(
"activityBehavior={}"
,
activityBehavior
);
if
(
activityBehavior
instanceof
UserTaskActivityBehavior
)
{
Task
currentTask
=
null
;
// 当前节点的task
if
(
currentActiviti
)
{
currentTask
=
getCurrentTaskInfo
(
processInstance
);
}
// 当前任务的分配角色
UserTaskActivityBehavior
userTaskActivityBehavior
=
(
UserTaskActivityBehavior
)
activityBehavior
;
TaskDefinition
taskDefinition
=
userTaskActivityBehavior
.
getTaskDefinition
();
Set
<
Expression
>
candidateGroupIdExpressions
=
taskDefinition
.
getCandidateGroupIdExpressions
();
if
(!
candidateGroupIdExpressions
.
isEmpty
())
{
// 任务的处理角色
setTaskGroup
(
vars
,
candidateGroupIdExpressions
);
// 当前处理人
if
(
currentTask
!=
null
)
{
setCurrentTaskAssignee
(
vars
,
currentTask
);
}
}
}
vars
.
put
(
"节点说明"
,
properties
.
get
(
"documentation"
));
String
description
=
activity
.
getProcessDefinition
().
getDescription
();
vars
.
put
(
"描述"
,
description
);
logger
.
debug
(
"trace variables: {}"
,
vars
);
activityInfo
.
put
(
"vars"
,
vars
);
return
activityInfo
;
}
/**
* 设置任务组
* @param vars
* @param candidateGroupIdExpressions
*/
private
void
setTaskGroup
(
Map
<
String
,
Object
>
vars
,
Set
<
Expression
>
candidateGroupIdExpressions
)
{
String
roles
=
""
;
for
(
Expression
expression
:
candidateGroupIdExpressions
)
{
String
expressionText
=
expression
.
getExpressionText
();
String
roleName
=
identityService
.
createGroupQuery
().
groupId
(
expressionText
).
singleResult
().
getName
();
roles
+=
roleName
;
}
vars
.
put
(
"任务所属角色"
,
roles
);
}
/**
* 设置当前处理人信息
* @param vars
* @param currentTask
*/
private
void
setCurrentTaskAssignee
(
Map
<
String
,
Object
>
vars
,
Task
currentTask
)
{
String
assignee
=
currentTask
.
getAssignee
();
if
(
assignee
!=
null
)
{
org
.
activiti
.
engine
.
identity
.
User
assigneeUser
=
identityService
.
createUserQuery
().
userId
(
assignee
).
singleResult
();
String
userInfo
=
assigneeUser
.
getFirstName
()
+
" "
+
assigneeUser
.
getLastName
();
vars
.
put
(
"当前处理人"
,
userInfo
);
}
}
/**
* 获取当前节点信息
* @param processInstance
* @return
*/
private
Task
getCurrentTaskInfo
(
ProcessInstance
processInstance
)
{
Task
currentTask
=
null
;
try
{
String
activitiId
=
(
String
)
PropertyUtils
.
getProperty
(
processInstance
,
"activityId"
);
logger
.
debug
(
"current activity id: {}"
,
activitiId
);
currentTask
=
taskService
.
createTaskQuery
().
processInstanceId
(
processInstance
.
getId
()).
taskDefinitionKey
(
activitiId
)
.
singleResult
();
logger
.
debug
(
"current task for processInstance: {}"
,
ToStringBuilder
.
reflectionToString
(
currentTask
));
}
catch
(
Exception
e
)
{
logger
.
error
(
"can not get property activityId from processInstance: {}"
,
processInstance
);
}
return
currentTask
;
}
/**
* 设置宽度、高度属性
* @param activity
* @param activityInfo
*/
private
void
setWidthAndHeight
(
ActivityImpl
activity
,
Map
<
String
,
Object
>
activityInfo
)
{
activityInfo
.
put
(
"width"
,
activity
.
getWidth
());
activityInfo
.
put
(
"height"
,
activity
.
getHeight
());
}
/**
* 设置坐标位置
* @param activity
* @param activityInfo
*/
private
void
setPosition
(
ActivityImpl
activity
,
Map
<
String
,
Object
>
activityInfo
)
{
activityInfo
.
put
(
"x"
,
activity
.
getX
());
activityInfo
.
put
(
"y"
,
activity
.
getY
());
}
public
ProcessEngine
getProcessEngine
()
{
return
processEngine
;
}
}
JeeSpringCloud/src/main/java/com/jeespring/modules/act/service/cmd/CreateAndTakeTransitionCmd.java
0 → 100644
View file @
20e6484f
package
com.jeespring.modules.act.service.cmd
;
import
java.util.Map
;
import
org.activiti.engine.impl.context.Context
;
import
org.activiti.engine.impl.interceptor.Command
;
import
org.activiti.engine.impl.interceptor.CommandContext
;
import
org.activiti.engine.impl.persistence.entity.ExecutionEntity
;
import
org.activiti.engine.impl.persistence.entity.TaskEntity
;
import
org.activiti.engine.impl.pvm.process.ActivityImpl
;
import
org.activiti.engine.impl.pvm.runtime.AtomicOperation
;
public
class
CreateAndTakeTransitionCmd
implements
Command
<
Void
>
{
private
TaskEntity
currentTaskEntity
;
private
ActivityImpl
activity
;
protected
Map
<
String
,
Object
>
variables
;
public
CreateAndTakeTransitionCmd
(
TaskEntity
currentTaskEntity
,
ActivityImpl
activity
,
Map
<
String
,
Object
>
variables
)
{
this
.
currentTaskEntity
=
currentTaskEntity
;
this
.
activity
=
activity
;
this
.
variables
=
variables
;
}
@Override
public
Void
execute
(
CommandContext
commandContext
)
{
if
(
currentTaskEntity
!=
null
)
{
ExecutionEntity
execution
=
commandContext
.
getExecutionEntityManager
().
findExecutionById
(
currentTaskEntity
.
getExecutionId
());
execution
.
setActivity
(
activity
);
execution
.
performOperation
(
AtomicOperation
.
TRANSITION_CREATE_SCOPE
);
if
(
variables
!=
null
)
{
if
(
currentTaskEntity
.
getExecutionId
()
!=
null
)
{
currentTaskEntity
.
setExecutionVariables
(
variables
);
}
else
{
currentTaskEntity
.
setVariables
(
variables
);
}
}
//删除当前的任务,不能删除当前正在执行的任务,所以要先清除掉关联
Context
.
getCommandContext
().
getTaskEntityManager
().
deleteTask
(
currentTaskEntity
,
TaskEntity
.
DELETE_REASON_DELETED
,
false
);
}
return
null
;
}
}
\ No newline at end of file
JeeSpringCloud/src/main/java/com/jeespring/modules/act/service/cmd/JumpTaskCmd.java
0 → 100644
View file @
20e6484f
package
com.jeespring.modules.act.service.cmd
;
import
java.util.Map
;
import
org.activiti.engine.impl.context.Context
;
import
org.activiti.engine.impl.interceptor.Command
;
import
org.activiti.engine.impl.interceptor.CommandContext
;
import
org.activiti.engine.impl.persistence.entity.ExecutionEntity
;
import
org.activiti.engine.impl.persistence.entity.TaskEntity
;
import
org.activiti.engine.impl.pvm.process.ActivityImpl
;
import
org.activiti.engine.impl.pvm.runtime.AtomicOperation
;
public
class
JumpTaskCmd
implements
Command
<
Void
>
{
private
TaskEntity
taskEntity
;
private
ActivityImpl
targetActivity
;
protected
Map
<
String
,
Object
>
variables
;
public
JumpTaskCmd
(
TaskEntity
taskEntity
,
ActivityImpl
targetActivity
,
Map
<
String
,
Object
>
variables
)
{
this
.
taskEntity
=
taskEntity
;
this
.
targetActivity
=
targetActivity
;
this
.
variables
=
variables
;
}
@Override
public
Void
execute
(
CommandContext
commandContext
)
{
if
(
taskEntity
!=
null
)
{
//删除当前的任务,不能删除当前正在执行的任务,所以要先清除掉关联
if
(
variables
!=
null
)
{
if
(
taskEntity
.
getExecutionId
()
!=
null
)
{
taskEntity
.
setExecutionVariables
(
variables
);
}
else
{
taskEntity
.
setVariables
(
variables
);
}
}
// // 完成活动历史
// Context.getCommandContext().getHistoryManager()
// .recordActivityEnd((ExecutionEntity) taskEntity.getExecution());
// 完成待办任务
Context
.
getCommandContext
().
getTaskEntityManager
().
deleteTask
(
taskEntity
,
TaskEntity
.
DELETE_REASON_COMPLETED
,
false
);
// DELETE_REASON_DELETED DELETE_REASON_COMPLETED
// 跳转任务
ExecutionEntity
execution
=
taskEntity
.
getExecution
();
execution
.
setActivity
(
targetActivity
);
execution
.
performOperation
(
AtomicOperation
.
ACTIVITY_START
);
}
return
null
;
}
}
\ No newline at end of file
JeeSpringCloud/src/main/java/com/jeespring/modules/act/service/cmd/ModelDeployProcessDefinitionCmd.java
0 → 100644
View file @
20e6484f
package
com.jeespring.modules.act.service.cmd
;
import
java.io.ByteArrayInputStream
;
import
org.activiti.bpmn.converter.BpmnXMLConverter
;
import
org.activiti.bpmn.model.BpmnModel
;
import
org.activiti.editor.language.json.converter.BpmnJsonConverter
;
import
org.activiti.engine.ActivitiException
;
import
org.activiti.engine.RepositoryService
;
import
org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl
;
import
org.activiti.engine.impl.context.Context
;
import
org.activiti.engine.impl.db.DbSqlSession
;
import
org.activiti.engine.impl.interceptor.Command
;
import
org.activiti.engine.impl.interceptor.CommandContext
;
import
org.activiti.engine.impl.persistence.entity.DeploymentEntity
;
import
org.activiti.engine.impl.persistence.entity.ResourceEntity
;
import
org.activiti.engine.impl.persistence.entity.ResourceEntityManager
;
import
org.activiti.engine.impl.util.IoUtil
;
import
org.activiti.engine.repository.ProcessDefinition
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
/**
* 模型部署或更新到流程定义
* @author ThinkGem
* @version 2016年8月2日
*/
public
class
ModelDeployProcessDefinitionCmd
implements
Command
<
Void
>
{
private
String
modelId
;
private
String
procDefKey
;
private
String
procDefName
;
public
ModelDeployProcessDefinitionCmd
(
String
modelId
,
String
procDefKey
,
String
procDefName
)
{
this
.
modelId
=
modelId
;
this
.
procDefKey
=
procDefKey
;
this
.
procDefName
=
procDefName
;
}
@Override
public
Void
execute
(
CommandContext
commandContext
)
{
RepositoryService
repositoryService
=
Context
.
getProcessEngineConfiguration
()
.
getRepositoryService
();
try
{
// 生成部署名称和数据 ThinkGem
JsonNode
editorNode
=
new
ObjectMapper
().
readTree
(
repositoryService
.
getModelEditorSource
(
modelId
));
BpmnModel
bpmnModel
=
new
BpmnJsonConverter
().
convertToBpmnModel
(
editorNode
);
byte
[]
bpmnBytes
=
new
BpmnXMLConverter
().
convertToXML
(
bpmnModel
);
// 查询流程定义是否已经存在了 ThinkGem
ProcessDefinition
processDefinition
=
Context
.
getProcessEngineConfiguration
()
.
getRepositoryService
().
createProcessDefinitionQuery
()
.
processDefinitionKey
(
procDefKey
).
latestVersion
().
singleResult
();
if
(
processDefinition
!=
null
){
ResourceEntityManager
resourceEntityManager
=
commandContext
.
getResourceEntityManager
();
DeploymentEntity
deployment
=
(
DeploymentEntity
)
repositoryService
.
createDeploymentQuery
()
.
deploymentId
(
processDefinition
.
getDeploymentId
()).
singleResult
();
// 删除原资源
resourceEntityManager
.
deleteResourcesByDeploymentId
(
deployment
.
getId
());
Context
.
getCommandContext
().
getSession
(
DbSqlSession
.
class
).
flush
();
// 插入新资源
ResourceEntity
resource
=
new
ResourceEntity
();
resource
.
setDeploymentId
(
deployment
.
getId
());
resource
.
setName
(
procDefName
+
".bpmn20.xml"
);
resource
.
setBytes
(
bpmnBytes
);
deployment
.
addResource
(
resource
);
resourceEntityManager
.
insertResource
(
resource
);
// 插入资源图片
ProcessEngineConfigurationImpl
processEngineConfiguration
=
Context
.
getProcessEngineConfiguration
();
byte
[]
diagramBytes
=
IoUtil
.
readInputStream
(
processEngineConfiguration
.
getProcessDiagramGenerator
().
generateDiagram
(
bpmnModel
,
"png"
,
processEngineConfiguration
.
getActivityFontName
(),
processEngineConfiguration
.
getLabelFontName
(),
processEngineConfiguration
.
getAnnotationFontName
(),
processEngineConfiguration
.
getClassLoader
()),
null
);
ResourceEntity
diagramResource
=
new
ResourceEntity
();
diagramResource
.
setDeploymentId
(
deployment
.
getId
());
diagramResource
.
setName
(
procDefName
+
"."
+
processDefinition
.
getKey
()
+
".png"
);
diagramResource
.
setBytes
(
diagramBytes
);
deployment
.
addResource
(
diagramResource
);
resourceEntityManager
.
insertResource
(
diagramResource
);
}
// 不存在部署一个新的流程 ThinkGem
else
{
repositoryService
.
createDeployment
().
name
(
procDefName
).
addInputStream
(
procDefName
+
".bpmn20.xml"
,
new
ByteArrayInputStream
(
bpmnBytes
)).
deploy
();
}
}
catch
(
Exception
e
){
throw
new
ActivitiException
(
"模型部署到流程定义错误"
,
e
);
}
return
null
;
}
}
\ No newline at end of file
JeeSpringCloud/src/main/java/com/jeespring/modules/act/service/creator/ChainedActivitiesCreator.java
0 → 100644
View file @
20e6484f
package
com.jeespring.modules.act.service.creator
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.activiti.engine.ProcessEngine
;
import
org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity
;
import
org.activiti.engine.impl.pvm.process.ActivityImpl
;
import
org.springframework.util.CollectionUtils
;
import
com.jeespring.modules.act.utils.ProcessDefUtils
;
public
class
ChainedActivitiesCreator
extends
RuntimeActivityCreatorSupport
implements
RuntimeActivityCreator
{
@SuppressWarnings
(
"unchecked"
)
public
ActivityImpl
[]
createActivities
(
ProcessEngine
processEngine
,
ProcessDefinitionEntity
processDefinition
,
RuntimeActivityDefinitionEntity
info
)
{
info
.
setFactoryName
(
ChainedActivitiesCreator
.
class
.
getName
());
RuntimeActivityDefinitionEntityIntepreter
radei
=
new
RuntimeActivityDefinitionEntityIntepreter
(
info
);
if
(
radei
.
getCloneActivityIds
()
==
null
)
{
radei
.
setCloneActivityIds
(
CollectionUtils
.
arrayToList
(
new
String
[
radei
.
getAssignees
().
size
()]));
}
return
createActivities
(
processEngine
,
processDefinition
,
info
.
getProcessInstanceId
(),
radei
.
getPrototypeActivityId
(),
radei
.
getNextActivityId
(),
radei
.
getAssignees
(),
radei
.
getCloneActivityIds
());
}
private
ActivityImpl
[]
createActivities
(
ProcessEngine
processEngine
,
ProcessDefinitionEntity
processDefinition
,
String
processInstanceId
,
String
prototypeActivityId
,
String
nextActivityId
,
List
<
String
>
assignees
,
List
<
String
>
activityIds
)
{
ActivityImpl
prototypeActivity
=
ProcessDefUtils
.
getActivity
(
processEngine
,
processDefinition
.
getId
(),
prototypeActivityId
);
List
<
ActivityImpl
>
activities
=
new
ArrayList
<
ActivityImpl
>();
for
(
int
i
=
0
;
i
<
assignees
.
size
();
i
++)
{
if
(
activityIds
.
get
(
i
)
==
null
)
{
String
activityId
=
createUniqueActivityId
(
processInstanceId
,
prototypeActivityId
);
activityIds
.
set
(
i
,
activityId
);
}
ActivityImpl
clone
=
createActivity
(
processEngine
,
processDefinition
,
prototypeActivity
,
activityIds
.
get
(
i
),
assignees
.
get
(
i
));
activities
.
add
(
clone
);
}
ActivityImpl
nextActivity
=
ProcessDefUtils
.
getActivity
(
processEngine
,
processDefinition
.
getId
(),
nextActivityId
);
createActivityChain
(
activities
,
nextActivity
);
return
activities
.
toArray
(
new
ActivityImpl
[
0
]);
}
}
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment