1 16 package org.apache.cocoon.portal.coplet.adapter.impl; 17 18 import java.io.UnsupportedEncodingException ; 19 import java.util.ArrayList ; 20 import java.util.Collections ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 24 import org.apache.avalon.framework.parameters.Parameterizable; 25 import org.apache.avalon.framework.parameters.Parameters; 26 import org.apache.avalon.framework.service.ServiceException; 27 import org.apache.avalon.framework.service.ServiceManager; 28 import org.apache.cocoon.ProcessingException; 29 import org.apache.cocoon.caching.Cache; 30 import org.apache.cocoon.caching.CachedResponse; 31 import org.apache.cocoon.components.sax.XMLByteStreamCompiler; 32 import org.apache.cocoon.components.sax.XMLByteStreamInterpreter; 33 import org.apache.cocoon.portal.PortalService; 34 import org.apache.cocoon.portal.coplet.CopletInstanceData; 35 import org.apache.cocoon.portal.event.CopletInstanceEvent; 36 import org.apache.cocoon.portal.event.impl.ChangeCopletInstanceAspectDataEvent; 37 import org.apache.cocoon.util.Deprecation; 38 import org.apache.cocoon.util.NetUtils; 39 import org.apache.excalibur.source.SourceValidity; 40 import org.xml.sax.ContentHandler ; 41 import org.xml.sax.SAXException ; 42 import org.xml.sax.ext.LexicalHandler ; 43 44 56 public class CachingURICopletAdapter 57 extends URICopletAdapter 58 implements Parameterizable { 59 60 61 public static final String CONFIGURATION_ENABLE_CACHING = "cache-enabled"; 62 63 64 public static final String CONFIGURATION_CACHE_GLOBAL= "cache-global"; 65 66 68 public static final String CONFIGURATION_CACHE_GLOBAL_USE_ATTRIBUTES= "cache-global-use-attributes"; 69 70 71 public static final String CONFIGURATION_IGNORE_SIZING_EVENTS = "ignore-sizing-events"; 72 73 74 public static final String CACHE = "cacheData"; 75 76 77 public static final String DO_NOT_CACHE = "doNotCache"; 78 79 83 public static final String PARAMETER_DISABLE_CACHING = "disable_caching"; 84 85 86 protected Boolean enableCaching = Boolean.TRUE; 87 88 89 protected Cache cache; 90 91 94 public void parameterize(Parameters parameters) { 95 if ( parameters.getParameter(PARAMETER_DISABLE_CACHING, null) != null ) { 96 Deprecation.logger.info("The 'disable_caching' parameter on the caching uri coplet adapter is deprecated. " 97 +"Use the configuration of the base coplet data instead."); 98 } 99 boolean disableCaching = parameters.getParameterAsBoolean(PARAMETER_DISABLE_CACHING, 100 !this.enableCaching.booleanValue()); 101 this.enableCaching = new Boolean (!disableCaching); 102 if ( this.getLogger().isInfoEnabled() ) { 103 this.getLogger().info(this.getClass().getName() + ": enable-caching=" + this.enableCaching); 104 } 105 } 106 107 110 public void service(ServiceManager manager) throws ServiceException { 111 super.service(manager); 112 this.cache = (Cache)this.manager.lookup(Cache.ROLE); 113 } 114 115 118 public void dispose() { 119 if ( this.manager != null ) { 120 this.manager.release(this.cache); 121 this.cache = null; 122 } 123 super.dispose(); 124 } 125 126 129 public void streamContent(CopletInstanceData coplet, ContentHandler contentHandler) 130 throws SAXException { 131 this.streamContent( coplet, 132 (String ) coplet.getCopletData().getAttribute("uri"), 133 contentHandler); 134 } 135 136 139 public void streamContent( final CopletInstanceData coplet, 140 final String uri, 141 final ContentHandler contentHandler) 142 throws SAXException { 143 boolean cachingEnabled = ((Boolean )this.getConfiguration(coplet, CONFIGURATION_ENABLE_CACHING, this.enableCaching)).booleanValue(); 145 boolean cacheGlobal = ((Boolean )this.getConfiguration(coplet, CONFIGURATION_CACHE_GLOBAL, Boolean.FALSE)).booleanValue(); 147 148 Object data = null; 149 if (cachingEnabled) { 151 if ( cacheGlobal ) { 152 final String key = this.getCacheKey(coplet, uri); 153 CachedResponse response = this.cache.get(key); 154 if (response != null ) { 155 data = response.getResponse(); 156 } 157 } else { 158 data = coplet.getTemporaryAttribute(CACHE); 159 } 160 } 161 if (data == null) { 162 if ( !cachingEnabled || coplet.getTemporaryAttribute(DO_NOT_CACHE) != null ) { 164 coplet.removeTemporaryAttribute(DO_NOT_CACHE); 165 if ( cacheGlobal ) { 166 final String key = this.getCacheKey(coplet, uri); 167 this.cache.remove(key); 168 } else { 169 coplet.removeTemporaryAttribute(CACHE); 170 } 171 super.streamContent(coplet, uri, contentHandler); 172 } else { 173 174 XMLByteStreamCompiler bc = new XMLByteStreamCompiler(); 175 176 super.streamContent(coplet, uri, bc); 177 data = bc.getSAXFragment(); 178 if (coplet.removeTemporaryAttribute(DO_NOT_CACHE) == null) { 179 if ( cacheGlobal ) { 180 CachedResponse response = new CachedResponse((SourceValidity[])null, (byte[])data); 181 try { 182 final String key = this.getCacheKey(coplet, uri); 183 this.cache.store(key, response); 184 } catch (ProcessingException pe) { 185 this.getLogger().warn("Exception during storing response into cache.", pe); 187 } 188 } else { 189 coplet.setTemporaryAttribute(CACHE, data); 190 } 191 } 192 } 193 } 194 if ( data != null ) { 196 XMLByteStreamInterpreter bi = new XMLByteStreamInterpreter(); 197 bi.setContentHandler(contentHandler); 198 if ( contentHandler instanceof LexicalHandler ) { 199 bi.setLexicalHandler((LexicalHandler )contentHandler); 200 } 201 bi.deserialize(data); 202 } 203 } 204 205 208 public void inform(CopletInstanceEvent e, PortalService service) { 209 if ( this.getLogger().isInfoEnabled() ) { 210 this.getLogger().info("CopletInstanceEvent " + e + " caught by CachingURICopletAdapter"); 211 } 212 this.handleCopletInstanceEvent(e); 213 super.inform(e, service); 214 } 215 216 219 public void handleCopletInstanceEvent(CopletInstanceEvent event) { 220 final CopletInstanceData coplet = (CopletInstanceData) event.getTarget(); 221 222 boolean ignoreSizing = ((Boolean )this.getConfiguration(coplet, CONFIGURATION_IGNORE_SIZING_EVENTS, Boolean.TRUE)).booleanValue(); 224 225 if ( !ignoreSizing || !isSizingEvent(event)) { 226 boolean cacheGlobal = ((Boolean )this.getConfiguration(coplet, CONFIGURATION_CACHE_GLOBAL, Boolean.FALSE)).booleanValue(); 228 if ( cacheGlobal ) { 229 final String key = this.getCacheKey(coplet, 230 (String ) coplet.getCopletData().getAttribute("uri")); 231 this.cache.remove(key); 232 } else { 233 coplet.removeTemporaryAttribute(CACHE); 234 } 235 } 236 } 237 238 241 protected boolean isSizingEvent(CopletInstanceEvent event) { 242 if ( event instanceof ChangeCopletInstanceAspectDataEvent ) { 243 if (((ChangeCopletInstanceAspectDataEvent)event).getAspectName().equals("size")) { 244 return true; 245 } 246 } 247 return false; 248 } 249 250 253 protected String getCacheKey(CopletInstanceData coplet, String uri) { 254 final Boolean useAttributes = (Boolean )this.getConfiguration(coplet, 255 CONFIGURATION_CACHE_GLOBAL_USE_ATTRIBUTES, 256 Boolean.FALSE); 257 if ( !useAttributes.booleanValue() ) { 258 return "coplet:" + coplet.getCopletData().getId() + '/' + uri; 259 } 260 final StringBuffer buffer = new StringBuffer ("coplet:"); 261 buffer.append(coplet.getCopletData().getId()); 262 buffer.append('/'); 263 buffer.append(uri); 264 boolean hasParams = false; 265 List keyList = new ArrayList (coplet.getAttributes().keySet()); 268 Collections.sort(keyList); 269 Iterator i = keyList.iterator(); 270 while ( i.hasNext() ) { 271 final Object name = i.next(); 272 final Object value = coplet.getAttribute(name.toString()); 273 if ( hasParams ) { 274 buffer.append('&'); 275 } else { 276 buffer.append('?'); 277 hasParams = true; 278 } 279 buffer.append(name.toString()); 280 buffer.append('='); 281 if ( value != null ) { 282 try { 283 buffer.append(NetUtils.encode(value.toString(), "utf-8")); 284 } catch (UnsupportedEncodingException ignore) { 285 } 287 } 288 } 289 keyList = new ArrayList (coplet.getTemporaryAttributes().keySet()); 291 Collections.sort(keyList); 292 i = keyList.iterator(); 293 while ( i.hasNext() ) { 294 final Object name = i.next(); 295 final Object value = coplet.getTemporaryAttribute(name.toString()); 296 if ( hasParams ) { 297 buffer.append('&'); 298 } else { 299 buffer.append('?'); 300 hasParams = true; 301 } 302 buffer.append(name.toString()); 303 buffer.append('='); 304 if ( value != null ) { 305 try { 306 buffer.append(NetUtils.encode(value.toString(), "utf-8")); 307 } catch (UnsupportedEncodingException ignore) { 308 } 310 } 311 } 312 return buffer.toString(); 313 } 314 } 315 | Popular Tags |