1 24 package org.riotfamily.website.generic.model.hibernate; 25 26 import java.util.ArrayList ; 27 import java.util.Collections ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.regex.Matcher ; 32 import java.util.regex.Pattern ; 33 34 import javax.servlet.http.HttpServletRequest ; 35 36 import org.apache.commons.logging.Log; 37 import org.apache.commons.logging.LogFactory; 38 import org.hibernate.Query; 39 import org.hibernate.SessionFactory; 40 import org.riotfamily.cachius.spring.CacheableController; 41 import org.riotfamily.common.collection.FlatMap; 42 import org.riotfamily.common.util.FormatUtils; 43 import org.riotfamily.riot.hibernate.support.HibernateSupport; 44 import org.riotfamily.riot.hibernate.support.HibernateUtils; 45 import org.riotfamily.website.cache.CacheInvalidationAdvice; 46 import org.riotfamily.website.generic.model.CacheableModelBuilder; 47 import org.springframework.beans.factory.BeanFactoryUtils; 48 import org.springframework.beans.factory.InitializingBean; 49 import org.springframework.context.ApplicationContext; 50 import org.springframework.context.ApplicationContextAware; 51 import org.springframework.util.ClassUtils; 52 import org.springframework.util.StringUtils; 53 54 55 60 public abstract class AbstractHqlModelBuilder extends HibernateSupport 61 implements CacheableModelBuilder, 62 ApplicationContextAware, InitializingBean { 63 64 public static final String CACHE_ETERNAL_STRING = "eternal"; 65 66 private static final Pattern PARAM_PATTERN = Pattern.compile("\\:([._\\w]+)"); 67 68 private Log log = LogFactory.getLog(AbstractHqlModelBuilder.class); 69 70 private ApplicationContext applicationContext; 71 72 protected String modelKey; 73 74 private String hql; 75 76 private ArrayList params = new ArrayList (); 77 78 private List parameterResolvers; 79 80 private boolean tagCacheItems = true; 81 82 private long timeToLive = CacheableController.CACHE_ETERNALLY; 83 84 public AbstractHqlModelBuilder() { 85 } 86 87 public AbstractHqlModelBuilder(SessionFactory sessionFactory) { 88 setSessionFactory(sessionFactory); 89 } 90 91 public void setApplicationContext(ApplicationContext applicationContext) { 92 this.applicationContext = applicationContext; 93 } 94 95 98 public void setModelKey(String modelKey) { 99 this.modelKey = modelKey; 100 } 101 102 protected String getModelKey(Query query) { 103 if (modelKey == null) { 104 modelKey = generateModelKey(query); 105 log.info("Generated model key is " + modelKey); 106 } 107 return modelKey; 108 } 109 110 protected String generateModelKey(Query query) { 111 Class clazz = getResultClass(query); 112 return StringUtils.uncapitalize(ClassUtils.getShortName(clazz)); 113 } 114 115 protected Class getResultClass(Query query) { 116 return query.getReturnTypes()[0].getReturnedClass(); 117 } 118 119 122 public void setHql(String hql) { 123 this.hql = hql; 124 } 125 126 protected String getHql() { 127 return this.hql; 128 } 129 130 134 public void setParameterResolvers(List parameterResolvers) { 135 this.parameterResolvers = parameterResolvers; 136 } 137 138 142 public void setTagCacheItems(boolean tagCacheItems) { 143 this.tagCacheItems = tagCacheItems; 144 } 145 146 149 public void setTtlPeriod(String timeToLive) { 150 if (!StringUtils.hasText(timeToLive)) { 151 return; 152 } 153 timeToLive = StringUtils.trimTrailingWhitespace(timeToLive); 154 if (timeToLive.equalsIgnoreCase(CACHE_ETERNAL_STRING)) { 155 this.timeToLive = CacheableController.CACHE_ETERNALLY; 156 } 157 else { 158 this.timeToLive = FormatUtils.parseMillis(timeToLive); 159 } 160 } 161 162 public void afterPropertiesSet() throws Exception { 163 if (getSessionFactory() == null) { 164 setSessionFactory((SessionFactory) 165 BeanFactoryUtils.beanOfTypeIncludingAncestors( 166 applicationContext, SessionFactory.class)); 167 } 168 169 if (parameterResolvers == null) { 170 parameterResolvers = Collections.EMPTY_LIST; 171 } 172 173 Matcher matcher = PARAM_PATTERN.matcher(hql); 174 while (matcher.find()) { 175 String param = matcher.group(1); 176 params.add(new Param(param, getParameterResolver(param))); 177 } 178 } 179 180 185 protected ParameterResolver getParameterResolver(String param) { 186 Iterator it = parameterResolvers.iterator(); 187 while (it.hasNext()) { 188 ParameterResolver resolver = (ParameterResolver) it.next(); 189 if (resolver.accept(param)) { 190 return resolver; 191 } 192 } 193 194 DefaultParameterResolver resolver = new DefaultParameterResolver(); 195 resolver.setParam(param); 196 return resolver; 197 } 198 199 206 public long getTimeToLive() { 207 return this.timeToLive; 208 } 209 210 217 public long getLastModified(HttpServletRequest request) { 218 return System.currentTimeMillis(); 219 } 220 221 public Map buildModel(final HttpServletRequest request) { 222 HibernateUtils.enableLiveModeFilterIfNecessary(getSession()); 223 Query query = createQuery(hql); 224 log.debug("Query: " + query.getQueryString()); 225 setParameters(query, request); 226 Object result = getResult(query); 227 if (tagCacheItems) { 228 tagResult(query, result, request); 229 } 230 FlatMap model = new FlatMap(); 231 model.put(getModelKey(query), result); 232 return model; 233 } 234 235 protected abstract Object getResult(Query query); 236 237 protected void tagResult(Query query, Object result, 238 HttpServletRequest request) { 239 240 } 241 242 protected void setParameters(Query query, HttpServletRequest request) { 243 Iterator it = params.iterator(); 244 while (it.hasNext()) { 245 Param param = (Param) it.next(); 246 Object value = param.getValue(request); 247 log.debug("Query parameter '" + param.name + "' = " + value); 248 query.setParameter(param.name, value); 249 } 250 } 251 252 public void appendCacheKey(StringBuffer key, HttpServletRequest request) { 253 Iterator it = params.iterator(); 254 while (it.hasNext()) { 255 Param param = (Param) it.next(); 256 param.appendToCacheKey(request, key); 257 } 258 } 259 260 private class Param { 261 262 private String name; 263 264 private ParameterResolver resolver; 265 266 Param (String name, ParameterResolver resolver) { 267 this.name = name; 268 this.resolver = resolver; 269 } 270 271 void appendToCacheKey(HttpServletRequest request, StringBuffer key) { 272 if (resolver.includeInCacheKey()) { 273 key.append(name).append('='); 274 key.append(getValue(request)).append(';'); 275 } 276 } 277 278 Object getValue(HttpServletRequest request) { 279 return resolver.getValue(request); 280 } 281 } 282 283 } | Popular Tags |