/* * Copyright 2010 The Ganshane Team. * * 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 corner.cache.services.impl; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.apache.commons.codec.digest.DigestUtils; import org.apache.tapestry5.ValueEncoder; import org.apache.tapestry5.ioc.Invocation; import org.apache.tapestry5.services.ValueEncoderSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; import corner.cache.annotations.CacheKeyParameter; import corner.cache.annotations.CacheNsParameter; import corner.cache.annotations.Cacheable; import corner.cache.services.CacheManager; import corner.cache.services.CacheStrategy; import corner.cache.services.CacheStrategySource; import corner.cache.services.CacheableDefinitionParser; import corner.cache.services.impl.CacheableDefine.Definition; import corner.cache.services.impl.CacheableDefine.Definition.Builder; import corner.orm.services.EntityService; /** * 针对缓存定义的解析 * @author <a href="mailto:jun.tsai@gmail.com">Jun Tsai</a> * @version $Revision$ * @since 3.1 */ public class CacheableDefinitionParserImpl implements CacheableDefinitionParser { private ValueEncoderSource valueEncoderSource; private CacheManager cacheManager; private CacheStrategySource source; private Logger logger = LoggerFactory.getLogger(CacheableDefinitionParserImpl.class); private EntityService entityService; public CacheableDefinitionParserImpl (ValueEncoderSource valueEncoderSource, CacheManager cacheManager, CacheStrategySource source, EntityService entityService ) { this.valueEncoderSource = valueEncoderSource; this.cacheManager = cacheManager; this.source = source; this.entityService =entityService; } /** * @see corner.cache.services.CacheableDefinitionParser#parseAsKey(org.apache.tapestry5.ioc.Invocation, java.lang.reflect.Method, corner.cache.services.CacheManager) */ public String parseAsKey(Invocation invocation,Method method){ Cacheable cacheable = method.getAnnotation(Cacheable.class); if(cacheable == null){ return null; } Definition define = null; //if (define == null) { // 如果没定义,则进行分析 Builder defineBuilder = CacheableDefine.Definition.newBuilder(); Annotation[][] parametersAnnotations = method .getParameterAnnotations(); for (int i = 0; i < parametersAnnotations.length; i++) { Annotation[] pa = parametersAnnotations[i]; for (Annotation a : pa) { if (a instanceof CacheKeyParameter) { defineBuilder.addParameterIndex(i); } } } define = defineBuilder.build(); // 得到缓存的参数 List<String> keyParameter=new ArrayList<String>(); Object pObj; Class pType; for (int i = 0; i < define.getParameterIndexCount(); i++) { int pIndex = define.getParameterIndex(i); pObj = invocation.getParameter(pIndex); pType = null; if(pObj!=null){ pType = entityService.getEntityClass(pObj); } if(pType == null){ pType = method.getParameterTypes()[pIndex]; } ValueEncoder encoder = valueEncoderSource.getValueEncoder(pType); keyParameter.add(encoder.toClient(pObj)); } //得到缓存的真正key String key=null; String keyFormat= cacheable.keyFormat(); logger.debug("key parameter:{}",keyParameter); if(!StringUtils.hasText(keyFormat)){ key = DigestUtils.shaHex(method.toString()+keyParameter.toString()); }else{ key =String.format(keyFormat, keyParameter.toArray(new Object[0])); } CacheStrategy strategy = this.source.findStrategy(cacheable.strategy()); CacheNsParameter[] nses = cacheable.namespaces(); if(strategy == null){ throw new RuntimeException("fail to find cache strategy instance!"); } return strategy.appendNamespace(cacheManager,cacheable.clazz(),nses,key,keyParameter.toArray()); } }