first commit
This commit is contained in:
11
src/main/java/com/sipai/activiti/Test.java
Normal file
11
src/main/java/com/sipai/activiti/Test.java
Normal file
@ -0,0 +1,11 @@
|
||||
package com.sipai.activiti;
|
||||
|
||||
import com.sipai.tools.CommUtil;
|
||||
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
int a = 3;
|
||||
int b = 3;
|
||||
System.out.println(a % b);
|
||||
}
|
||||
}
|
||||
39
src/main/java/com/sipai/activiti/cmd/JumpActivityCmd.java
Normal file
39
src/main/java/com/sipai/activiti/cmd/JumpActivityCmd.java
Normal file
@ -0,0 +1,39 @@
|
||||
package com.sipai.activiti.cmd;
|
||||
|
||||
/**
|
||||
* @author: Henry Yan
|
||||
*/
|
||||
|
||||
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.pvm.process.ActivityImpl;
|
||||
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
|
||||
|
||||
public class JumpActivityCmd implements Command<Object> {
|
||||
private String activityId;
|
||||
private String processInstanceId;
|
||||
private String jumpOrigin;
|
||||
|
||||
public JumpActivityCmd(String processInstanceId, String activityId) {
|
||||
this(processInstanceId, activityId, "jump");
|
||||
}
|
||||
|
||||
public JumpActivityCmd(String processInstanceId, String activityId, String jumpOrigin) {
|
||||
this.activityId = activityId;
|
||||
this.processInstanceId = processInstanceId;
|
||||
this.jumpOrigin = jumpOrigin;
|
||||
}
|
||||
|
||||
public Object execute(CommandContext commandContext) {
|
||||
|
||||
ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findExecutionById(processInstanceId);
|
||||
|
||||
executionEntity.destroyScope(jumpOrigin);
|
||||
|
||||
ProcessDefinitionImpl processDefinition = executionEntity.getProcessDefinition();
|
||||
ActivityImpl activity = processDefinition.findActivity(activityId);
|
||||
executionEntity.executeActivity(activity);
|
||||
return executionEntity;
|
||||
}
|
||||
}
|
||||
32
src/main/java/com/sipai/activiti/form/UsersFormType.java
Normal file
32
src/main/java/com/sipai/activiti/form/UsersFormType.java
Normal file
@ -0,0 +1,32 @@
|
||||
package com.sipai.activiti.form;
|
||||
|
||||
import org.activiti.engine.form.AbstractFormType;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 用户表单字段类型
|
||||
*
|
||||
* @author henryyan
|
||||
*/
|
||||
public class UsersFormType extends AbstractFormType {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "users";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertFormValueToModelValue(String propertyValue) {
|
||||
String[] split = StringUtils.split(propertyValue, ",");
|
||||
return Arrays.asList(split);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertModelValueToFormValue(Object modelValue) {
|
||||
return ObjectUtils.toString(modelValue);
|
||||
}
|
||||
|
||||
}
|
||||
95
src/main/java/com/sipai/activiti/util/DateConverter.java
Normal file
95
src/main/java/com/sipai/activiti/util/DateConverter.java
Normal file
@ -0,0 +1,95 @@
|
||||
package com.sipai.activiti.util;
|
||||
|
||||
import org.apache.commons.beanutils.Converter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateConverter implements Converter {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DateConverter.class);
|
||||
|
||||
private static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
private static final String DATETIME_PATTERN_NO_SECOND = "yyyy-MM-dd HH:mm";
|
||||
|
||||
private static final String DATE_PATTERN = "yyyy-MM-dd";
|
||||
|
||||
private static final String MONTH_PATTERN = "yyyy-MM";
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object convert(Class type, Object value) {
|
||||
Object result = null;
|
||||
if (type == Date.class) {
|
||||
try {
|
||||
result = doConvertToDate(value);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (type == String.class) {
|
||||
result = doConvertToString(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert String to Date
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
* @throws ParseException
|
||||
*/
|
||||
private Date doConvertToDate(Object value) throws ParseException {
|
||||
Date result = null;
|
||||
|
||||
if (value instanceof String) {
|
||||
result = DateUtils.parseDate((String) value, new String[]{DATE_PATTERN, DATETIME_PATTERN,
|
||||
DATETIME_PATTERN_NO_SECOND, MONTH_PATTERN});
|
||||
|
||||
// all patterns failed, try a milliseconds constructor
|
||||
if (result == null && StringUtils.isNotEmpty((String) value)) {
|
||||
|
||||
try {
|
||||
result = new Date(new Long((String) value).longValue());
|
||||
} catch (Exception e) {
|
||||
logger.error("Converting from milliseconds to Date fails!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if (value instanceof Object[]) {
|
||||
// let's try to convert the first element only
|
||||
Object[] array = (Object[]) value;
|
||||
|
||||
if (array.length >= 1) {
|
||||
value = array[0];
|
||||
result = doConvertToDate(value);
|
||||
}
|
||||
|
||||
} else if (Date.class.isAssignableFrom(value.getClass())) {
|
||||
result = (Date) value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Date to String
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private String doConvertToString(Object value) {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATETIME_PATTERN);
|
||||
String result = null;
|
||||
if (value instanceof Date) {
|
||||
result = simpleDateFormat.format(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
93
src/main/java/com/sipai/activiti/util/LinkedProperties.java
Normal file
93
src/main/java/com/sipai/activiti/util/LinkedProperties.java
Normal file
@ -0,0 +1,93 @@
|
||||
package com.sipai.activiti.util;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 有序Properties
|
||||
*/
|
||||
public class LinkedProperties extends Properties {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Map<Object, Object> linkMap = new LinkedHashMap<Object, Object>();
|
||||
|
||||
public void clear() {
|
||||
linkMap.clear();
|
||||
}
|
||||
|
||||
public boolean contains(Object value) {
|
||||
return linkMap.containsValue(value);
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return linkMap.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
return linkMap.containsValue(value);
|
||||
}
|
||||
|
||||
public Enumeration elements() {
|
||||
throw new RuntimeException("Method elements is not supported in LinkedProperties class");
|
||||
}
|
||||
|
||||
public Set entrySet() {
|
||||
return linkMap.entrySet();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return linkMap.equals(o);
|
||||
}
|
||||
|
||||
public Object get(Object key) {
|
||||
return linkMap.get(key);
|
||||
}
|
||||
|
||||
public String getProperty(String key) {
|
||||
Object oval = get(key); //here the class Properties uses super.get()
|
||||
if (oval == null) return null;
|
||||
return (oval instanceof String) ? (String) oval : null; //behavior of standard properties
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return linkMap.isEmpty();
|
||||
}
|
||||
|
||||
public Enumeration keys() {
|
||||
Set keys = linkMap.keySet();
|
||||
return Collections.enumeration(keys);
|
||||
}
|
||||
|
||||
public Set keySet() {
|
||||
return linkMap.keySet();
|
||||
}
|
||||
|
||||
public void list(PrintStream out) {
|
||||
this.list(new PrintWriter(out, true));
|
||||
}
|
||||
|
||||
public void list(PrintWriter out) {
|
||||
out.println("-- listing properties --");
|
||||
for (Map.Entry e : (Set<Map.Entry>) this.entrySet()) {
|
||||
String key = (String) e.getKey();
|
||||
String val = (String) e.getValue();
|
||||
if (val.length() > 40) {
|
||||
val = val.substring(0, 37) + "...";
|
||||
}
|
||||
out.println(key + "=" + val);
|
||||
}
|
||||
}
|
||||
|
||||
public Object put(Object key, Object value) {
|
||||
return linkMap.put(key, value);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return linkMap.size();
|
||||
}
|
||||
|
||||
public Collection values() {
|
||||
return linkMap.values();
|
||||
}
|
||||
|
||||
}
|
||||
258
src/main/java/com/sipai/activiti/util/Page.java
Normal file
258
src/main/java/com/sipai/activiti/util/Page.java
Normal file
@ -0,0 +1,258 @@
|
||||
package com.sipai.activiti.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author HenryYan
|
||||
*/
|
||||
public class Page<T> {
|
||||
|
||||
// -- 公共变量 --//
|
||||
public static final String ASC = "asc";
|
||||
public static final String DESC = "desc";
|
||||
|
||||
// -- 分页参数 --//
|
||||
protected int pageNo = 1;
|
||||
protected int pageSize = -1;
|
||||
protected String orderBy = null;
|
||||
protected String order = null;
|
||||
protected boolean autoCount = true;
|
||||
|
||||
// -- 返回结果 --//
|
||||
protected List<T> result = Lists.newArrayList();
|
||||
protected long totalCount = -1;
|
||||
|
||||
// -- 构造函数 --//
|
||||
public Page() {
|
||||
}
|
||||
|
||||
public Page(int pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
// -- 分页参数访问函数 --//
|
||||
|
||||
/**
|
||||
* 获得当前页的页号,序号从1开始,默认为1.
|
||||
*/
|
||||
public int getPageNo() {
|
||||
return pageNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前页的页号,序号从1开始,低于1时自动调整为1.
|
||||
*/
|
||||
public void setPageNo(final int pageNo) {
|
||||
this.pageNo = pageNo;
|
||||
|
||||
if (pageNo < 1) {
|
||||
this.pageNo = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回Page对象自身的setPageNo函数,可用于连续设置。
|
||||
*/
|
||||
public Page<T> pageNo(final int thePageNo) {
|
||||
setPageNo(thePageNo);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得每页的记录数量, 默认为-1.
|
||||
*/
|
||||
public int getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置每页的记录数量.
|
||||
*/
|
||||
public void setPageSize(final int pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回Page对象自身的setPageSize函数,可用于连续设置。
|
||||
*/
|
||||
public Page<T> pageSize(final int thePageSize) {
|
||||
setPageSize(thePageSize);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据pageNo和pageSize计算当前页第一条记录在总结果集中的位置,序号从1开始.
|
||||
*/
|
||||
public int getFirst() {
|
||||
return ((pageNo - 1) * pageSize) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得排序字段,无默认值. 多个排序字段时用','分隔.
|
||||
*/
|
||||
public String getOrderBy() {
|
||||
return orderBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置排序字段,多个排序字段时用','分隔.
|
||||
*/
|
||||
public void setOrderBy(final String orderBy) {
|
||||
this.orderBy = orderBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回Page对象自身的setOrderBy函数,可用于连续设置。
|
||||
*/
|
||||
public Page<T> orderBy(final String theOrderBy) {
|
||||
setOrderBy(theOrderBy);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得排序方向, 无默认值.
|
||||
*/
|
||||
public String getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置排序方式向.
|
||||
*
|
||||
* @param order 可选值为desc或asc,多个排序字段时用','分隔.
|
||||
*/
|
||||
public void setOrder(final String order) {
|
||||
String lowcaseOrder = StringUtils.lowerCase(order);
|
||||
|
||||
// 检查order字符串的合法值
|
||||
String[] orders = StringUtils.split(lowcaseOrder, ',');
|
||||
for (String orderStr : orders) {
|
||||
if (!StringUtils.equals(DESC, orderStr) && !StringUtils.equals(ASC, orderStr)) {
|
||||
throw new IllegalArgumentException("排序方向" + orderStr + "不是合法值");
|
||||
}
|
||||
}
|
||||
|
||||
this.order = lowcaseOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回Page对象自身的setOrder函数,可用于连续设置。
|
||||
*/
|
||||
public Page<T> order(final String theOrder) {
|
||||
setOrder(theOrder);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否已设置排序字段,无默认值.
|
||||
*/
|
||||
public boolean isOrderBySetted() {
|
||||
return (StringUtils.isNotBlank(orderBy) && StringUtils.isNotBlank(order));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得查询对象时是否先自动执行count查询获取总记录数, 默认为false.
|
||||
*/
|
||||
public boolean isAutoCount() {
|
||||
return autoCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置查询对象时是否自动先执行count查询获取总记录数.
|
||||
*/
|
||||
public void setAutoCount(final boolean autoCount) {
|
||||
this.autoCount = autoCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回Page对象自身的setAutoCount函数,可用于连续设置。
|
||||
*/
|
||||
public Page<T> autoCount(final boolean theAutoCount) {
|
||||
setAutoCount(theAutoCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
// -- 访问查询结果函数 --//
|
||||
|
||||
/**
|
||||
* 获得页内的记录列表.
|
||||
*/
|
||||
public List<T> getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置页内的记录列表.
|
||||
*/
|
||||
public void setResult(final List<T> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得总记录数, 默认值为-1.
|
||||
*/
|
||||
public long getTotalCount() {
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置总记录数.
|
||||
*/
|
||||
public void setTotalCount(final long totalCount) {
|
||||
this.totalCount = totalCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据pageSize与totalCount计算总页数, 默认值为-1.
|
||||
*/
|
||||
public long getTotalPages() {
|
||||
if (totalCount < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
long count = totalCount / pageSize;
|
||||
if (totalCount % pageSize > 0) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否还有下一页.
|
||||
*/
|
||||
public boolean isHasNext() {
|
||||
return (pageNo + 1 <= getTotalPages());
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得下页的页号, 序号从1开始. 当前页为尾页时仍返回尾页序号.
|
||||
*/
|
||||
public int getNextPage() {
|
||||
if (isHasNext()) {
|
||||
return pageNo + 1;
|
||||
} else {
|
||||
return pageNo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否还有上一页.
|
||||
*/
|
||||
public boolean isHasPre() {
|
||||
return (pageNo - 1 >= 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得上页的页号, 序号从1开始. 当前页为首页时返回首页序号.
|
||||
*/
|
||||
public int getPrePage() {
|
||||
if (isHasPre()) {
|
||||
return pageNo - 1;
|
||||
} else {
|
||||
return pageNo;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/main/java/com/sipai/activiti/util/PageUtil.java
Normal file
26
src/main/java/com/sipai/activiti/util/PageUtil.java
Normal file
@ -0,0 +1,26 @@
|
||||
package com.sipai.activiti.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 分页工具
|
||||
*
|
||||
* @author henryyan
|
||||
*/
|
||||
public class PageUtil {
|
||||
|
||||
public static int PAGE_SIZE = 50;
|
||||
|
||||
public static int[] init(Page<?> page, HttpServletRequest request) {
|
||||
int pageNumber = Integer.parseInt(StringUtils.defaultIfBlank(request.getParameter("p"), "1"));
|
||||
page.setPageNo(pageNumber);
|
||||
int pageSize = Integer.parseInt(StringUtils.defaultIfBlank(request.getParameter("ps"), String.valueOf(PAGE_SIZE)));
|
||||
page.setPageSize(pageSize);
|
||||
int firstResult = page.getFirst() - 1;
|
||||
int maxResults = page.getPageSize();
|
||||
return new int[]{firstResult, maxResults};
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
package com.sipai.activiti.util;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.impl.RepositoryServiceImpl;
|
||||
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
|
||||
import org.activiti.engine.impl.pvm.process.ActivityImpl;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 流程定义缓存
|
||||
*
|
||||
* @author henryyan
|
||||
*/
|
||||
public class ProcessDefinitionCache {
|
||||
|
||||
private static Map<String, ProcessDefinition> map = Maps.newHashMap();
|
||||
|
||||
private static Map<String, List<ActivityImpl>> activities = Maps.newHashMap();
|
||||
|
||||
private static Map<String, ActivityImpl> singleActivity = Maps.newHashMap();
|
||||
|
||||
private static RepositoryService repositoryService;
|
||||
|
||||
public static ProcessDefinition get(String processDefinitionId) {
|
||||
ProcessDefinition processDefinition = map.get(processDefinitionId);
|
||||
if (processDefinition == null) {
|
||||
processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
|
||||
if (processDefinition != null) {
|
||||
put(processDefinitionId, processDefinition);
|
||||
}
|
||||
}
|
||||
return processDefinition;
|
||||
}
|
||||
|
||||
public static void put(String processDefinitionId, ProcessDefinition processDefinition) {
|
||||
map.put(processDefinitionId, processDefinition);
|
||||
ProcessDefinitionEntity pde = (ProcessDefinitionEntity) processDefinition;
|
||||
activities.put(processDefinitionId, pde.getActivities());
|
||||
for (ActivityImpl activityImpl : pde.getActivities()) {
|
||||
singleActivity.put(processDefinitionId + "_" + activityImpl.getId(), activityImpl);
|
||||
}
|
||||
}
|
||||
|
||||
public static ActivityImpl getActivity(String processDefinitionId, String activityId) {
|
||||
ProcessDefinition processDefinition = get(processDefinitionId);
|
||||
if (processDefinition != null) {
|
||||
ActivityImpl activityImpl = singleActivity.get(processDefinitionId + "_" + activityId);
|
||||
if (activityImpl != null) {
|
||||
return activityImpl;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getActivityName(String processDefinitionId, String activityId) {
|
||||
ActivityImpl activity = getActivity(processDefinitionId, activityId);
|
||||
if (activity != null) {
|
||||
return ObjectUtils.toString(activity.getProperty("name"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setRepositoryService(RepositoryService repositoryService) {
|
||||
ProcessDefinitionCache.repositoryService = repositoryService;
|
||||
}
|
||||
|
||||
}
|
||||
208
src/main/java/com/sipai/activiti/util/PropertyFileUtil.java
Normal file
208
src/main/java/com/sipai/activiti/util/PropertyFileUtil.java
Normal file
@ -0,0 +1,208 @@
|
||||
package com.sipai.activiti.util;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.DefaultPropertiesPersister;
|
||||
import org.springframework.util.PropertiesPersister;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 系统属性工具类
|
||||
*
|
||||
* @author HenryYan
|
||||
*/
|
||||
public class PropertyFileUtil {
|
||||
|
||||
|
||||
private static final String DEFAULT_ENCODING = "UTF-8";
|
||||
private static Logger logger = LoggerFactory.getLogger(PropertyFileUtil.class);
|
||||
private static Properties properties;
|
||||
private static PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
|
||||
private static ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
private static Properties activePropertyFiles = null;
|
||||
private static String PROFILE_ID = StringUtils.EMPTY;
|
||||
public static boolean INITIALIZED = false; // 是否已初始化
|
||||
|
||||
/**
|
||||
* 初始化读取配置文件,读取的文件列表位于classpath下面的application-files.properties<br/>
|
||||
* <p/>
|
||||
* 多个配置文件会用最后面的覆盖相同属性值
|
||||
*
|
||||
* @throws IOException 读取属性文件时
|
||||
*/
|
||||
public static void init() throws IOException {
|
||||
String fileNames = "application-files.properties";
|
||||
PROFILE_ID = StringUtils.EMPTY;
|
||||
innerInit(fileNames);
|
||||
activePropertyFiles(fileNames);
|
||||
INITIALIZED = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化读取配置文件,读取的文件列表位于classpath下面的application-[type]-files.properties<br/>
|
||||
* <p/>
|
||||
* 多个配置文件会用最后面的覆盖相同属性值
|
||||
*
|
||||
* @param profile 配置文件类型,application-[profile]-files.properties
|
||||
* @throws IOException 读取属性文件时
|
||||
*/
|
||||
public static void init(String profile) throws IOException {
|
||||
if (StringUtils.isBlank(profile)) {
|
||||
init();
|
||||
} else {
|
||||
PROFILE_ID = profile;
|
||||
String fileNames = "application-" + profile + "-files.properties";
|
||||
innerInit(fileNames);
|
||||
}
|
||||
INITIALIZED = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部处理
|
||||
*
|
||||
* @param fileName
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void innerInit(String fileName) throws IOException {
|
||||
String[] propFiles = activePropertyFiles(fileName);
|
||||
logger.debug("读取属性文件:{}", ArrayUtils.toString(propFiles));
|
||||
properties = loadProperties(propFiles);
|
||||
Set<Object> keySet = properties.keySet();
|
||||
for (Object key : keySet) {
|
||||
logger.debug("property: {}, value: {}", key, properties.getProperty(key.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取读取的资源文件列表
|
||||
*
|
||||
* @param fileName
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private static String[] activePropertyFiles(String fileName) throws IOException {
|
||||
logger.info("读取" + fileName);
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
InputStream resourceAsStream = loader.getResourceAsStream(fileName);
|
||||
// 默认的Properties实现使用HashMap算法,为了保持原有顺序使用有序Map
|
||||
activePropertyFiles = new LinkedProperties();
|
||||
activePropertyFiles.load(resourceAsStream);
|
||||
|
||||
Set<Object> fileKeySet = activePropertyFiles.keySet();
|
||||
String[] propFiles = new String[fileKeySet.size()];
|
||||
List<Object> fileList = new ArrayList<Object>();
|
||||
|
||||
fileList.addAll(activePropertyFiles.keySet());
|
||||
for (int i = 0; i < propFiles.length; i++) {
|
||||
String fileKey = fileList.get(i).toString();
|
||||
propFiles[i] = activePropertyFiles.getProperty(fileKey);
|
||||
}
|
||||
return propFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入多个properties文件, 相同的属性在最后载入的文件中的值将会覆盖之前的载入.
|
||||
* 文件路径使用Spring Resource格式, 文件编码使用UTF-8.
|
||||
*
|
||||
* @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
|
||||
*/
|
||||
public static Properties loadProperties(String... resourcesPaths) throws IOException {
|
||||
Properties props = new Properties();
|
||||
|
||||
for (String location : resourcesPaths) {
|
||||
|
||||
logger.debug("Loading properties file from:" + location);
|
||||
|
||||
InputStream is = null;
|
||||
try {
|
||||
Resource resource = resourceLoader.getResource(location);
|
||||
is = resource.getInputStream();
|
||||
propertiesPersister.load(props, new InputStreamReader(is, DEFAULT_ENCODING));
|
||||
} catch (IOException ex) {
|
||||
logger.info("Could not load properties from classpath:" + location + ": " + ex.getMessage());
|
||||
} finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的key
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Set<String> getKeys() {
|
||||
return properties.stringPropertyNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取键值对Map
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, String> getKeyValueMap() {
|
||||
Set<String> keys = getKeys();
|
||||
Map<String, String> values = new HashMap<String, String>();
|
||||
for (String key : keys) {
|
||||
values.put(key, get(key));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取属性值
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public static String get(String key) {
|
||||
String propertyValue = properties.getProperty(key);
|
||||
logger.debug("获取属性:{},值:{}", key, propertyValue);
|
||||
return propertyValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取属性值
|
||||
*
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
*/
|
||||
public static String get(String key, String defaultValue) {
|
||||
String propertyValue = properties.getProperty(key);
|
||||
String value = StringUtils.defaultString(propertyValue, defaultValue);
|
||||
logger.debug("获取属性:{},值:{}", key, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向内存添加属性
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public static void add(String key, String value) {
|
||||
properties.put(key, value);
|
||||
logger.debug("通过方法添加属性到内存:{},值:{}", key, value);
|
||||
}
|
||||
|
||||
public static Properties getActivePropertyFiles() {
|
||||
return activePropertyFiles;
|
||||
}
|
||||
|
||||
public static String getProfile() {
|
||||
return PROFILE_ID;
|
||||
}
|
||||
}
|
||||
24
src/main/java/com/sipai/activiti/util/PropertyType.java
Normal file
24
src/main/java/com/sipai/activiti/util/PropertyType.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.sipai.activiti.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 属性数据类型
|
||||
*
|
||||
* @author HenryYan
|
||||
*/
|
||||
public enum PropertyType {
|
||||
S(String.class), I(Integer.class), L(Long.class), F(Float.class), N(Double.class), D(Date.class), SD(java.sql.Date.class), B(
|
||||
Boolean.class);
|
||||
|
||||
private Class<?> clazz;
|
||||
|
||||
private PropertyType(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public Class<?> getValue() {
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
37
src/main/java/com/sipai/activiti/util/UserUtil.java
Normal file
37
src/main/java/com/sipai/activiti/util/UserUtil.java
Normal file
@ -0,0 +1,37 @@
|
||||
package com.sipai.activiti.util;
|
||||
|
||||
import org.activiti.engine.identity.User;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* 用户工具类
|
||||
*
|
||||
* @author HenryYan
|
||||
*/
|
||||
public class UserUtil {
|
||||
|
||||
public static final String USER = "user";
|
||||
|
||||
/**
|
||||
* 设置用户到session
|
||||
*
|
||||
* @param session
|
||||
* @param user
|
||||
*/
|
||||
public static void saveUserToSession(HttpSession session, User user) {
|
||||
session.setAttribute(USER, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Session获取当前用户信息
|
||||
*
|
||||
* @param session
|
||||
* @return
|
||||
*/
|
||||
public static User getUserFromSession(HttpSession session) {
|
||||
Object attribute = session.getAttribute(USER);
|
||||
return attribute == null ? null : (User) attribute;
|
||||
}
|
||||
|
||||
}
|
||||
77
src/main/java/com/sipai/activiti/util/Variable.java
Normal file
77
src/main/java/com/sipai/activiti/util/Variable.java
Normal file
@ -0,0 +1,77 @@
|
||||
package com.sipai.activiti.util;
|
||||
|
||||
import jodd.util.StringUtil;
|
||||
|
||||
import org.apache.commons.beanutils.ConvertUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Variable {
|
||||
|
||||
private String keys;
|
||||
private String values;
|
||||
private String types;
|
||||
|
||||
public String getKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
public void setKeys(String keys) {
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
public String getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public void setValues(String values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public String getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public void setTypes(String types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public Map<String, Object> getVariableMap() {
|
||||
Map<String, Object> vars = new HashMap<String, Object>();
|
||||
|
||||
ConvertUtils.register(new DateConverter(), java.util.Date.class);
|
||||
|
||||
if (StringUtil.isBlank(keys)) {
|
||||
return vars;
|
||||
}
|
||||
|
||||
String[] arrayKey = keys.split(",");
|
||||
String[] arrayValue = values.split(",");
|
||||
String[] arrayType = types.split(",");
|
||||
for (int i = 0; i < arrayKey.length; i++) {
|
||||
if ("".equals(arrayKey[i]) || "".equals(arrayValue[i]) || "".equals(arrayType[i])) {
|
||||
continue;
|
||||
}
|
||||
String key = arrayKey[i];
|
||||
String value = arrayValue[i];
|
||||
String type = arrayType[i];
|
||||
Object objectValue=null;
|
||||
if(!type.equals("A")){
|
||||
Class<?> targetType = Enum.valueOf(PropertyType.class, type).getValue();
|
||||
objectValue = ConvertUtils.convert(value, targetType);
|
||||
}else{
|
||||
//如果变量为ArrayList需特别处理
|
||||
String[] list =value.split("-");
|
||||
objectValue=new ArrayList<String>();
|
||||
for (String str : list) {
|
||||
((ArrayList)objectValue).add(str);
|
||||
}
|
||||
}
|
||||
vars.put(key, objectValue);
|
||||
}
|
||||
return vars;
|
||||
}
|
||||
|
||||
}
|
||||
83
src/main/java/com/sipai/activiti/util/WorkflowUtils.java
Normal file
83
src/main/java/com/sipai/activiti/util/WorkflowUtils.java
Normal file
@ -0,0 +1,83 @@
|
||||
package com.sipai.activiti.util;
|
||||
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author HenryYan
|
||||
*/
|
||||
public class WorkflowUtils {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(WorkflowUtils.class);
|
||||
|
||||
/**
|
||||
* 转换流程节点类型为中文说明
|
||||
*
|
||||
* @param type 英文名称
|
||||
* @return 翻译后的中文名称
|
||||
*/
|
||||
public static String parseToZhType(String type) {
|
||||
Map<String, String> types = new HashMap<String, String>();
|
||||
types.put("userTask", "用户任务");
|
||||
types.put("serviceTask", "系统任务");
|
||||
types.put("startEvent", "开始节点");
|
||||
types.put("endEvent", "结束节点");
|
||||
types.put("exclusiveGateway", "条件判断节点(系统自动根据条件处理)");
|
||||
types.put("inclusiveGateway", "并行处理任务");
|
||||
types.put("callActivity", "子流程");
|
||||
return types.get(type) == null ? type : types.get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出图片文件到硬盘
|
||||
*
|
||||
* @return 文件的全路径
|
||||
*/
|
||||
public static String exportDiagramToFile(RepositoryService repositoryService, ProcessDefinition processDefinition, String exportDir) throws IOException {
|
||||
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);
|
||||
return diagramPath;
|
||||
} else {
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
logger.debug("export diagram to : {}", diagramPath);
|
||||
|
||||
// wirte bytes to file
|
||||
FileUtils.writeByteArrayToFile(file, b);
|
||||
return diagramPath;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user