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
05beecd0
Commit
05beecd0
authored
Nov 12, 2018
by
Huang
Browse files
no commit message
parent
bc5dd330
Changes
368
Hide whitespace changes
Inline
Side-by-side
Too many changes to show.
To preserve performance only
20 of 368+
files are displayed.
Plain diff
Email patch
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/utils/http/HttpUtils.java
0 → 100644
View file @
05beecd0
package
com.jeespring.common.utils.http
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.net.ssl.*
;
import
java.io.*
;
import
java.net.ConnectException
;
import
java.net.SocketTimeoutException
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.security.cert.X509Certificate
;
/**
* 通用http发送方法
*
* @author JeeSpring
*/
public
class
HttpUtils
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
HttpUtils
.
class
);
/**
* 向指定 URL 发送GET方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public
static
String
sendGet
(
String
url
,
String
param
)
{
StringBuilder
result
=
new
StringBuilder
();
BufferedReader
in
=
null
;
try
{
String
urlNameString
=
url
+
"?"
+
param
;
log
.
info
(
"sendGet - {}"
,
urlNameString
);
URL
realUrl
=
new
URL
(
urlNameString
);
URLConnection
connection
=
realUrl
.
openConnection
();
connection
.
setRequestProperty
(
"accept"
,
"*/*"
);
connection
.
setRequestProperty
(
"connection"
,
"Keep-Alive"
);
connection
.
setRequestProperty
(
"user-agent"
,
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"
);
connection
.
connect
();
in
=
new
BufferedReader
(
new
InputStreamReader
(
connection
.
getInputStream
()));
String
line
;
while
((
line
=
in
.
readLine
())
!=
null
)
{
result
.
append
(
line
);
}
log
.
info
(
"recv - {}"
,
result
);
}
catch
(
ConnectException
e
)
{
log
.
error
(
"调用HttpUtils.sendGet ConnectException, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
catch
(
SocketTimeoutException
e
)
{
log
.
error
(
"调用HttpUtils.sendGet SocketTimeoutException, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
catch
(
IOException
e
)
{
log
.
error
(
"调用HttpUtils.sendGet IOException, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
catch
(
Exception
e
)
{
log
.
error
(
"调用HttpsUtil.sendGet Exception, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
finally
{
try
{
if
(
in
!=
null
)
{
in
.
close
();
}
}
catch
(
Exception
ex
)
{
log
.
error
(
"调用in.close Exception, url="
+
url
+
",param="
+
param
,
ex
.
getMessage
());
}
}
return
result
.
toString
();
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public
static
String
sendPost
(
String
url
,
String
param
)
{
PrintWriter
out
=
null
;
BufferedReader
in
=
null
;
StringBuilder
result
=
new
StringBuilder
();
try
{
String
urlNameString
=
url
+
"?"
+
param
;
log
.
info
(
"sendPost - {}"
,
urlNameString
);
URL
realUrl
=
new
URL
(
urlNameString
);
URLConnection
conn
=
realUrl
.
openConnection
();
conn
.
setRequestProperty
(
"accept"
,
"*/*"
);
conn
.
setRequestProperty
(
"connection"
,
"Keep-Alive"
);
conn
.
setRequestProperty
(
"user-agent"
,
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"
);
conn
.
setRequestProperty
(
"Accept-Charset"
,
"utf-8"
);
conn
.
setRequestProperty
(
"contentType"
,
"utf-8"
);
conn
.
setDoOutput
(
true
);
conn
.
setDoInput
(
true
);
out
=
new
PrintWriter
(
conn
.
getOutputStream
());
out
.
print
(
param
);
out
.
flush
();
in
=
new
BufferedReader
(
new
InputStreamReader
(
conn
.
getInputStream
(),
"utf-8"
));
String
line
;
while
((
line
=
in
.
readLine
())
!=
null
)
{
result
.
append
(
line
);
}
log
.
info
(
"recv - {}"
,
result
);
}
catch
(
ConnectException
e
)
{
log
.
error
(
"调用HttpUtils.sendPost ConnectException, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
catch
(
SocketTimeoutException
e
)
{
log
.
error
(
"调用HttpUtils.sendPost SocketTimeoutException, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
catch
(
IOException
e
)
{
log
.
error
(
"调用HttpUtils.sendPost IOException, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
catch
(
Exception
e
)
{
log
.
error
(
"调用HttpsUtil.sendPost Exception, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
finally
{
try
{
if
(
out
!=
null
)
{
out
.
close
();
}
if
(
in
!=
null
)
{
in
.
close
();
}
}
catch
(
IOException
ex
)
{
log
.
error
(
"调用in.close Exception, url="
+
url
+
",param="
+
param
,
ex
.
getMessage
());
}
}
return
result
.
toString
();
}
public
static
String
sendSSLPost
(
String
url
,
String
param
)
{
StringBuilder
result
=
new
StringBuilder
();
String
urlNameString
=
url
+
"?"
+
param
;
try
{
log
.
info
(
"sendSSLPost - {}"
,
urlNameString
);
SSLContext
sc
=
SSLContext
.
getInstance
(
"SSL"
);
sc
.
init
(
null
,
new
TrustManager
[]
{
new
TrustAnyTrustManager
()
},
new
java
.
security
.
SecureRandom
());
URL
console
=
new
URL
(
urlNameString
);
HttpsURLConnection
conn
=
(
HttpsURLConnection
)
console
.
openConnection
();
conn
.
setRequestProperty
(
"accept"
,
"*/*"
);
conn
.
setRequestProperty
(
"connection"
,
"Keep-Alive"
);
conn
.
setRequestProperty
(
"user-agent"
,
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"
);
conn
.
setRequestProperty
(
"Accept-Charset"
,
"utf-8"
);
conn
.
setRequestProperty
(
"contentType"
,
"utf-8"
);
conn
.
setDoOutput
(
true
);
conn
.
setDoInput
(
true
);
conn
.
setSSLSocketFactory
(
sc
.
getSocketFactory
());
conn
.
setHostnameVerifier
(
new
TrustAnyHostnameVerifier
());
conn
.
connect
();
InputStream
is
=
conn
.
getInputStream
();
BufferedReader
br
=
new
BufferedReader
(
new
InputStreamReader
(
is
));
String
ret
=
""
;
while
((
ret
=
br
.
readLine
())
!=
null
)
{
if
(
ret
!=
null
&&
!
""
.
equals
(
ret
.
trim
()))
{
result
.
append
(
new
String
(
ret
.
getBytes
(
"ISO-8859-1"
),
"utf-8"
));
}
}
log
.
info
(
"recv - {}"
,
result
);
conn
.
disconnect
();
br
.
close
();
}
catch
(
ConnectException
e
)
{
log
.
error
(
"调用HttpUtils.sendSSLPost ConnectException, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
catch
(
SocketTimeoutException
e
)
{
log
.
error
(
"调用HttpUtils.sendSSLPost SocketTimeoutException, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
catch
(
IOException
e
)
{
log
.
error
(
"调用HttpUtils.sendSSLPost IOException, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
catch
(
Exception
e
)
{
log
.
error
(
"调用HttpsUtil.sendSSLPost Exception, url="
+
url
+
",param="
+
param
,
e
.
getMessage
());
}
return
result
.
toString
();
}
private
static
class
TrustAnyTrustManager
implements
X509TrustManager
{
@Override
public
void
checkClientTrusted
(
X509Certificate
[]
chain
,
String
authType
)
{
}
@Override
public
void
checkServerTrusted
(
X509Certificate
[]
chain
,
String
authType
)
{
}
@Override
public
X509Certificate
[]
getAcceptedIssuers
()
{
return
new
X509Certificate
[]
{};
}
}
private
static
class
TrustAnyHostnameVerifier
implements
HostnameVerifier
{
@Override
public
boolean
verify
(
String
hostname
,
SSLSession
session
)
{
return
true
;
}
}
}
\ No newline at end of file
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/validator/BeanValidators.java
0 → 100644
View file @
05beecd0
/**
* Copyright (c) 2005-2012 springside.org.cn
*/
package
com.jeespring.common.validator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
javax.validation.ConstraintViolation
;
import
javax.validation.ConstraintViolationException
;
import
javax.validation.Validator
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
/**
* JSR303 Validator(Hibernate Validator)工具类.
*
* ConstraintViolation中包含propertyPath, message 和invalidValue等信息.
* 提供了各种convert方法,适合不同的i18n需求:
* 1. List<String>, String内容为message
* 2. List<String>, String内容为propertyPath + separator + message
* 3. Map<propertyPath, message>
*
* 详情见wiki: https://github.com/springside/springside4/wiki/HibernateValidator
* @author calvin
* @version 2013-01-15
*/
public
class
BeanValidators
{
/**
* 调用JSR303的validate方法, 验证失败时抛出ConstraintViolationException.
*/
@SuppressWarnings
({
"unchecked"
,
"rawtypes"
})
public
static
void
validateWithException
(
Validator
validator
,
Object
object
,
Class
<?>...
groups
)
throws
ConstraintViolationException
{
Set
constraintViolations
=
validator
.
validate
(
object
,
groups
);
if
(!
constraintViolations
.
isEmpty
())
{
throw
new
ConstraintViolationException
(
constraintViolations
);
}
}
/**
* 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>中为List<message>.
*/
public
static
List
<
String
>
extractMessage
(
ConstraintViolationException
e
)
{
return
extractMessage
(
e
.
getConstraintViolations
());
}
/**
* 辅助方法, 转换Set<ConstraintViolation>为List<message>
*/
@SuppressWarnings
(
"rawtypes"
)
public
static
List
<
String
>
extractMessage
(
Set
<?
extends
ConstraintViolation
>
constraintViolations
)
{
List
<
String
>
errorMessages
=
Lists
.
newArrayList
();
for
(
ConstraintViolation
violation
:
constraintViolations
)
{
errorMessages
.
add
(
violation
.
getMessage
());
}
return
errorMessages
;
}
/**
* 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为Map<property, message>.
*/
public
static
Map
<
String
,
String
>
extractPropertyAndMessage
(
ConstraintViolationException
e
)
{
return
extractPropertyAndMessage
(
e
.
getConstraintViolations
());
}
/**
* 辅助方法, 转换Set<ConstraintViolation>为Map<property, message>.
*/
@SuppressWarnings
(
"rawtypes"
)
public
static
Map
<
String
,
String
>
extractPropertyAndMessage
(
Set
<?
extends
ConstraintViolation
>
constraintViolations
)
{
Map
<
String
,
String
>
errorMessages
=
Maps
.
newHashMap
();
for
(
ConstraintViolation
violation
:
constraintViolations
)
{
errorMessages
.
put
(
violation
.
getPropertyPath
().
toString
(),
violation
.
getMessage
());
}
return
errorMessages
;
}
/**
* 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath message>.
*/
public
static
List
<
String
>
extractPropertyAndMessageAsList
(
ConstraintViolationException
e
)
{
return
extractPropertyAndMessageAsList
(
e
.
getConstraintViolations
(),
" "
);
}
/**
* 辅助方法, 转换Set<ConstraintViolations>为List<propertyPath message>.
*/
@SuppressWarnings
(
"rawtypes"
)
public
static
List
<
String
>
extractPropertyAndMessageAsList
(
Set
<?
extends
ConstraintViolation
>
constraintViolations
)
{
return
extractPropertyAndMessageAsList
(
constraintViolations
,
" "
);
}
/**
* 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath +separator+ message>.
*/
public
static
List
<
String
>
extractPropertyAndMessageAsList
(
ConstraintViolationException
e
,
String
separator
)
{
return
extractPropertyAndMessageAsList
(
e
.
getConstraintViolations
(),
separator
);
}
/**
* 辅助方法, 转换Set<ConstraintViolation>为List<propertyPath +separator+ message>.
*/
@SuppressWarnings
(
"rawtypes"
)
public
static
List
<
String
>
extractPropertyAndMessageAsList
(
Set
<?
extends
ConstraintViolation
>
constraintViolations
,
String
separator
)
{
List
<
String
>
errorMessages
=
Lists
.
newArrayList
();
for
(
ConstraintViolation
violation
:
constraintViolations
)
{
errorMessages
.
add
(
violation
.
getPropertyPath
()
+
separator
+
violation
.
getMessage
());
}
return
errorMessages
;
}
}
\ No newline at end of file
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/web/AbstractBaseController.java
0 → 100644
View file @
05beecd0
/**
* Copyright © 2012-2016 <a href="https://github.com/HuangBingGui/jeespring">jeespring</a> All rights reserved.
*/
package
com.jeespring.common.web
;
import
com.jeespring.common.mapper.JsonMapper
;
import
com.jeespring.common.redis.RedisUtils
;
import
com.jeespring.common.utils.DateUtils
;
import
com.jeespring.common.validator.BeanValidators
;
import
com.jeespring.modules.oauth.service.OauthService
;
import
com.jeespring.modules.utils.service.EmailService
;
import
org.apache.commons.lang3.StringEscapeUtils
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.ui.Model
;
import
org.springframework.validation.BindException
;
import
org.springframework.web.bind.WebDataBinder
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.servlet.mvc.support.RedirectAttributes
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.validation.ConstraintViolationException
;
import
javax.validation.ValidationException
;
import
javax.validation.Validator
;
import
java.beans.PropertyEditorSupport
;
import
java.io.IOException
;
import
java.util.Date
;
import
java.util.List
;
/**
* 控制器支持类
*
* @author 黄炳桂 516821420@qq.com
* @version 2013-3-23
*/
public
abstract
class
AbstractBaseController
{
/**
* 日志对象
*/
protected
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
/**
* 管理基础路径
*/
@Value
(
"${adminPath}"
)
protected
String
adminPath
;
/**
* 验证Bean实例对象
*/
@Autowired
protected
Validator
validator
;
@Autowired
private
EmailService
mailService
;
@Autowired
private
OauthService
oauthService
;
/**
* 服务端参数有效性验证
*
* @param object 验证的实体对象
* @param groups 验证组
* @return 验证成功:返回true;严重失败:将错误信息添加到 message 中
*/
protected
boolean
beanValidator
(
Model
model
,
Object
object
,
Class
<?>...
groups
)
{
try
{
BeanValidators
.
validateWithException
(
validator
,
object
,
groups
);
}
catch
(
ConstraintViolationException
ex
)
{
List
<
String
>
list
=
BeanValidators
.
extractPropertyAndMessageAsList
(
ex
,
": "
);
list
.
add
(
0
,
"数据验证失败:"
);
addMessage
(
model
,
list
.
toArray
(
new
String
[]{}));
return
false
;
}
return
true
;
}
/**
* 服务端参数有效性验证
*
* @param object 验证的实体对象
* @param groups 验证组
* @return 验证成功:返回true;严重失败:将错误信息添加到 flash message 中
*/
protected
boolean
beanValidator
(
RedirectAttributes
redirectAttributes
,
Object
object
,
Class
<?>...
groups
)
{
try
{
BeanValidators
.
validateWithException
(
validator
,
object
,
groups
);
}
catch
(
ConstraintViolationException
ex
)
{
List
<
String
>
list
=
BeanValidators
.
extractPropertyAndMessageAsList
(
ex
,
": "
);
list
.
add
(
0
,
"数据验证失败:"
);
addMessage
(
redirectAttributes
,
list
.
toArray
(
new
String
[]{}));
return
false
;
}
return
true
;
}
/**
* 服务端参数有效性验证
*
* @param object 验证的实体对象
* @param groups 验证组,不传入此参数时,同@Valid注解验证
* @return 验证成功:继续执行;验证失败:抛出异常跳转400页面。
*/
protected
void
beanValidator
(
Object
object
,
Class
<?>...
groups
)
{
BeanValidators
.
validateWithException
(
validator
,
object
,
groups
);
}
/**
* 添加Model消息
*
* @param model
* @param messages
*/
protected
void
addMessage
(
Model
model
,
String
...
messages
)
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
String
message
:
messages
)
{
sb
.
append
(
message
).
append
(
messages
.
length
>
1
?
"<br/>"
:
""
);
}
model
.
addAttribute
(
"message"
,
sb
.
toString
());
}
/**
* 添加Flash消息
*/
protected
void
addMessage
(
RedirectAttributes
redirectAttributes
,
String
...
messages
)
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
String
message
:
messages
)
{
sb
.
append
(
message
).
append
(
messages
.
length
>
1
?
"<br/>"
:
""
);
}
redirectAttributes
.
addFlashAttribute
(
"message"
,
sb
.
toString
());
}
/**
* 客户端返回JSON字符串
*
* @param response
* @param object
* @return
*/
protected
String
renderString
(
HttpServletResponse
response
,
Object
object
)
{
return
renderString
(
response
,
JsonMapper
.
toJsonString
(
object
),
"application/json"
);
}
/**
* 客户端返回字符串
*
* @param response
* @param string
* @return
*/
protected
String
renderString
(
HttpServletResponse
response
,
String
string
,
String
type
)
{
try
{
response
.
reset
();
response
.
setContentType
(
type
);
response
.
setCharacterEncoding
(
"utf-8"
);
response
.
getWriter
().
print
(
string
);
return
null
;
}
catch
(
IOException
e
)
{
return
null
;
}
}
/**
* 参数绑定异常
*/
@ExceptionHandler
({
Exception
.
class
,
BindException
.
class
,
ConstraintViolationException
.
class
,
ValidationException
.
class
})
public
String
bindException
(
Exception
ex
,
HttpServletRequest
request
)
{
//if(ex instanceof IOException){
// return "error/400";
//}
try
{
mailService
.
sendMailException
(
"Java后台异常"
,
"URL:"
+
request
.
getRequestURL
()
+
"<br>QueryString:"
+
request
.
getQueryString
()
+
"<br>Exception:"
+
ex
.
getMessage
()
+
"<br>"
);
}
catch
(
Exception
exception
){}
return
"error/400"
;
}
/**
* 授权登录异常
*/
@ExceptionHandler
({
AuthenticationException
.
class
})
public
String
authenticationException
()
{
return
"error/403"
;
}
/**
* 拦截API调用次数控制
*/
@ModelAttribute
protected
void
APIHandler
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
try
{
if
(!
RedisUtils
.
isShireRedis
()){
return
;}
if
(!
oauthService
.
isOauthOpen
()){
return
;}
//if(request.getRequestURI().indexOf("/rest/")<0) return;
if
(
request
.
getRequestURI
().
indexOf
(
"/rest/oauth/apiTimeLimiFaild"
)>=
0
)
{
return
;
}
if
(
request
.
getRequestURI
().
indexOf
(
"/admin?login"
)>=
0
)
{
return
;
}
if
(
request
.
getRequestURI
().
indexOf
(
"/admin/login"
)>=
0
)
{
return
;
}
if
(
"/admin"
.
equals
(
request
.
getRequestURI
())){
Result
result
=
oauthService
.
userOnlineAmount
();
if
(
"-1"
.
equals
(
result
.
getResultCode
()))
{
response
.
sendRedirect
(
"/rest/oauth/userOnlineAmountFaild"
);
}
return
;
}
oauthService
.
setApiTime
();
Result
result
=
oauthService
.
ApiTimeLimi
(
request
.
getRemoteAddr
());
if
(
result
.
getResultCoe
().
toString
()==
"-1"
){
//response.sendRedirect("../error/403");
if
(
request
.
getRequestURI
().
indexOf
(
"/rest/"
)>
0
)
{
response
.
sendRedirect
(
"/rest/oauth/apiTimeLimiFaild?apiTimeLimi="
+
result
.
getResultObject
());
}
else
{
response
.
sendRedirect
(
"/rest/oauth/apiTimeLimiFaild?apiTimeLimi="
+
result
.
getResultObject
());
}
//response.sendRedirect("/rest/oauth/apiTimeLimifaild");
}
}
catch
(
Exception
e
){
}
}
/**
* Rest云接口安全拦截
*/
@ModelAttribute
protected
void
RestHandler
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
try
{
if
(!
RedisUtils
.
isShireRedis
()){
return
;}
if
(!
oauthService
.
isOauthOpen
()){
return
;}
if
(
request
.
getRequestURI
().
indexOf
(
"/rest/"
)<
0
)
{
return
;
}
if
(
request
.
getRequestURI
().
indexOf
(
"/rest/oauth/token"
)>=
0
)
{
return
;
}
if
(
request
.
getRequestURI
().
indexOf
(
"/rest/oauth/faild"
)>=
0
)
{
return
;
}
if
(
request
.
getRequestURI
().
indexOf
(
"/rest/oauth/checkToken"
)>=
0
)
{
return
;
}
Result
result
=
oauthService
.
checkToken
(
request
.
getParameter
(
"token"
),
request
.
getRemoteAddr
());
if
(
result
.
getResultCoe
().
toString
()==
"-1"
){
//response.sendRedirect("../error/403");
response
.
sendRedirect
(
"/rest/oauth/faild"
);
}
}
catch
(
Exception
e
){
}
}
/**
* 初始化数据绑定
* 1. 将所有传递进来的String进行HTML编码,防止XSS攻击
* 2. 将字段中Date类型转换为String类型
*/
@InitBinder
protected
void
initBinder
(
WebDataBinder
binder
)
{
// String类型转换,将所有传递进来的String进行HTML编码,防止XSS攻击
binder
.
registerCustomEditor
(
String
.
class
,
new
PropertyEditorSupport
()
{
@Override
public
void
setAsText
(
String
text
)
{
//过滤,进行html转码
setValue
(
text
==
null
?
null
:
StringEscapeUtils
.
unescapeHtml4
(
StringEscapeUtils
.
escapeHtml4
(
text
.
trim
())));
//不过滤,不进行html转码
//setValue(text == null ? null : text.trim());
}
@Override
public
String
getAsText
()
{
Object
value
=
getValue
();
return
value
!=
null
?
StringEscapeUtils
.
unescapeHtml4
(
value
.
toString
())
:
""
;
//return value != null ? value.toString() : "";
}
});
// Date 类型转换
binder
.
registerCustomEditor
(
Date
.
class
,
new
PropertyEditorSupport
()
{
@Override
public
void
setAsText
(
String
text
)
{
setValue
(
DateUtils
.
parseDate
(
text
));
}
// @Override
// public String getAsText() {
// Object value = getValue();
// return value != null ? DateUtils.formatDateTime((Date)value) : "";
// }
});
}
}
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/web/CKFinderConfig.java
0 → 100644
View file @
05beecd0
/**
* Copyright © 2012-2016 <a href="https://github.com/HuangBingGui/jeespring">jeespring</a> All rights reserved.
*/
package
com.jeespring.common.web
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.util.Scanner
;
import
javax.servlet.ServletConfig
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
org.springframework.core.io.DefaultResourceLoader
;
import
org.springframework.core.io.Resource
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.Node
;
import
org.w3c.dom.NodeList
;
import
com.ckfinder.connector.configuration.Configuration
;
import
com.ckfinder.connector.configuration.Events
;
import
com.ckfinder.connector.data.AccessControlLevel
;
import
com.ckfinder.connector.utils.AccessControlUtil
;
import
com.ckfinder.connector.utils.PathUtils
;
import
com.jeespring.common.config.Global
;
import
com.jeespring.common.utils.FileUtils
;
import
com.jeespring.modules.sys.security.SystemAuthorizingRealm
;
import
com.jeespring.modules.sys.utils.UserUtils
;
/**
* CKFinder配置
*
* @author 黄炳桂 516821420@qq.com
* @version 2014-06-25
*/
public
class
CKFinderConfig
extends
Configuration
{
public
CKFinderConfig
(
ServletConfig
servletConfig
)
{
super
(
servletConfig
);
}
@Override
protected
Configuration
createConfigurationInstance
()
{
SystemAuthorizingRealm
.
Principal
principal
=
UserUtils
.
getPrincipal
();
if
(
principal
==
null
)
{
return
new
CKFinderConfig
(
this
.
servletConf
);
}
boolean
isView
=
true
;
boolean
isUpload
=
true
;
boolean
isEdit
=
true
;
AccessControlLevel
alc
=
this
.
getAccessConrolLevels
().
get
(
0
);
alc
.
setFolderView
(
isView
);
alc
.
setFolderCreate
(
isEdit
);
alc
.
setFolderRename
(
isEdit
);
alc
.
setFolderDelete
(
isEdit
);
alc
.
setFileView
(
isView
);
alc
.
setFileUpload
(
isUpload
);
alc
.
setFileRename
(
isEdit
);
alc
.
setFileDelete
(
isEdit
);
AccessControlUtil
.
getInstance
(
this
).
loadACLConfig
();
try
{
this
.
baseURL
=
FileUtils
.
path
(
Servlets
.
getRequest
().
getContextPath
()
+
Global
.
USERFILES_BASE_URL
+
principal
+
"/"
);
this
.
baseDir
=
FileUtils
.
path
(
Global
.
getUserfilesBaseDir
()
+
Global
.
USERFILES_BASE_URL
+
principal
+
"/"
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
return
new
CKFinderConfig
(
this
.
servletConf
);
}
@Override
public
boolean
checkAuthentication
(
final
HttpServletRequest
request
)
{
return
UserUtils
.
getPrincipal
()
!=
null
;
}
@Override
public
void
init
()
throws
Exception
{
DefaultResourceLoader
loader
=
new
DefaultResourceLoader
();
Resource
resource
=
loader
.
getResource
(
this
.
xmlFilePath
);
Class
<?>
clazz
=
getClass
().
getSuperclass
();
Field
field
=
clazz
.
getDeclaredField
(
"lastCfgModificationDate"
);
Method
method
=
clazz
.
getDeclaredMethod
(
"clearConfiguration"
);
method
.
setAccessible
(
true
);
method
.
invoke
(
this
);
field
.
setAccessible
(
true
);
field
.
set
(
this
,
System
.
currentTimeMillis
());
DocumentBuilderFactory
dbf
=
DocumentBuilderFactory
.
newInstance
();
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
Document
doc
=
db
.
parse
(
resource
.
getInputStream
());
doc
.
normalize
();
Node
node
=
doc
.
getFirstChild
();
if
(
node
!=
null
)
{
NodeList
nodeList
=
node
.
getChildNodes
();
for
(
int
i
=
0
;
i
<
nodeList
.
getLength
();
++
i
)
{
Node
childNode
=
nodeList
.
item
(
i
);
if
(
"enabled"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
enabled
=
Boolean
.
valueOf
(
childNode
.
getTextContent
().
trim
()).
booleanValue
();
}
if
(
"baseDir"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
baseDir
=
childNode
.
getTextContent
().
trim
();
this
.
baseDir
=
PathUtils
.
escape
(
this
.
baseDir
);
this
.
baseDir
=
PathUtils
.
addSlashToEnd
(
this
.
baseDir
);
}
if
(
"baseURL"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
baseURL
=
childNode
.
getTextContent
().
trim
();
this
.
baseURL
=
PathUtils
.
escape
(
this
.
baseURL
);
this
.
baseURL
=
PathUtils
.
addSlashToEnd
(
this
.
baseURL
);
}
if
(
"licenseName"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
licenseName
=
childNode
.
getTextContent
().
trim
();
}
if
(
"licenseKey"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
licenseKey
=
childNode
.
getTextContent
().
trim
();
}
String
value
;
if
(
"imgWidth"
.
equals
(
childNode
.
getNodeName
()))
{
value
=
childNode
.
getTextContent
().
trim
();
value
=
value
.
replaceAll
(
"//D"
,
""
);
try
{
this
.
imgWidth
=
Integer
.
valueOf
(
value
);
}
catch
(
NumberFormatException
var13
)
{
this
.
imgWidth
=
null
;
}
}
if
(
"imgQuality"
.
equals
(
childNode
.
getNodeName
()))
{
value
=
childNode
.
getTextContent
().
trim
();
value
=
value
.
replaceAll
(
"//D"
,
""
);
method
=
clazz
.
getDeclaredMethod
(
"adjustQuality"
,
new
Class
[]{
String
.
class
});
method
.
setAccessible
(
true
);
this
.
imgQuality
=
Float
.
parseFloat
(
method
.
invoke
(
this
,
value
).
toString
());
}
if
(
"imgHeight"
.
equals
(
childNode
.
getNodeName
()))
{
value
=
childNode
.
getTextContent
().
trim
();
value
=
value
.
replaceAll
(
"//D"
,
""
);
try
{
this
.
imgHeight
=
Integer
.
valueOf
(
value
);
}
catch
(
NumberFormatException
var12
)
{
this
.
imgHeight
=
null
;
}
}
if
(
"thumbs"
.
equals
(
childNode
.
getNodeName
()))
{
method
=
clazz
.
getDeclaredMethod
(
"setThumbs"
,
new
Class
[]{
NodeList
.
class
});
method
.
setAccessible
(
true
);
method
.
invoke
(
this
,
childNode
.
getChildNodes
());
}
if
(
"accessControls"
.
equals
(
childNode
.
getNodeName
()))
{
method
=
clazz
.
getDeclaredMethod
(
"setACLs"
,
new
Class
[]{
NodeList
.
class
});
method
.
setAccessible
(
true
);
method
.
invoke
(
this
,
childNode
.
getChildNodes
());
}
if
(
"hideFolders"
.
equals
(
childNode
.
getNodeName
()))
{
method
=
clazz
.
getDeclaredMethod
(
"setHiddenFolders"
,
new
Class
[]{
NodeList
.
class
});
method
.
setAccessible
(
true
);
method
.
invoke
(
this
,
childNode
.
getChildNodes
());
}
if
(
"hideFiles"
.
equals
(
childNode
.
getNodeName
()))
{
method
=
clazz
.
getDeclaredMethod
(
"setHiddenFiles"
,
new
Class
[]{
NodeList
.
class
});
method
.
setAccessible
(
true
);
method
.
invoke
(
this
,
childNode
.
getChildNodes
());
}
if
(
"checkDoubleExtension"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
doubleExtensions
=
Boolean
.
valueOf
(
childNode
.
getTextContent
().
trim
()).
booleanValue
();
}
if
(
"disallowUnsafeCharacters"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
disallowUnsafeCharacters
=
Boolean
.
valueOf
(
childNode
.
getTextContent
().
trim
()).
booleanValue
();
}
if
(
"forceASCII"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
forceASCII
=
Boolean
.
valueOf
(
childNode
.
getTextContent
().
trim
()).
booleanValue
();
}
if
(
"checkSizeAfterScaling"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
checkSizeAfterScaling
=
Boolean
.
valueOf
(
childNode
.
getTextContent
().
trim
()).
booleanValue
();
}
Scanner
sc
;
if
(
"htmlExtensions"
.
equals
(
childNode
.
getNodeName
()))
{
value
=
childNode
.
getTextContent
();
sc
=
(
new
Scanner
(
value
)).
useDelimiter
(
","
);
while
(
sc
.
hasNext
())
{
String
val
=
sc
.
next
();
if
(
val
!=
null
&&
!
""
.
equals
(
val
))
{
this
.
htmlExtensions
.
add
(
val
.
trim
().
toLowerCase
());
}
}
}
if
(
"secureImageUploads"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
secureImageUploads
=
Boolean
.
valueOf
(
childNode
.
getTextContent
().
trim
()).
booleanValue
();
}
if
(
"uriEncoding"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
uriEncoding
=
childNode
.
getTextContent
().
trim
();
}
if
(
"userRoleSessionVar"
.
equals
(
childNode
.
getNodeName
()))
{
this
.
userRoleSessionVar
=
childNode
.
getTextContent
().
trim
();
}
if
(
"defaultResourceTypes"
.
equals
(
childNode
.
getNodeName
()))
{
value
=
childNode
.
getTextContent
().
trim
();
sc
=
(
new
Scanner
(
value
)).
useDelimiter
(
","
);
while
(
sc
.
hasNext
())
{
this
.
defaultResourceTypes
.
add
(
sc
.
next
());
}
}
if
(
"plugins"
.
equals
(
childNode
.
getNodeName
()))
{
method
=
clazz
.
getDeclaredMethod
(
"setPlugins"
,
new
Class
[]{
Node
.
class
});
method
.
setAccessible
(
true
);
method
.
invoke
(
this
,
childNode
);
}
if
(
"basePathBuilderImpl"
.
equals
(
childNode
.
getNodeName
()))
{
method
=
clazz
.
getDeclaredMethod
(
"setBasePathImpl"
,
new
Class
[]{
String
.
class
});
method
.
setAccessible
(
true
);
method
.
invoke
(
this
,
childNode
.
getTextContent
().
trim
());
}
}
}
method
=
clazz
.
getDeclaredMethod
(
"setTypes"
,
new
Class
[]{
Document
.
class
});
method
.
setAccessible
(
true
);
method
.
invoke
(
this
,
doc
);
field
=
clazz
.
getDeclaredField
(
"events"
);
field
.
setAccessible
(
true
);
field
.
set
(
this
,
new
Events
());
this
.
registerEventHandlers
();
}
}
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/web/Result.java
0 → 100644
View file @
05beecd0
package
com.jeespring.common.web
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
public
class
Result
extends
HashMap
<
String
,
Object
>
implements
Map
<
String
,
Object
>{
/**
*
*/
private
static
final
long
serialVersionUID
=
1L
;
private
HashMap
<
String
,
Object
>
resultHashMap
=
new
HashMap
<
String
,
Object
>();
public
void
setResultObject
(
Object
obejct
)
{
put
(
"RESULT"
,
obejct
);
}
public
void
setResultExtend
(
String
key
,
Object
object
){
JSONObject
jsonObject
=
JSON
.
parseObject
(
JSON
.
toJSONString
(
get
(
"RESULT"
)));
jsonObject
.
put
(
key
,
object
);
put
(
"RESULT"
,
jsonObject
);
}
public
void
setResultHashMap
(
String
item
,
Object
obejct
)
{
resultHashMap
.
put
(
item
,
obejct
);
put
(
"RESULT"
,
resultHashMap
);
}
public
void
setResultCode
(
Object
resultCode
)
{
put
(
"CODE"
,
resultCode
);
}
public
Object
getResultCoe
(){
return
get
(
"CODE"
);
}
public
Object
getResultCode
(){
return
get
(
"CODE"
);
}
public
<
T
>
List
<
T
>
getResutObjectList
()
{
return
(
List
<
T
>)
get
(
"RESULT"
);
}
public
<
V
,
K
>
Map
<
K
,
V
>
getResutObjectMap
()
{
return
(
Map
<
K
,
V
>)
get
(
"RESULT"
);
}
public
<
T
extends
Object
>
T
getResultObject
()
{
return
(
T
)
get
(
"RESULT"
);
}
}
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/web/ResultFactory.java
0 → 100644
View file @
05beecd0
package
com.jeespring.common.web
;
public
class
ResultFactory
{
private
ResultFactory
()
{
}
protected
static
final
String
SuccessCode
=
"0"
;
protected
static
final
String
ErrorCode
=
"-1"
;
public
static
Result
getSuccessResult
()
{
return
getResultBean
(
SuccessCode
,
"成功"
);
}
public
static
Result
getSuccessResult
(
String
resultMessage
)
{
return
getResultBean
(
SuccessCode
,
resultMessage
);
}
public
static
Result
getErrorResult
(
String
resultMessage
)
{
return
getResultBean
(
ErrorCode
,
resultMessage
);
}
private
static
Result
getResultBean
(
String
resultCode
,
String
resultMessage
)
{
Result
result
=
ResultBean
.
result
.
getResult
();
result
.
put
(
"CODE"
,
resultCode
);
result
.
put
(
"MESSAGE"
,
resultMessage
);
return
result
;
}
public
static
Result
getResultBean
(
String
resultMessage
,
Object
o
)
{
Result
result
=
ResultBean
.
result
.
getResult
();
result
.
put
(
"CODE"
,
SuccessCode
);
result
.
put
(
"MESSAGE"
,
resultMessage
);
result
.
put
(
"Object"
,
o
);
return
result
;
}
private
enum
ResultBean
{
result
;
Result
getResult
()
{
return
new
Result
();
}
}
}
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/web/Servlets.java
0 → 100644
View file @
05beecd0
/**
* Copyright (c) 2005-2012 springside.org.cn
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
*/
package
com.jeespring.common.web
;
import
java.io.UnsupportedEncodingException
;
import
java.util.Enumeration
;
import
java.util.Iterator
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.StringTokenizer
;
import
java.util.TreeMap
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.apache.commons.lang3.Validate
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
com.google.common.net.HttpHeaders
;
import
com.jeespring.common.config.Global
;
import
com.jeespring.common.utils.Encodes
;
import
com.jeespring.common.utils.StringUtils
;
import
com.jeespring.modules.sys.security.SystemAuthorizingRealm.Principal
;
import
com.jeespring.modules.sys.utils.UserUtils
;
/**
* Http与Servlet工具类.
*
* @author calvin/HuangBingGui
* @version 2014-8-19
*/
public
class
Servlets
{
// -- 常用数值定义 --//
public
static
final
long
ONE_YEAR_SECONDS
=
60
*
60
*
24
*
365
;
// 静态文件后缀
private
static
String
[]
staticFiles
;
/**
* 设置客户端缓存过期时间 的Header.
*/
public
static
void
setExpiresHeader
(
HttpServletResponse
response
,
long
expiresSeconds
)
{
// Http 1.0 header, set a fix expires date.
response
.
setDateHeader
(
HttpHeaders
.
EXPIRES
,
System
.
currentTimeMillis
()
+
expiresSeconds
*
1000
);
// Http 1.1 header, set a time after now.
response
.
setHeader
(
HttpHeaders
.
CACHE_CONTROL
,
"private, max-age="
+
expiresSeconds
);
}
/**
* 设置禁止客户端缓存的Header.
*/
public
static
void
setNoCacheHeader
(
HttpServletResponse
response
)
{
// Http 1.0 header
response
.
setDateHeader
(
HttpHeaders
.
EXPIRES
,
1L
);
response
.
addHeader
(
HttpHeaders
.
PRAGMA
,
"no-cache"
);
// Http 1.1 header
response
.
setHeader
(
HttpHeaders
.
CACHE_CONTROL
,
"no-cache, no-store, max-age=0"
);
}
/**
* 设置LastModified Header.
*/
public
static
void
setLastModifiedHeader
(
HttpServletResponse
response
,
long
lastModifiedDate
)
{
response
.
setDateHeader
(
HttpHeaders
.
LAST_MODIFIED
,
lastModifiedDate
);
}
/**
* 设置Etag Header.
*/
public
static
void
setEtag
(
HttpServletResponse
response
,
String
etag
)
{
response
.
setHeader
(
HttpHeaders
.
ETAG
,
etag
);
}
/**
* 根据浏览器If-Modified-Since Header, 计算文件是否已被修改.
* <p>
* 如果无修改, checkIfModify返回false ,设置304 not modify status.
*
* @param lastModified 内容的最后修改时间.
*/
public
static
boolean
checkIfModifiedSince
(
HttpServletRequest
request
,
HttpServletResponse
response
,
long
lastModified
)
{
long
ifModifiedSince
=
request
.
getDateHeader
(
HttpHeaders
.
IF_MODIFIED_SINCE
);
if
((
ifModifiedSince
!=
-
1
)
&&
(
lastModified
<
ifModifiedSince
+
1000
))
{
response
.
setStatus
(
HttpServletResponse
.
SC_NOT_MODIFIED
);
return
false
;
}
return
true
;
}
/**
* 根据浏览器 If-None-Match Header, 计算Etag是否已无效.
* <p>
* 如果Etag有效, checkIfNoneMatch返回false, 设置304 not modify status.
*
* @param etag 内容的ETag.
*/
public
static
boolean
checkIfNoneMatchEtag
(
HttpServletRequest
request
,
HttpServletResponse
response
,
String
etag
)
{
String
headerValue
=
request
.
getHeader
(
HttpHeaders
.
IF_NONE_MATCH
);
if
(
headerValue
!=
null
)
{
boolean
conditionSatisfied
=
false
;
if
(!
"*"
.
equals
(
headerValue
))
{
StringTokenizer
commaTokenizer
=
new
StringTokenizer
(
headerValue
,
","
);
while
(!
conditionSatisfied
&&
commaTokenizer
.
hasMoreTokens
())
{
String
currentToken
=
commaTokenizer
.
nextToken
();
if
(
currentToken
.
trim
().
equals
(
etag
))
{
conditionSatisfied
=
true
;
}
}
}
else
{
conditionSatisfied
=
true
;
}
if
(
conditionSatisfied
)
{
response
.
setStatus
(
HttpServletResponse
.
SC_NOT_MODIFIED
);
response
.
setHeader
(
HttpHeaders
.
ETAG
,
etag
);
return
false
;
}
}
return
true
;
}
/**
* 设置让浏览器弹出下载对话框的Header.
*
* @param fileName 下载后的文件名.
*/
public
static
void
setFileDownloadHeader
(
HttpServletResponse
response
,
String
fileName
)
{
try
{
// 中文文件名支持
String
encodedfileName
=
new
String
(
fileName
.
getBytes
(),
"ISO8859-1"
);
response
.
setHeader
(
HttpHeaders
.
CONTENT_DISPOSITION
,
"attachment; filename=\""
+
encodedfileName
+
"\""
);
}
catch
(
UnsupportedEncodingException
e
)
{
e
.
getMessage
();
}
}
/**
* 取得带相同前缀的Request Parameters, copy from spring WebUtils.
* <p>
* 返回的结果的Parameter名已去除前缀.
*/
@SuppressWarnings
(
"rawtypes"
)
public
static
Map
<
String
,
Object
>
getParametersStartingWith
(
ServletRequest
request
,
String
prefix
)
{
Validate
.
notNull
(
request
,
"Request must not be null"
);
Enumeration
paramNames
=
request
.
getParameterNames
();
Map
<
String
,
Object
>
params
=
new
TreeMap
<
String
,
Object
>();
String
pre
=
prefix
;
if
(
pre
==
null
)
{
pre
=
""
;
}
while
(
paramNames
!=
null
&&
paramNames
.
hasMoreElements
())
{
String
paramName
=
(
String
)
paramNames
.
nextElement
();
if
(
""
.
equals
(
pre
)
||
paramName
.
startsWith
(
pre
))
{
String
unprefixed
=
paramName
.
substring
(
pre
.
length
());
String
[]
values
=
request
.
getParameterValues
(
paramName
);
if
(
values
==
null
||
values
.
length
==
0
)
{
values
=
new
String
[]{};
// Do nothing, no values found at all.
}
else
if
(
values
.
length
>
1
)
{
params
.
put
(
unprefixed
,
values
);
}
else
{
params
.
put
(
unprefixed
,
values
[
0
]);
}
}
}
return
params
;
}
/**
* 组合Parameters生成Query String的Parameter部分,并在paramter name上加上prefix.
*/
public
static
String
encodeParameterStringWithPrefix
(
Map
<
String
,
Object
>
params
,
String
prefix
)
{
StringBuilder
queryStringBuilder
=
new
StringBuilder
();
String
pre
=
prefix
;
if
(
pre
==
null
)
{
pre
=
""
;
}
Iterator
<
Entry
<
String
,
Object
>>
it
=
params
.
entrySet
().
iterator
();
while
(
it
.
hasNext
())
{
Entry
<
String
,
Object
>
entry
=
it
.
next
();
queryStringBuilder
.
append
(
pre
).
append
(
entry
.
getKey
()).
append
(
"="
).
append
(
entry
.
getValue
());
if
(
it
.
hasNext
())
{
queryStringBuilder
.
append
(
"&"
);
}
}
return
queryStringBuilder
.
toString
();
}
/**
* 客户端对Http Basic验证的 Header进行编码.
*/
public
static
String
encodeHttpBasic
(
String
userName
,
String
password
)
{
String
encode
=
userName
+
":"
+
password
;
return
"Basic "
+
Encodes
.
encodeBase64
(
encode
.
getBytes
());
}
/**
* 是否是Ajax异步请求
*
* @param request
*/
public
static
boolean
isAjaxRequest
(
HttpServletRequest
request
)
{
String
accept
=
request
.
getHeader
(
"accept"
);
String
xRequestedWith
=
request
.
getHeader
(
"X-Requested-With"
);
Principal
principal
=
UserUtils
.
getPrincipal
();
// 如果是异步请求或是手机端,则直接返回信息
return
((
accept
!=
null
&&
accept
.
indexOf
(
"application/json"
)
!=
-
1
||
(
xRequestedWith
!=
null
&&
xRequestedWith
.
indexOf
(
"XMLHttpRequest"
)
!=
-
1
)
||
(
principal
!=
null
&&
principal
.
isMobileLogin
())));
}
/**
* 获取当前请求对象
*
* @return
*/
public
static
HttpServletRequest
getRequest
()
{
try
{
return
((
ServletRequestAttributes
)
RequestContextHolder
.
getRequestAttributes
()).
getRequest
();
}
catch
(
Exception
e
)
{
return
null
;
}
}
/**
* 判断访问URI是否是静态文件请求
*
* @throws Exception
*/
public
static
boolean
isStaticFile
(
String
uri
)
{
if
(
staticFiles
==
null
)
{
staticFiles
=
StringUtils
.
split
(
Global
.
getConfig
(
"web.staticFile"
),
","
);
}
return
StringUtils
.
endsWithAny
(
uri
,
staticFiles
)
&&
!
StringUtils
.
endsWithAny
(
uri
,
".html"
)
&&
!
StringUtils
.
endsWithAny
(
uri
,
".jsp"
)
&&
!
StringUtils
.
endsWithAny
(
uri
,
".java"
);
}
}
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/websocket/WebSockertFilter.java
0 → 100644
View file @
05beecd0
package
com.jeespring.common.websocket
;
import
java.io.IOException
;
import
java.net.UnknownHostException
;
import
java.util.Calendar
;
import
java.util.Date
;
import
java.util.Timer
;
import
java.util.TimerTask
;
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
org.java_websocket.WebSocketImpl
;
import
com.jeespring.common.websocket.onchat.ChatServer
;
public
class
WebSockertFilter
{
/**
* 初始化
*/
public
void
init
(
FilterConfig
fc
)
throws
ServletException
{
this
.
startWebsocketChatServer
();
// this.startWebsocketOnline();
}
/**
* 启动即时聊天服务
*/
public
void
startWebsocketChatServer
(){
WebSocketImpl
.
DEBUG
=
false
;
ChatServer
s
;
try
{
s
=
new
ChatServer
(
8668
);
s
.
start
();
System
.
out
.
println
(
"websocket服务器启动,端口"
+
s
.
getPort
()
);
}
catch
(
UnknownHostException
e
)
{
e
.
printStackTrace
();
}
}
//计时器
public
void
timer
()
{
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
set
(
Calendar
.
HOUR_OF_DAY
,
9
);
// 控制时
calendar
.
set
(
Calendar
.
MINUTE
,
0
);
// 控制分
calendar
.
set
(
Calendar
.
SECOND
,
0
);
// 控制秒
Date
time
=
calendar
.
getTime
();
// 得出执行任务的时间
Timer
timer
=
new
Timer
();
timer
.
scheduleAtFixedRate
(
new
TimerTask
()
{
@Override
public
void
run
()
{
//PersonService personService = (PersonService)ApplicationContext.getBean("personService");
//System.out.println("-------设定要指定任务--------");
}
},
time
,
1000
*
60
*
60
*
24
);
// 这里设定将延时每天固定执行
}
public
void
destroy
()
{
// TODO Auto-generated method stub
}
public
void
doFilter
(
ServletRequest
arg0
,
ServletResponse
arg1
,
FilterChain
arg2
)
throws
IOException
,
ServletException
{
// TODO Auto-generated method stub
}
}
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/websocket/onchat/ChatServer.java
0 → 100644
View file @
05beecd0
package
com.jeespring.common.websocket.onchat
;
import
java.io.IOException
;
import
java.net.InetSocketAddress
;
import
java.net.UnknownHostException
;
import
java.nio.ByteBuffer
;
import
java.nio.CharBuffer
;
import
java.nio.charset.Charset
;
import
java.nio.charset.CharsetDecoder
;
import
java.text.SimpleDateFormat
;
import
java.util.Collection
;
import
java.util.Date
;
import
org.java_websocket.WebSocket
;
import
org.java_websocket.WebSocketImpl
;
import
org.java_websocket.framing.Framedata
;
import
org.java_websocket.handshake.ClientHandshake
;
import
org.java_websocket.server.WebSocketServer
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
com.jeespring.common.json.AjaxJson
;
import
com.jeespring.common.utils.SpringContextHolder
;
import
com.jeespring.common.websocket.utils.Constant
;
import
com.jeespring.modules.iim.entity.ChatHistory
;
import
com.jeespring.modules.iim.service.ChatHistoryService
;
import
java.util.List
;
public
class
ChatServer
extends
WebSocketServer
{
public
ChatServer
(
int
port
)
throws
UnknownHostException
{
super
(
new
InetSocketAddress
(
port
));
}
public
ChatServer
(
InetSocketAddress
address
)
{
super
(
address
);
}
/**
* 触发连接事件
*/
@Override
public
void
onOpen
(
WebSocket
conn
,
ClientHandshake
handshake
)
{
// Collection<String> onlineUsers = MsgServerPool.getOnlineUser();
// AjaxJson j = new AjaxJson();
// j.put("data", onlineUsers);
// MsgServerPool.sendMessageToUser(conn, "_online_all_status_"+j.getJsonStr());//首次登陆系统时,获取用户的在线状态
}
/**
* 触发关闭事件
*/
@Override
public
void
onClose
(
WebSocket
conn
,
int
code
,
String
reason
,
boolean
remote
)
{
userLeave
(
conn
);
Collection
<
String
>
onlineUsers
=
ChatServerPool
.
getOnlineUser
();
AjaxJson
j
=
new
AjaxJson
();
j
.
put
(
"data"
,
onlineUsers
);
ChatServerPool
.
sendMessage
(
"_online_all_status_"
+
j
.
getJsonStr
());
//通知所有用户更新在线信息
}
/**
* 客户端发送消息到服务器时触发事件
*/
@Override
public
void
onMessage
(
WebSocket
conn
,
String
message
){
message
=
message
.
toString
();
ChatHistoryService
chatHistoryService
=
SpringContextHolder
.
getBean
(
"chatHistoryService"
);
// TODO Auto-generated catch block
if
(
null
!=
message
&&
message
.
startsWith
(
Constant
.
_online_user_
)){
//用户上线
String
userId
=
message
.
replaceFirst
(
Constant
.
_online_user_
,
""
);
this
.
userjoin
(
userId
,
conn
);
//通知所有用户更新在线信息
Collection
<
String
>
onlineUsers
=
ChatServerPool
.
getOnlineUser
();
AjaxJson
j
=
new
AjaxJson
();
j
.
put
(
"data"
,
onlineUsers
);
ChatServerPool
.
sendMessage
(
"_online_all_status_"
+
j
.
getJsonStr
());
//通知所有用户更新在线信息
//读取离线信息
ChatHistory
chat
=
new
ChatHistory
();
chat
.
setUserid2
(
userId
);
chat
.
setStatus
(
"0"
);
List
<
ChatHistory
>
list
=
chatHistoryService
.
findList
(
chat
);
for
(
ChatHistory
c
:
list
){
ChatServerPool
.
sendMessageToUser
(
conn
,
c
.
getUserid1
()+
Constant
.
_msg_
+
c
.
getUserid2
()+
Constant
.
_msg_
+
c
.
getMsg
()+
Constant
.
_msg_
+
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
).
format
(
c
.
getCreateDate
()));
//向所某用户发送消息
c
.
setStatus
(
"1"
);
//标记为已读
chatHistoryService
.
save
(
c
);
}
}
if
(
null
!=
message
&&
message
.
startsWith
(
Constant
.
_leave_user_
)){
//用户离线
this
.
userLeave
(
conn
);
Collection
<
String
>
onlineUsers
=
ChatServerPool
.
getOnlineUser
();
AjaxJson
j
=
new
AjaxJson
();
j
.
put
(
"data"
,
onlineUsers
);
ChatServerPool
.
sendMessage
(
"_online_all_status_"
+
j
.
getJsonStr
());
//通知所有用户更新在线信息
}
if
(
null
!=
message
&&
message
.
contains
(
Constant
.
_msg_
)){
//
String
[]
arr
=
message
.
split
(
Constant
.
_msg_
);
String
fromUser
=
arr
[
0
];
String
toUser
=
arr
[
1
];
String
msg
=
arr
[
2
];
//保存聊天记录
ChatHistory
chat
=
new
ChatHistory
();
chat
.
setUserid1
(
fromUser
);
chat
.
setUserid2
(
toUser
);
chat
.
setMsg
(
msg
);
chat
.
setCreateDate
(
new
Date
());
WebSocket
toUserConn
=
ChatServerPool
.
getWebSocketByUser
(
toUser
);
if
(
toUserConn
!=
null
){
ChatServerPool
.
sendMessageToUser
(
ChatServerPool
.
getWebSocketByUser
(
toUser
),
message
);
//向所某用户发送消息
chat
.
setStatus
(
"1"
);
//设置为已读
}
else
{
ChatServerPool
.
sendMessageToUser
(
conn
,
"_sys_对方现在离线,他将在上线后收到你的消息!"
);
//同时向本人发送消息
chat
.
setStatus
(
"0"
);
//设置为未读
}
chatHistoryService
.
save
(
chat
);
}
}
@Override
public
void
onMessage
(
WebSocket
conn
,
ByteBuffer
buffer
){
Charset
charset
=
null
;
CharsetDecoder
decoder
=
null
;
CharBuffer
charBuffer
=
null
;
try
{
charset
=
Charset
.
forName
(
"UTF-8"
);
decoder
=
charset
.
newDecoder
();
// charBuffer = decoder.decode(buffer);//用这个的话,只能输出来一次结果,第二次显示为空
charBuffer
=
decoder
.
decode
(
buffer
.
asReadOnlyBuffer
());
//return charBuffer.toString();
System
.
out
.
println
(
charBuffer
.
toString
());
}
catch
(
Exception
ex
)
{
ex
.
printStackTrace
();
}
}
public
void
onFragment
(
WebSocket
conn
,
Framedata
fragment
)
{
}
/**
* 触发异常事件
*/
@Override
public
void
onError
(
WebSocket
conn
,
Exception
ex
)
{
ex
.
printStackTrace
();
if
(
conn
!=
null
)
{
//some errors like port binding failed may not be assignable to a specific websocket
}
}
/**
* 用户加入处理
* @param user
*/
public
void
userjoin
(
String
user
,
WebSocket
conn
){
// AjaxJson j = new AjaxJson();
// j.put("type", "user_join");
// j.put("user", "<a onclick=\"toUserMsg('"+user+"');\">"+user+"</a>");
// MsgServerPool.sendMessage(j.getJsonStr()); //把当前用户加入到所有在线用户列表中
// String joinMsg = "{\"from\":\"[系统]\",\"content\":\""+user+"上线了\",\"timestamp\":"+new Date().getTime()+",\"type\":\"message\"}";
// MsgServerPool.sendMessage(joinMsg); //向所有在线用户推送当前用户上线的消息
// j = new AjaxJson();
// j.put("type", "get_online_user");
ChatServerPool
.
addUser
(
user
,
conn
);
//向连接池添加当前的连接对象
// j.put("list", MsgServerPool.getOnlineUser());
// MsgServerPool.sendMessageToUser(conn, j.getJsonStr()); //向当前连接发送当前在线用户的列表
}
/**
* 用户下线处理
* @param user
*/
public
void
userLeave
(
WebSocket
conn
){
String
user
=
ChatServerPool
.
getUserByKey
(
conn
);
boolean
b
=
ChatServerPool
.
removeUser
(
conn
);
//在连接池中移除连接
// if(b){
// AjaxJson j = new AjaxJson();
// j.put("type", "user_leave");
// j.put("user", "<a onclick=\"toUserMsg('"+user+"');\">"+user+"</a>");
// MsgServerPool.sendMessage(j.getJsonStr()); //把当前用户从所有在线用户列表中删除
// String joinMsg = "{\"from\":\"[系统]\",\"content\":\""+user+"下线了\",\"timestamp\":"+new Date().getTime()+",\"type\":\"message\"}";
// MsgServerPool.sendMessage(joinMsg); //向在线用户发送当前用户退出的消息
// }
}
/*public static void main( String[] args ) throws InterruptedException , IOException {
WebSocketImpl.DEBUG = false;
int port = 8667; //端口
ChatServer s = new ChatServer(port);
s.start();
//System.out.println( "服务器的端口" + s.getPort() );
}*/
}
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/websocket/onchat/ChatServerPool.java
0 → 100644
View file @
05beecd0
package
com.jeespring.common.websocket.onchat
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Set
;
import
org.java_websocket.WebSocket
;
public
class
ChatServerPool
{
private
static
final
Map
<
WebSocket
,
String
>
userconnections
=
new
HashMap
<
WebSocket
,
String
>();
/**
* 获取用户名
* @param session
*/
public
static
String
getUserByKey
(
WebSocket
conn
){
return
userconnections
.
get
(
conn
);
}
/**
* 获取WebSocket
* @param user
*/
public
static
WebSocket
getWebSocketByUser
(
String
user
){
Set
<
WebSocket
>
keySet
=
userconnections
.
keySet
();
synchronized
(
keySet
)
{
for
(
WebSocket
conn
:
keySet
)
{
String
cuser
=
userconnections
.
get
(
conn
);
if
(
cuser
.
equals
(
user
)){
return
conn
;
}
}
}
return
null
;
}
/**
* 向连接池中添加连接
* @param inbound
*/
public
static
void
addUser
(
String
user
,
WebSocket
conn
){
userconnections
.
put
(
conn
,
user
);
//添加连接
}
/**
* 获取所有的在线用户
* @return
*/
public
static
Collection
<
String
>
getOnlineUser
(){
// List<String> setUsers = new ArrayList<String>();
Collection
<
String
>
setUsers
=
userconnections
.
values
();
// for(String u:setUser){
// setUsers.add("<a onclick=\"toUserMsg('"+u+"');\">"+u+"</a>");
// }
return
setUsers
;
}
/**
* 移除连接池中的连接
* @param inbound
*/
public
static
boolean
removeUser
(
WebSocket
conn
){
if
(
userconnections
.
containsKey
(
conn
)){
userconnections
.
remove
(
conn
);
//移除连接
return
true
;
}
else
{
return
false
;
}
}
/**
* 向特定的用户发送数据
* @param user
* @param message
*/
public
static
void
sendMessageToUser
(
WebSocket
conn
,
String
message
){
if
(
null
!=
conn
&&
null
!=
userconnections
.
get
(
conn
)){
conn
.
send
(
message
);
}
}
/**
* 向所有的用户发送消息
* @param message
*/
public
static
void
sendMessage
(
String
message
){
Set
<
WebSocket
>
keySet
=
userconnections
.
keySet
();
synchronized
(
keySet
)
{
for
(
WebSocket
conn
:
keySet
)
{
String
user
=
userconnections
.
get
(
conn
);
if
(
user
!=
null
){
conn
.
send
(
message
);
}
}
}
}
}
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/common/websocket/utils/Constant.java
0 → 100644
View file @
05beecd0
package
com.jeespring.common.websocket.utils
;
public
class
Constant
{
public
static
final
String
_online_user_
=
"_online_user_"
;
public
static
final
String
_leave_user_
=
"_leave_user_"
;
public
static
final
String
_msg_
=
"_msg_"
;
}
JeeSpringCloud/jeespring-framework/src/main/java/com/jeespring/modules/act/ActConfig.java
0 → 100644
View file @
05beecd0
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/jeespring-framework/src/main/java/com/jeespring/modules/act/dao/ActDao.java
0 → 100644
View file @
05beecd0
/**
* Copyright © 2012-2016 <a href="https://gitee.com/JeeHuangBingGui/jeeSpringCloud">JeeSpring</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/jeespring-framework/src/main/java/com/jeespring/modules/act/entity/Act.java
0 → 100644
View file @
05beecd0
/**
* Copyright © 2012-2016 <a href="https://gitee.com/JeeHuangBingGui/jeeSpringCloud">JeeSpring</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 JeeSpring
* @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/jeespring-framework/src/main/java/com/jeespring/modules/act/rest/diagram/services/BaseProcessDefinitionDiagramLayoutResource.java
0 → 100644
View file @
05beecd0
/* 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/jeespring-framework/src/main/java/com/jeespring/modules/act/rest/diagram/services/ProcessDefinitionDiagramLayoutResource.java
0 → 100644
View file @
05beecd0
/* 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/jeespring-framework/src/main/java/com/jeespring/modules/act/rest/diagram/services/ProcessInstanceDiagramLayoutResource.java
0 → 100644
View file @
05beecd0
/* 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/jeespring-framework/src/main/java/com/jeespring/modules/act/rest/diagram/services/ProcessInstanceHighlightsResource.java
0 → 100644
View file @
05beecd0
/* 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/jeespring-framework/src/main/java/com/jeespring/modules/act/rest/editor/main/StencilsetRestResource.java
0 → 100644
View file @
05beecd0
/* 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/jeespring-framework/src/main/java/com/jeespring/modules/act/rest/editor/model/ModelEditorJsonRestResource.java
0 → 100644
View file @
05beecd0
/* 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
;
}
}
Prev
1
…
4
5
6
7
8
9
10
11
12
…
19
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