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
"deploy/git@ustchcs.com:gujinli1118/litemall.git" did not exist on "aa0887466690ccc088cf9f894034ff9d7fee990a"
Commit
20e6484f
authored
Oct 12, 2018
by
HuangBingGui
Browse files
no commit message
parent
22579f13
Changes
37
Hide 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