This commit is contained in:
Shaun Chyxion 2018-04-27 23:21:18 +08:00
parent 896d8cf61e
commit 60ed97a090
29 changed files with 284 additions and 320 deletions

41
pom.xml
View File

@ -28,8 +28,6 @@
<shiro.version>1.3.2</shiro.version>
<aspectj.version>1.8.10</aspectj.version>
<main.class>Main</main.class>
<maven.tomcat.port>8080</maven.tomcat.port>
<maven.tomcat.path>/</maven.tomcat.path>
</properties>
<scm>
@ -271,16 +269,6 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- / Spring Boot -->
<dependency>
<groupId>org.jdom</groupId>
@ -591,35 +579,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<version>3.0</version>
<webResources>
<resource>
<directory>src/main/webapp</directory>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>${maven.tomcat.port}</port>
<path>${maven.tomcat.path}</path>
<charset>utf-8</charset>
<uriEncoding>utf-8</uriEncoding>
<contextReloadable>false</contextReloadable>
<systemProperties>
<http.port>${maven.tomcat.port}</http.port>
<project.basedir>${project.basedir}</project.basedir>
</systemProperties>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>

@ -1 +0,0 @@
Subproject commit a7c690619e09fae1d48584794d68d1b8ee78c197

@ -1 +0,0 @@
Subproject commit a7c690619e09fae1d48584794d68d1b8ee78c197

View File

@ -468,9 +468,7 @@ public class CodeGenBaseTool {
col.put("isKey", keys.contains(colName));
col.put("isIndex", indexes.contains(colName));
col.put("col", colName);
col.put("name",
StringUtils.uncapitalize(
WordUtils.convertToCamelCase(colName, "_")));
col.put("name", WordUtils.toCamel(colName));
int size = rs.getInt("COLUMN_SIZE");
col.put("size", size);
String type = rs.getString("TYPE_NAME").toLowerCase();

View File

@ -1,7 +1,6 @@
package me.chyxion.tigon.codegen.service.support;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
/**
@ -19,17 +18,11 @@ public class MapperXmlCodeGen extends MapperCodeGen {
@Override
public String process(Map<String, Object> dataModel,
String module, String model) {
StringBuilder sbFilePath = new StringBuilder(resourcesDir)
.append("mybatis/mappers/");
if (StringUtils.isNotBlank(module)) {
sbFilePath.append(module).append("/");
}
sbFilePath.append(dataModel.get("minusJoinedModelName")).append("-mapper.xml");
return render(new CodeGenArgs(
CodeGenArgs.TARGET_MAPPER_XML,
"/codegen/mapper-xml.ftl",
dataModel,
sbFilePath.toString()));
CodeGenArgs.TARGET_MAPPER_XML,
"/codegen/mapper-xml.ftl",
dataModel,
codeDir + dataModel.get("pkgDir") +
"/mapper/" + model + "Mapper.xml"));
}
}

View File

@ -1,6 +1,7 @@
package me.chyxion.tigon.form;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.validation.annotation.NotNullOrBlank;
/**
@ -11,28 +12,10 @@ import me.chyxion.tigon.validation.annotation.NotNullOrBlank;
* Oct 8, 2016 6:26:19 PM
*/
@Getter
@Setter
public class FC2<CreatorId> extends FC1 {
private static final long serialVersionUID = 1L;
private transient boolean __lock = true;
@NotNullOrBlank
protected CreatorId createdBy;
/**
* set created by
* @param createdBy created by
*/
public void setCreatedBy(final CreatorId createdBy) {
if (!__lock) {
this.createdBy = createdBy;
__lock = true;
}
}
/**
* unlock set created by
*/
public void unlock() {
__lock = false;
}
}

View File

@ -2,7 +2,6 @@ package me.chyxion.tigon.form;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotNull;
import me.chyxion.tigon.format.annotation.EmptyToNull;
/**
@ -18,8 +17,7 @@ public class FU1<Id>
extends FU0<Id> {
private static final long serialVersionUID = 1L;
@NotNull
protected Boolean enabled;
protected boolean enabled = true;
@EmptyToNull
protected String note;
}

View File

@ -12,29 +12,11 @@ import me.chyxion.tigon.validation.annotation.NotNullOrBlank;
* Oct 8, 2016 6:26:36 PM
*/
@Getter
@Setter
public class FU2<EditorId, Id>
extends FU1<Id> {
private static final long serialVersionUID = 1L;
private transient boolean __lock = true;
@NotNullOrBlank
private EditorId updatedBy;
/**
* set updated by
* @param updatedBy updated by
*/
public void setUpdatedBy(final EditorId updatedBy) {
if (!__lock) {
this.updatedBy = updatedBy;
__lock = true;
}
}
/**
* unlock set created by
*/
public void unlock() {
__lock = false;
}
}

View File

@ -96,4 +96,13 @@ public class WordUtils {
}
return strRtn;
}
/**
* convert underline word to
* @param word
* @return
*/
public static String toCamel(final String word) {
return StringUtils.uncapitalize(convertToCamelCase(word.toLowerCase(), "_"));
}
}

