/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.cocoon.webapps.session.components; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.component.Component; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.service.ServiceManager; import org.apache.avalon.framework.service.ServiceSelector; import org.apache.avalon.framework.service.Serviceable; import org.apache.avalon.framework.thread.ThreadSafe; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.components.ContextHelper; import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.Session; import org.apache.cocoon.util.Deprecation; import org.apache.cocoon.webapps.session.ContextManager; import org.apache.cocoon.webapps.session.context.SessionContext; import org.apache.cocoon.webapps.session.context.SessionContextProvider; import org.apache.cocoon.webapps.session.context.SimpleSessionContext; import org.apache.excalibur.source.SourceResolver; import org.apache.excalibur.xml.xpath.XPathProcessor; import org.xml.sax.SAXException; /** * Context manager * * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a> * @deprecated This block is deprecated and will be removed in future versions. * @version CVS $Id$ */ public final class DefaultContextManager extends AbstractLogEnabled implements Serviceable, ContextManager, ThreadSafe, Component, Contextualizable, Disposable { /** The <code>ServiceManager</code> */ private ServiceManager manager; /** The context */ private Context context; /** selector for context provider */ private ServiceSelector contextSelector; /** The xpath processor */ private XPathProcessor xpathProcessor; /** The source resolver */ private SourceResolver resolver; /* The list of reserved contexts */ static private final String[] reservedContextNames = {"session", "context"}; /** * Avalon Serviceable Interface */ public void service(ServiceManager manager) throws ServiceException { this.manager = manager; this.contextSelector = (ServiceSelector)this.manager.lookup(SessionContextProvider.ROLE+"Selector"); this.xpathProcessor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE); this.resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE); Deprecation.logger.warn("The session-fw block is deprecated. Please use the provided alternatives instead."); } /** * Get the session */ private Session getSession(boolean create) { final Request request = ContextHelper.getRequest( this.context ); return request.getSession( create ); } /** * Get the list of contexts */ private Map getSessionContexts(Session session) { Map contexts; contexts = (Map)session.getAttribute(SessionContext.class.getName()); if (contexts == null) { contexts = new HashMap(5, 3); session.setAttribute(SessionContext.class.getName(), contexts); } return contexts; } /** * Checks if the context name is a reserved context. */ private boolean isReservedContextName(String name) { // synchronized (not needed) int i, l; boolean found; found = false; i = 0; l = reservedContextNames.length; while (i < l && found == false) { found = reservedContextNames[i].equals(name); i++; } if (!found ) { found = false; SessionContextProvider provider = null; try { provider = (SessionContextProvider)this.contextSelector.select( name ); found = true; } catch (ServiceException ignore) { } finally { this.contextSelector.release(provider); } } return found; } /** * Get a reserved context */ private boolean existsReservedContext(String name) throws ProcessingException { // synchronized (not needed) boolean exists = false; SessionContextProvider provider = null; try { provider = (SessionContextProvider)this.contextSelector.select( name ); exists = provider.existsSessionContext( name ); } catch (ServiceException ignore) { } finally { this.contextSelector.release(provider); } return exists; } /** * Get a reserved context */ private SessionContext getReservedContext(String name) throws ProcessingException { // synchronized SessionContext context = null; SessionContextProvider provider = null; try { provider = (SessionContextProvider)this.contextSelector.select( name ); synchronized (provider) { context = provider.getSessionContext(name); } } catch (ServiceException ignore) { } finally { this.contextSelector.release(provider); } return context; } /** * Create a new public context in the session. * Create a new public session context for this user. If this context * already exists no new context is created and the old one will be used * instead. */ public SessionContext createContext(String name, String loadURI, String saveURI) throws IOException, SAXException, ProcessingException { // synchronized if (this.getLogger().isDebugEnabled()) { this.getLogger().debug("BEGIN createContext name=" + name + "load=" + loadURI + "save=" + saveURI); } // test arguments if (name == null) { throw new ProcessingException("CreateContext: Name is required"); } Session session = this.getSession(true); if (session == null) { throw new ProcessingException("CreateContext: Session is required"); } SessionContext context; synchronized(session) { // test for reserved context if (this.isReservedContextName(name)) { throw new ProcessingException("SessionContext with name " + name + " is reserved and cannot be created manually."); } if (this.existsContext(name)) { context = this.getContext(name); } else { Map contexts = this.getSessionContexts(session); context = new SimpleSessionContext(this.xpathProcessor, this.resolver); context.setup(name, loadURI, saveURI); contexts.put(name, context); } } if (this.getLogger().isDebugEnabled()) { this.getLogger().debug("END createContext context="+context); } return context; } /** * Delete a public context in the session. * If the context exists for this user, it and all of its information * is deleted. */ public void deleteContext(String name) throws ProcessingException { // synchronized if (this.getLogger().isDebugEnabled() ) { this.getLogger().debug("BEGIN deleteContext name=" + name); } // test arguments if (name == null) { throw new ProcessingException("SessionManager.deleteContext: Name is required"); } if (this.isReservedContextName(name)) { throw new ProcessingException("SessionContext with name " + name + " is reserved and cannot be deleted manually."); } Session session = this.getSession(false); if (session == null) { throw new ProcessingException("SessionManager.deleteContext: Session is required"); } synchronized(session) { final Map contexts = this.getSessionContexts(session); if (contexts.containsKey(name)) { contexts.remove(name); } } if (this.getLogger().isDebugEnabled() ) { this.getLogger().debug("END deleteContext"); } } /** * Get a public context. * The session context with the given name is returned. If the context does * not exist <CODE>null</CODE> is returned. */ public SessionContext getContext(String name) throws ProcessingException { // synchronized if (this.getLogger().isDebugEnabled() ) { this.getLogger().debug("BEGIN getContext name=" + name); } SessionContext context; if (this.isReservedContextName(name) ) { context = this.getReservedContext(name); } else { Session session = this.getSession(false); if ( session != null) { synchronized (session) { final Map contexts = this.getSessionContexts( session ); context = (SessionContext)contexts.get(name); } } else { context = null; } } if (this.getLogger().isDebugEnabled() ) { this.getLogger().debug("END getContext context=" + context); } return context; } /** * Check if a context exists */ public boolean hasSessionContext() throws ProcessingException { Session session = this.getSession(false); if (session == null) { throw new ProcessingException("SessionManager.hasSessionContext: Session is required."); } synchronized (session) { final Map contexts = this.getSessionContexts(session); return !(contexts.isEmpty()); } } /** * Check if a public context exists. * If the session context with the given name exists, <CODE>true</CODE> is * returned. */ public boolean existsContext(String name) throws ProcessingException { Session session = this.getSession(false); if (session == null) { throw new ProcessingException("SessionManager.existsContext: Session is required."); } synchronized (session) { final Map contexts = this.getSessionContexts(session); boolean result = contexts.containsKey(name); if (!result && this.isReservedContextName(name) ) { result = this.existsReservedContext(name); } return result; } } /* (non-Javadoc) * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context) */ public void contextualize(Context context) throws ContextException { this.context = context; } /* (non-Javadoc) * @see org.apache.avalon.framework.activity.Disposable#dispose() */ public void dispose() { if ( this.manager != null) { this.manager.release( this.contextSelector ); this.manager.release( this.xpathProcessor ); this.manager.release( this.resolver ); this.contextSelector = null; this.xpathProcessor = null; this.resolver = null; this.manager = null; } } }