1 16 package org.apache.cocoon.webapps.session.components; 17 18 import java.io.IOException ; 19 import java.util.HashMap ; 20 import java.util.Map ; 21 22 import org.apache.avalon.framework.activity.Disposable; 23 import org.apache.avalon.framework.component.Component; 24 import org.apache.avalon.framework.context.Context; 25 import org.apache.avalon.framework.context.ContextException; 26 import org.apache.avalon.framework.context.Contextualizable; 27 import org.apache.avalon.framework.logger.AbstractLogEnabled; 28 import org.apache.avalon.framework.service.ServiceException; 29 import org.apache.avalon.framework.service.ServiceManager; 30 import org.apache.avalon.framework.service.ServiceSelector; 31 import org.apache.avalon.framework.service.Serviceable; 32 import org.apache.avalon.framework.thread.ThreadSafe; 33 import org.apache.cocoon.ProcessingException; 34 import org.apache.cocoon.components.ContextHelper; 35 import org.apache.cocoon.environment.Request; 36 import org.apache.cocoon.environment.Session; 37 import org.apache.cocoon.webapps.session.ContextManager; 38 import org.apache.cocoon.webapps.session.context.SessionContext; 39 import org.apache.cocoon.webapps.session.context.SessionContextProvider; 40 import org.apache.cocoon.webapps.session.context.SimpleSessionContext; 41 import org.apache.excalibur.source.SourceResolver; 42 import org.apache.excalibur.xml.xpath.XPathProcessor; 43 import org.xml.sax.SAXException ; 44 45 51 public final class DefaultContextManager 52 extends AbstractLogEnabled 53 implements Serviceable, ContextManager, ThreadSafe, Component, Contextualizable, Disposable { 54 55 56 private ServiceManager manager; 57 58 59 private Context context; 60 61 62 private ServiceSelector contextSelector; 63 64 65 private XPathProcessor xpathProcessor; 66 67 68 private SourceResolver resolver; 69 70 71 static private final String [] reservedContextNames = {"session", 72 "context"}; 73 76 public void service(ServiceManager manager) 77 throws ServiceException { 78 this.manager = manager; 79 this.contextSelector = (ServiceSelector)this.manager.lookup(SessionContextProvider.ROLE+"Selector"); 80 this.xpathProcessor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE); 81 this.resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE); 82 } 83 84 87 private Session getSession(boolean create) { 88 final Request request = ContextHelper.getRequest( this.context ); 89 return request.getSession( create ); 90 } 91 92 95 private Map getSessionContexts(Session session) { 96 Map contexts; 97 contexts = (Map )session.getAttribute(SessionContext.class.getName()); 98 if (contexts == null) { 99 contexts = new HashMap (5, 3); 100 session.setAttribute(SessionContext.class.getName(), contexts); 101 } 102 return contexts; 103 } 104 105 108 private boolean isReservedContextName(String name) { 109 int i, l; 111 boolean found; 112 found = false; 113 i = 0; 114 l = reservedContextNames.length; 115 while (i < l && found == false) { 116 found = reservedContextNames[i].equals(name); 117 i++; 118 } 119 if (!found ) { 120 found = false; 121 SessionContextProvider provider = null; 122 try { 123 provider = (SessionContextProvider)this.contextSelector.select( name ); 124 found = true; 125 } catch (ServiceException ignore) { 126 } finally { 127 this.contextSelector.release(provider); 128 } 129 } 130 return found; 131 } 132 133 136 private boolean existsReservedContext(String name) 137 throws ProcessingException { 138 boolean exists = false; 140 SessionContextProvider provider = null; 141 try { 142 provider = (SessionContextProvider)this.contextSelector.select( name ); 143 exists = provider.existsSessionContext( name ); 144 } catch (ServiceException ignore) { 145 } finally { 146 this.contextSelector.release(provider); 147 } 148 149 return exists; 150 } 151 152 155 private SessionContext getReservedContext(String name) 156 throws ProcessingException { 157 SessionContext context = null; 159 SessionContextProvider provider = null; 160 try { 161 provider = (SessionContextProvider)this.contextSelector.select( name ); 162 synchronized (provider) { 163 context = provider.getSessionContext(name); 164 } 165 } catch (ServiceException ignore) { 166 } finally { 167 this.contextSelector.release(provider); 168 } 169 170 return context; 171 } 172 173 179 public SessionContext createContext(String name, String loadURI, String saveURI) 180 throws IOException , SAXException , ProcessingException { 181 if (this.getLogger().isDebugEnabled()) { 183 this.getLogger().debug("BEGIN createContext name=" + name + 184 "load=" + loadURI + 185 "save=" + saveURI); 186 } 187 if (name == null) { 189 throw new ProcessingException("CreateContext: Name is required"); 190 } 191 Session session = this.getSession(true); 192 if (session == null) { 193 throw new ProcessingException("CreateContext: Session is required"); 194 } 195 196 SessionContext context; 197 synchronized(session) { 198 if (this.isReservedContextName(name)) { 200 throw new ProcessingException("SessionContext with name " + name + " is reserved and cannot be created manually."); 201 } 202 203 if (this.existsContext(name)) { 204 context = this.getContext(name); 205 } else { 206 Map contexts = this.getSessionContexts(session); 207 context = new SimpleSessionContext(this.xpathProcessor, this.resolver); 208 context.setup(name, loadURI, saveURI); 209 contexts.put(name, context); 210 } 211 } 212 213 if (this.getLogger().isDebugEnabled()) { 214 this.getLogger().debug("END createContext context="+context); 215 } 216 217 return context; 218 } 219 220 225 public void deleteContext(String name) 226 throws ProcessingException { 227 if (this.getLogger().isDebugEnabled() ) { 229 this.getLogger().debug("BEGIN deleteContext name=" + name); 230 } 231 232 if (name == null) { 234 throw new ProcessingException("SessionManager.deleteContext: Name is required"); 235 } 236 if (this.isReservedContextName(name)) { 237 throw new ProcessingException("SessionContext with name " + name + " is reserved and cannot be deleted manually."); 238 } 239 Session session = this.getSession(false); 240 if (session == null) { 241 throw new ProcessingException("SessionManager.deleteContext: Session is required"); 242 } 243 244 synchronized(session) { 245 final Map contexts = this.getSessionContexts(session); 246 if (contexts.containsKey(name)) { 247 contexts.remove(name); 248 } 249 } 250 251 if (this.getLogger().isDebugEnabled() ) { 252 this.getLogger().debug("END deleteContext"); 253 } 254 } 255 256 261 public SessionContext getContext(String name) 262 throws ProcessingException { 263 if (this.getLogger().isDebugEnabled() ) { 265 this.getLogger().debug("BEGIN getContext name=" + name); 266 } 267 268 SessionContext context; 269 if (this.isReservedContextName(name) ) { 270 context = this.getReservedContext(name); 271 } else { 272 Session session = this.getSession(false); 273 if ( session != null) { 274 synchronized (session) { 275 final Map contexts = this.getSessionContexts( session ); 276 context = (SessionContext)contexts.get(name); 277 } 278 } else { 279 context = null; 280 } 281 } 282 283 if (this.getLogger().isDebugEnabled() ) { 284 this.getLogger().debug("END getContext context=" + context); 285 } 286 287 return context; 288 } 289 290 293 public boolean hasSessionContext() 294 throws ProcessingException { 295 Session session = this.getSession(false); 296 if (session == null) { 297 throw new ProcessingException("SessionManager.hasSessionContext: Session is required."); 298 } 299 synchronized (session) { 300 final Map contexts = this.getSessionContexts(session); 301 return !(contexts.isEmpty()); 302 } 303 } 304 305 310 public boolean existsContext(String name) 311 throws ProcessingException { 312 Session session = this.getSession(false); 313 if (session == null) { 314 throw new ProcessingException("SessionManager.existsContext: Session is required."); 315 } 316 synchronized (session) { 317 final Map contexts = this.getSessionContexts(session); 318 boolean result = contexts.containsKey(name); 319 if (!result && this.isReservedContextName(name) ) { 320 result = this.existsReservedContext(name); 321 } 322 return result; 323 } 324 } 325 326 327 330 public void contextualize(Context context) throws ContextException { 331 this.context = context; 332 } 333 334 337 public void dispose() { 338 if ( this.manager != null) { 339 this.manager.release( this.contextSelector ); 340 this.manager.release( this.xpathProcessor ); 341 this.manager.release( this.resolver ); 342 this.contextSelector = null; 343 this.xpathProcessor = null; 344 this.resolver = null; 345 this.manager = null; 346 } 347 } 348 349 } 350 | Popular Tags |