View File

@ -25,6 +25,15 @@
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<artifactId>commons-codec</artifactId>
<groupId>commons-codec</groupId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>

View File

@ -1,11 +1,12 @@
package me.chyxion.tigon.mybatis.cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.util.Assert;
import java.util.concurrent.locks.ReadWriteLock;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.HashOperations;
/**
* @version 0.0.1
@ -14,29 +15,24 @@ import org.springframework.data.redis.core.ValueOperations;
* chyxion@163.com <br>
* Feb 23, 2016 6:03:39 PM
*/
@Slf4j
public final class RedisCache implements Cache {
private static final Logger log =
LoggerFactory.getLogger(RedisCache.class);
private String id;
private RedisTemplate<String, Object> redisTpl;
private ValueOperations<String, Object> valueOp;
private RedisCacheConfig config;
private final String id;
private final RedisTemplate<String, Object> redisTpl;
private final HashOperations<String, String, Object> hashOp;
private final RedisCacheConfig config;
/**
* construct cache
* @param id cache id
*/
public RedisCache(String id) {
if (id == null) {
throw new IllegalArgumentException(
"Cache Instance ID Could Not Be Null");
}
log.info("Create Redis Cache [{}].", id);
public RedisCache(final String id) {
Assert.hasText(id, "Redis cache instance id could not be null");
log.info("Create redis cache [{}].", id);
this.id = id;
config = RedisCacheConfig.getInstance();
redisTpl = config.getRedisTpl();
valueOp = redisTpl.opsForValue();
hashOp = redisTpl.opsForHash();
}
/**
@ -50,24 +46,25 @@ public final class RedisCache implements Cache {
* {@inheritDoc}
*/
public int getSize() {
log.debug("Get Cache [{}] Size.", id);
return redisTpl.keys(prefixedKey("*")).size();
final Long size = hashOp.size(id);
log.info("Get redis cache [{}] size [{}].", id, size);
return size.intValue();
}
/**
* {@inheritDoc}
*/
public void putObject(final Object key, final Object value) {
log.debug("Put Object Key [{}], Value [{}].", key, value);
valueOp.set(prefixedKey(key), value);
log.debug("Put redis cache [{}] object key [{}], value [{}].", id, key, value);
hashOp.put(id, keyMd5(key), value);
}
/**
* {@inheritDoc}
*/
public Object getObject(final Object key) {
Object value = valueOp.get(prefixedKey(key));
log.debug("Get Object Key [{}], Value [{}].", key, value);
final Object value = hashOp.get(id, keyMd5(key));
log.debug("Get redis cache object key [{}], value [{}].", key, value);
return value;
}
@ -75,17 +72,16 @@ public final class RedisCache implements Cache {
* {@inheritDoc}
*/
public Object removeObject(final Object key) {
log.debug("Remove Object Key [{}].", key);
redisTpl.delete(prefixedKey(key));
return 1;
log.info("Remove redis cache [{}] object key [{}].", id, key);
return hashOp.delete(id, keyMd5(key));
}
/**
* {@inheritDoc}
*/
public void clear() {
log.debug("Clear Cache Key [{}].", id);
redisTpl.delete(redisTpl.keys(prefixedKey("*")));
log.info("Clear redis cache [{}].", id);
redisTpl.delete(id);
}
/**
@ -101,7 +97,7 @@ public final class RedisCache implements Cache {
*/
@Override
public String toString() {
return "Redis Cache [" + id + "]";
return "Redis cache [" + id + "]";
}
// --
@ -112,14 +108,9 @@ public final class RedisCache implements Cache {
* @param key cache key
* @return prefixed key
*/
String prefixedKey(Object key) {
return prefix() + String.valueOf(key);
}
/**
* @return cache prefix
*/
String prefix() {
return id + ":";
private String keyMd5(Object key) {
final String md5Hex = DigestUtils.md5Hex(key instanceof String ? (String) key : String.valueOf(key));
log.debug("Get redis cache [{}] key [{}] md5 hex [{}].", id, key, md5Hex);
return md5Hex;
}
}

View File

@ -140,6 +140,13 @@ public interface BaseMapper<PrimaryKey, Model extends BaseModel<PrimaryKey>> {
*/
int delete(@NotNull @Param(PARAM_SEARCH_KEY) PrimaryKey primaryKey);
/**
* find one by search
* @param search search
* @return true if exists rows
*/
boolean exists(@Param(PARAM_SEARCH_KEY) Search search);
/**
* find one by search
* @param search search

View File

@ -0,0 +1,29 @@
package me.chyxion.tigon.mybatis;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* 14/10/2017 10:43 PM
*/
public class ExistsXmlProcessor extends AbstractOnMissingCreateProcessor {
/**
* {@inheritDoc}
*/
@Override
protected String missingXPathExpression() {
return "/mapper/select[@id='exists']";
}
/**
* {@inheritDoc}
*/
@Override
protected Element elementToAppend(Class<BaseMapper<?, ?>> mapperClass, Document doc) {
return appendIncludeEl(doc,
createSelectEl(doc, "exists", "boolean"), "Tigon.exists");
}
}

View File

@ -85,13 +85,13 @@ class KeyGenInterceptor implements Interceptor {
Object paramObj = boundSql.getParameterObject();
if (paramObj instanceof MapperMethod.ParamMap) {
@SuppressWarnings("unchecked")
MapperMethod.ParamMap<Object> paramMap =
(MapperMethod.ParamMap<Object>) paramObj;
MapperMethod.ParamMap<Object> paramMap =
(MapperMethod.ParamMap<Object>) paramObj;
if (paramMap.containsKey(BaseMapper.PARAM_MODEL_KEY) ||
paramMap.containsKey(BaseMapper.PARAM_MODELS_KEY)) {
KeyGenerator keygen = mappedStatement.getKeyGenerator();
if (keygen.getClass().equals(Jdbc3KeyGenerator.class)) {
log.debug("Replace JDBC3 Key Generator.");
log.info("Replace JDBC3 key generator.");
SystemMetaObject.forObject(mappedStatement)
.setValue("keyGenerator",
new Jdbc3KeyGen(keygen));

View File

@ -46,6 +46,7 @@ public class TigonSqlSessionFactoryBean extends SqlSessionFactoryBean {
MAPPER_XML_PROCESSORS.add(new PrimaryKeyXmlProcessor());
MAPPER_XML_PROCESSORS.add(new ColsXmlProcessor());
MAPPER_XML_PROCESSORS.add(new InsertXmlProcessor());
MAPPER_XML_PROCESSORS.add(new ExistsXmlProcessor());
MAPPER_XML_PROCESSORS.add(new FindXmlProcessor());
MAPPER_XML_PROCESSORS.add(new ListXmlProcessor());
MAPPER_XML_PROCESSORS.add(new CountXmlProcessor());
@ -126,7 +127,7 @@ public class TigonSqlSessionFactoryBean extends SqlSessionFactoryBean {
}
@SuppressWarnings("unchecked")
private Class<BaseMapper<?, ?>> getMapperClass(String name) {
private Class<BaseMapper<?, ?>> getMapperClass(String name) {
Class<BaseMapper<?, ?>> mapperClassRtn = null;
try {
Class<?> classFound = ClassUtils.forName(name,

View File

@ -183,6 +183,18 @@
</sql>
<!--/ Delete -->
<!-- Exists -->
<sql id="exists">
select
<![CDATA[
if (count(*) > 0, 1, 0)
]]>
from
<include refid="table" />
<include refid="Tigon.searchForCount" />
</sql>
<!--/ Exists -->
<!-- Find One -->
<sql id="find">
select

View File

@ -16,10 +16,4 @@ public interface PubProducer {
* @param message message
*/
void publish(String topic, Object message);
/**
* @param topic topic
* @param message message
*/
void publish(String topic, String message);
}

View File

@ -1,10 +1,9 @@
package me.chyxion.tigon.redis.pub.support;
import me.chyxion.tigon.redis.pub.PubProducer;
import me.chyxion.tigon.redis.util.PubSubUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
* @version 0.0.1
@ -18,30 +17,22 @@ public class PubProducerSupport
@Autowired
private RedisTemplate<String, Object> redisTpl;
@Autowired
private StringRedisTemplate strRedisTpl;
private RedisTemplate<String, String> strRedisTpl;
/**
* {@inheritDoc}
*/
@Override
public void publish(String topic, Object message) {
publish(redisTpl, topic, message);
}
/**
* {@inheritDoc}
*/
@Override
public void publish(String topic, String message) {
publish(strRedisTpl, topic, message);
}
// --
// private methods
private <T> void publish(
RedisTemplate<String, T> redisTpl, String topic, T message) {
redisTpl.opsForList().rightPush(topic + PUB_QUEUE_SUFFIX, message);
public void publish(final String topic, final Object message) {
if (message != null) {
if (message instanceof CharSequence) {
strRedisTpl.opsForList().rightPush(PubSubUtils.queueKey(topic),
String.valueOf(message));
}
else {
redisTpl.opsForList().rightPush(PubSubUtils.queueKey(topic), message);
}
}
strRedisTpl.convertAndSend(MESSAGE_CHANEL, topic);
}
}

View File

@ -0,0 +1,20 @@
package me.chyxion.tigon.redis.util;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Dec 24, 2017 10:54 AM
*/
public class PubSubUtils {
public static final String QUEUE_PREFIX = "__TIGON_REDIS_PUB__";
public static final String MESSAGE_CHANEL = "__TIGON_REDIS_PUB__";
/**
* return topic queue
* @param topic topic
* @return topic queue
*/
public static String queueKey(final String topic) {
return QUEUE_PREFIX + ":" + topic;
}
}

View File

@ -1,9 +1,8 @@
package me.chyxion.tigon.service;
import java.util.List;
import java.util.function.Function;
import me.chyxion.tigon.mybatis.Search;
import javax.validation.constraints.Min;
import me.chyxion.tigon.mybatis.Search;
import me.chyxion.tigon.model.BaseModel;
import me.chyxion.tigon.model.ViewModel;
import me.chyxion.tigon.model.ListResult;
@ -90,14 +89,14 @@ public interface BaseQueryService<PrimaryKey,
* scan model of all
* @param scanner scanner
*/
Model scan(@NotNull Function<Model, Boolean> scanner);
Model scan(@NotNull Scanner<Model> scanner);
/**
* scan model by search
* @param search search
* @param scanner scanner
*/
Model scan(Search search, @NotNull Function<Model, Boolean> scanner);
Model scan(Search search, @NotNull Scanner<Model> scanner);
/**
* scan model by search
@ -105,11 +104,15 @@ public interface BaseQueryService<PrimaryKey,
* @param search search
* @param scanner scanner
*/
Model scan(@Min(1) int batchSize, Search search, @NotNull Function<Model, Boolean> scanner);
Model scan(@Min(1) int batchSize, Search search, @NotNull Scanner<Model> scanner);
Model scan(@Min(1) int batchSize,
Search search,
@NotNull Function<Search, List<Model>> dataQuerier,
@NotNull Function<Search, Integer> countQuerier,
@NotNull Function<Model, Boolean> scanner);
interface Scanner<T> {
/**
* scan model
* @param model model
* @return false to break
*/
boolean found(T model);
}
}

View File

@ -1,19 +1,13 @@
package me.chyxion.tigon.service.support;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.*;
import lombok.extern.slf4j.Slf4j;
import me.chyxion.tigon.model.BaseModel;
import me.chyxion.tigon.mybatis.Search;
import me.chyxion.tigon.model.BaseModel;
import me.chyxion.tigon.model.ViewModel;
import me.chyxion.tigon.mybatis.BaseMapper;
import javax.validation.constraints.NotNull;
import org.apache.commons.lang3.StringUtils;
import me.chyxion.tigon.service.BaseCrudService;
import org.hibernate.validator.constraints.NotEmpty;
import me.chyxion.tigon.validation.annotation.NotNullOrBlank;
import org.springframework.transaction.annotation.Transactional;
/**
@ -52,10 +46,7 @@ public class BaseCrudServiceSupport
*/
@Override
public ViewModel<Model> create(Model model) {
beforeInsert(model);
mapper.insert(model);
afterInsert(model);
return toViewModel(model);
return create(Arrays.asList(model)).iterator().next();
}
/**
@ -63,10 +54,17 @@ public class BaseCrudServiceSupport
*/
@Override
@Transactional
public Collection<ViewModel<Model>> create(@NotEmpty Collection<Model> models) {
List<ViewModel<Model>> viewModels = new ArrayList<ViewModel<Model>>(models.size());
public Collection<ViewModel<Model>> create(Collection<Model> models) {
for (final Model model : models) {
model.beforeInsert();
beforeInsert(model);
}
mapper.insert(models);
final List<ViewModel<Model>> viewModels =
new ArrayList<>(models.size());
for (Model model : models) {
viewModels.add(create(model));
afterInsert(model);
viewModels.add(toViewModel(model));
}
return viewModels;
}
@ -87,7 +85,7 @@ public class BaseCrudServiceSupport
*/
@Override
@Transactional
public int update(@NotNull Model model, @NotNull Search search) {
public int update(Model model, Search search) {
return mapper.update(model, search);
}
@ -95,7 +93,7 @@ public class BaseCrudServiceSupport
* {@inheritDoc}
*/
@Override
public int update(@NotEmpty Map<String, ?> model, @NotNullOrBlank PrimaryKey primaryKey) {
public int update(Map<String, ?> model, PrimaryKey primaryKey) {
return mapper.update(model, primaryKey);
}
@ -104,7 +102,7 @@ public class BaseCrudServiceSupport
*/
@Override
@Transactional
public int update(@NotEmpty Map<String, ?> model, @NotNull Search search) {
public int update(Map<String, ?> model, Search search) {
return mapper.update(model, search);
}

View File

@ -2,9 +2,8 @@ package me.chyxion.tigon.service.support;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import java.util.function.Function;
import me.chyxion.tigon.mybatis.Search;
import me.chyxion.tigon.model.BaseModel;
import me.chyxion.tigon.mybatis.Search;
import me.chyxion.tigon.model.ViewModel;
import me.chyxion.tigon.model.ListResult;
import me.chyxion.tigon.mybatis.BaseMapper;
@ -25,7 +24,7 @@ public class BaseQueryServiceSupport
extends BaseServiceSupport<PrimaryKey, Model, Mapper>
implements BaseQueryService<PrimaryKey, Model> {
@Value("${default.query.batch.size:32}")
@Value("${default.query.batch.size:256}")
private int scanBatchSize;
/**
@ -33,7 +32,7 @@ public class BaseQueryServiceSupport
*/
@Override
public Model find(PrimaryKey primaryKey) {
log.debug("Find Model By PrimaryKey [{}].", primaryKey);
log.debug("Find model by primary key [{}].", primaryKey);
return mapper.find(primaryKey);
}
@ -42,7 +41,7 @@ public class BaseQueryServiceSupport
*/
@Override
public Model find(Search search) {
log.debug("Find Model By Search [{}].", search);
log.debug("Find model by search [{}].", search);
return mapper.find(search);
}
@ -51,7 +50,7 @@ public class BaseQueryServiceSupport
*/
@Override
public List<Model> list(Search search) {
log.debug("List Models By Search [{}].", search);
log.debug("List models by search [{}].", search);
return mapper.list(search);
}
@ -60,8 +59,8 @@ public class BaseQueryServiceSupport
*/
@Override
public ListResult<Model> listPage(Search search) {
log.debug("List Models Page By Search [{}].", search);
return new ListResult<Model>(list(search), count(search));
log.debug("LIST MODELS PAGE BY SEARCH [{}].", search);
return new ListResult<>(list(search), count(search));
}
/**
@ -78,7 +77,7 @@ public class BaseQueryServiceSupport
*/
@Override
public ViewModel<Model> findViewModel(Search search) {
log.debug("Find View Model By Search [{}].", search);
log.debug("Find view model by search [{}].", search);
Model model = find(search);
return model != null ? toViewModel(model) : null;
}
@ -88,7 +87,7 @@ public class BaseQueryServiceSupport
*/
@Override
public int count(Search search) {
log.debug("Count Model By Search [{}].", search);
log.debug("Count model by search [{}].", search);
return mapper.count(search);
}
@ -97,7 +96,7 @@ public class BaseQueryServiceSupport
*/
@Override
public List<ViewModel<Model>> listViewModels(Search search) {
log.debug("List View Models By Search [{}].", search);
log.debug("List view models by search [{}].", search);
return toViewModel(list(search));
}
@ -107,8 +106,8 @@ public class BaseQueryServiceSupport
@Override
public ListResult<ViewModel<Model>> listViewModelsPage(
Search search) {
log.debug("List View Models Page By Search [{}].", search);
return new ListResult<ViewModel<Model>>(
log.debug("List view models page by search [{}].", search);
return new ListResult<>(
listViewModels(search),
count(search));
}
@ -117,7 +116,7 @@ public class BaseQueryServiceSupport
* {@inheritDoc}
*/
@Override
public Model scan(Function<Model, Boolean> scanner) {
public Model scan(Scanner<Model> scanner) {
return scan(null, scanner);
}
@ -125,7 +124,7 @@ public class BaseQueryServiceSupport
* {@inheritDoc}
*/
@Override
public Model scan(Search search, Function<Model, Boolean> scanner) {
public Model scan(Search search, Scanner<Model> scanner) {
return scan(scanBatchSize(), search, scanner);
}
@ -133,37 +132,25 @@ public class BaseQueryServiceSupport
* {@inheritDoc}
*/
@Override
public Model scan(int batchSize, Search search, Function<Model, Boolean> scanner) {
return scan(batchSize, search, this::list, this::count, scanner);
}
/**
* {@inheritDoc}
*/
@Override
public Model scan(final int batchSize,
Search search,
final Function<Search, List<Model>> dataQuerier,
final Function<Search, Integer> countQuerier,
final Function<Model, Boolean> scanner) {
public Model scan(int batchSize, Search search, Scanner<Model> scanner) {
log.info("Scan model by search [{}].", search);
int total = countQuerier.apply(search);
int total = count(search);
if (total > 0) {
if (search == null) {
log.debug("Scan search is null, use default.");
search = new Search();
}
for (int start = 0; start < total; start += batchSize) {
for (Model model : dataQuerier.apply(
search.offset(start)
.limit(Math.min(batchSize, total - start)))) {
if (scanner.apply(model)) {
log.info("Model [{}] found by scanner, stop scan.", model);
for (Model model : list(
search.offset(start)
.limit(Math.min(batchSize, total - start)))) {
if (scanner.found(model)) {
log.info("Model [{}] found by scanner.", model);
return model;
}
}
}
log.info("Scan completed, no matched model found by scanner.");
log.debug("No matched model found by scanner.");
}
else {
log.info("No model to scan by search [{}].", search);

View File

@ -44,7 +44,7 @@ public class DefaultWebSessionManagerExt extends DefaultWebSessionManager {
sessionListeners = new LinkedList<SessionListener>();
}
else {
log.info("SessionListeners [{}] Found.", sessionListeners);
log.info("Session listeners [{}] found.", sessionListeners);
}
setSessionListeners(sessionListeners);
}
@ -66,7 +66,7 @@ public class DefaultWebSessionManagerExt extends DefaultWebSessionManager {
writeSessionIdCookie(sessionId, request, response);
}
else {
log.debug("Session ID cookie is disabled. No cookie has been set for new session with id [{}]", sessionId);
log.debug("Session id cookie is disabled. no cookie has been set for new session with id [{}]", sessionId);
}
request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
@ -79,14 +79,14 @@ public class DefaultWebSessionManagerExt extends DefaultWebSessionManager {
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
Serializable sessionId = null;
if (sessionIdManager != null) {
log.debug("Get Custom Session ID From Custom Session Manager.");
log.debug("Get custom session id from custom session manager.");
sessionId = sessionIdManager.read(
(HttpServletRequest) request,
(HttpServletResponse) response,
new SimpleCookie(getSessionIdCookie()));
}
if (sessionId == null) {
log.debug("No Custom Session ID Found From Custom Session Manager, Get Session Id From Cookie.");
log.debug("No custom session id found from custom session manager, get session id from cookie.");
sessionId = super.getSessionId(request, response);
}
return sessionId;
@ -96,21 +96,21 @@ public class DefaultWebSessionManagerExt extends DefaultWebSessionManager {
// private methods
void writeSessionIdCookie(Serializable currentId, HttpServletRequest request, HttpServletResponse response) {
Assert.notNull(currentId, "sessionId Cannot Be Null When Persisting For Subsequent Requests");
Assert.notNull(currentId, "Session id cannot be null when persisting for subsequent requests");
String sessionId = currentId.toString();
// copy cookie template
Cookie cookie = new SimpleCookie(getSessionIdCookie());
cookie.setValue(sessionId);
if (sessionIdManager != null) {
if (sessionIdManager.write(request, response, cookie)) {
log.info("Custom Session ID Mananger Write Session ID Cookie [{}] For Session [{}].", cookie, sessionId);
log.info("Custom session id manager write session id cookie [{}] for session [{}].", cookie, sessionId);
return;
}
else {
log.info("Custom Session ID Mananger Dose Not Write Session ID Cookie [{}] For Session [{}].", cookie, sessionId);
log.info("Custom session id manager dose not write session id cookie [{}] for session [{}].", cookie, sessionId);
}
}
log.info("Default Write Session ID Cookie [{}] For Session [{}].", cookie, sessionId);
log.info("Default write session id cookie [{}] for session [{}].", cookie, sessionId);
cookie.saveTo(request, response);
}
}

View File

@ -1,12 +1,8 @@
package me.chyxion.tigon.shiro;
import javax.servlet.Filter;
import static javax.servlet.DispatcherType.*;
import org.springframework.context.annotation.Bean;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
/**
@ -18,25 +14,13 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean;
public class TigonShiroConfig {
@Bean
public FilterRegistrationBean someFilterRegistration(
@Qualifier("shiroFilter") ShiroFilterFactoryBean filterFactoryBean) throws Exception {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setAsyncSupported(true);
registration.addUrlPatterns("/*");
registration.addInitParameter("targetFilterLifecycle", "true");
registration.setEnabled(true);
registration.setName("shiroFilter");
registration.setOrder(Integer.MAX_VALUE);
// registration.setOrder(0);
registration.setDispatcherTypes(REQUEST, FORWARD, INCLUDE, ERROR);
DelegatingFilterProxy filterProxy =
new DelegatingFilterProxy((Filter) filterFactoryBean.getObject());
filterProxy.setTargetFilterLifecycle(true);
filterProxy.setTargetBeanName("shiroFilter");
registration.setFilter(filterProxy);
return registration;
public FilterRegistrationBean shiroFilterRegistrationBean() {
final FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
// Servlet container manage filter lifecycle
filterRegistration.addInitParameter("targetFilterLifecycle", "true");
filterRegistration.setEnabled(true);
filterRegistration.addUrlPatterns("/*");
return filterRegistration;
}
}

View File

@ -1,12 +1,11 @@
package me.chyxion.tigon.webmvc;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
/**
* JSON View
@ -83,6 +82,23 @@ public class JSONView extends FastJsonJsonView {
return dataResp;
}
/**
* Response json for any client accepts media
* @return content type
*/
@Override
public String getContentType() {
return "*/*";
}
/**
* {@inheritDoc}
*/
@Override
protected void setResponseContentType(HttpServletRequest request, HttpServletResponse response) {
response.setContentType(DEFAULT_CONTENT_TYPE);
}
private JSONViewDataModel buildDataModel(Map<String, Object> model) {
log.debug("Build Data Model From Map Model.");
Object objData = null;

View File

@ -3,13 +3,10 @@ package me.chyxion.tigon.webmvc;
import lombok.Getter;
import java.util.Map;
import java.util.HashMap;
import me.chyxion.tigon.model.Mappable;
/**
* @version 0.0.4
* @since 0.0.1
* @author Donghuang <br>
* donghuang@wacai.com <br>
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Sep 21, 2014 8:32:06 PM
*/
public class JSONViewDataModel {
@ -91,38 +88,22 @@ public class JSONViewDataModel {
*/
@SuppressWarnings("unchecked")
public Map<String, Object> toMap(
final String successKey,
final String dataKey,
final String codeKey,
final String messageKey) {
final String successKey,
final String dataKey,
final String codeKey,
final String messageKey) {
Map<String, Object> mapData = null;
if (data instanceof Map) {
mapData = (Map<String, Object>) data;
}
else if (data instanceof Mappable) {
mapData = ((Mappable) data).toMap();
}
else {
mapData = new HashMap<String, Object>();
if (data != null) {
mapData.put(dataKey, data);
}
}
// attrs
final Map<String, Object> mapData = new HashMap<>();
if (attrs != null) {
mapData.putAll(attrs);
}
// success
if (!mapData.containsKey(successKey)) {
mapData.put(successKey, success);
if (!success) {
mapData.put(messageKey, getMessageOrExceptionMessage());
}
if (data != null) {
mapData.put(dataKey, data);
}
// code
if (!mapData.containsKey(codeKey)) {
mapData.put(codeKey, code);
mapData.put(successKey, success);
mapData.put(codeKey, code);
if (!success) {
mapData.put(messageKey, getMessageOrExceptionMessage());
}
return mapData;
}

View File

@ -1,17 +1,23 @@
package me.chyxion.tigon.webmvc;
import java.io.File;
import org.slf4j.Logger;
import java.util.Arrays;
import java.net.URLEncoder;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import java.util.Collection;
import lombok.extern.slf4j.Slf4j;
import me.chyxion.tigon.model.Mappable;
import org.springframework.util.ClassUtils;
import org.springframework.http.MediaType;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpHeaders;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.Resource;
import org.apache.commons.lang3.CharEncoding;
import org.springframework.http.ResponseEntity;
import org.springframework.core.MethodParameter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.http.converter.ResourceHttpMessageConverter;
@ -19,19 +25,23 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 19, 2017 11:32:22
* @version 0.0.4
* @since 0.0.1
* @author Donghuang <br>
* donghuang@wacai.com <br>
* Jul 16, 2014 10:03:15 PM
*/
@Slf4j
public class TigonReturnValueHandler
implements HandlerMethodReturnValueHandler {
private static final Logger log =
LoggerFactory.getLogger(TigonReturnValueHandler.class);
@Value("${tigon.webmvc.jsonview.null-jsonarray-as-empty:true}")
private boolean writeNullJsonArrayAsEmpty;
@Autowired
private JSONViewConfig jsonViewConfig;
private HttpEntityMethodProcessor httpEntityProcessor =
new HttpEntityMethodProcessor(Arrays.<HttpMessageConverter<?>>asList(
new HttpEntityMethodProcessor(Arrays.asList(
new ResourceHttpMessageConverter()));
/**
@ -50,18 +60,31 @@ public class TigonReturnValueHandler
MethodParameter returnType,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) throws Exception {
log.debug("Return Value Handler, Handle Return Value [{}], Return Type [{}].",
returnValue, returnType);
log.debug("Return value handler, handle return value [{}], return type [{}].",
returnValue, returnType);
if (!handleResource(returnValue,
returnType, mavContainer, webRequest)) {
JSONViewDataModel model = null;
final JSONViewDataModel model;
if (returnValue instanceof JSONViewDataModel) {
log.debug("Controller Return Value Is JSONViewDataModel, Return.");
log.debug("Controller return value is JSONViewDataModel, return.");
model = (JSONViewDataModel) returnValue;
}
else if (returnValue instanceof Mappable) {
log.debug("Controller return value is mappable, call #toMap.");
model = new JSONViewDataModel(((Mappable) returnValue).toMap());
}
else {
log.debug("Wrap Controller Return Value To Data Model.");
model = new JSONViewDataModel(returnValue);
final Class<?> returnTypeClass = returnType.getMethod().getReturnType();
if (writeNullJsonArrayAsEmpty && returnValue == null &&
(returnTypeClass.isArray() ||
ClassUtils.isAssignable(Collection.class, returnTypeClass))) {
log.info("Wrap controller return null collection to data model.");
model = new JSONViewDataModel(new Object[0]);
}
else {
log.debug("Wrap controller return value to data model.");
model = new JSONViewDataModel(returnValue);
}
}
mavContainer.setView(new JSONView(model, jsonViewConfig));
}
@ -121,7 +144,7 @@ public class TigonReturnValueHandler
headers.setContentType(
MediaType.valueOf(resourceModel.getContentType()));
headers.setContentLength(resourceModel.getContentLength());
entity = new ResponseEntity<Resource>(
entity = new ResponseEntity<>(
resourceModel.getResource(), headers, HttpStatus.OK);
}
boolean handled = false;

View File

@ -1,7 +1,6 @@
package me.chyxion.tigon.webmvc.formatter;
import java.util.Locale;
import java.text.ParseException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.format.Formatter;
@ -26,7 +25,7 @@ public class EmptyToNullFormatter implements Formatter<String> {
* {@inheritDoc}
*/
@Override
public String parse(String text, Locale locale) throws ParseException {
public String parse(String text, Locale locale) {
return StringUtils.isNotEmpty(text) ? text : null;
}
}

View File

@ -1,7 +1,6 @@
package me.chyxion.tigon.webmvc.formatter;
import java.util.Locale;
import java.text.ParseException;
import org.springframework.format.Formatter;
import org.apache.commons.lang3.StringUtils;
@ -24,7 +23,7 @@ public class TrimFormatter implements Formatter<String> {
* {@inheritDoc}
*/
@Override
public String parse(String text, Locale locale) throws ParseException {
return StringUtils.isNotEmpty(text) ? text.trim() : null;
public String parse(String text, Locale locale) {
return StringUtils.trim(text);
}
}