001: /*
002: * Copyright 2002-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.web.jsf;
018:
019: import javax.faces.context.ExternalContext;
020: import javax.faces.context.FacesContext;
021:
022: import org.springframework.util.Assert;
023: import org.springframework.web.context.WebApplicationContext;
024: import org.springframework.web.util.WebUtils;
025:
026: /**
027: * Convenience methods to retrieve the root WebApplicationContext for a given
028: * FacesContext. This is e.g. useful for accessing a Spring context from
029: * custom JSF code.
030: *
031: * <p>Analogous to Spring's WebApplicationContextUtils for the ServletContext.
032: *
033: * @author Juergen Hoeller
034: * @since 1.1
035: * @see org.springframework.web.context.ContextLoader
036: * @see org.springframework.web.context.support.WebApplicationContextUtils
037: */
038: public abstract class FacesContextUtils {
039:
040: /**
041: * Find the root WebApplicationContext for this web app, which is
042: * typically loaded via ContextLoaderListener or ContextLoaderServlet.
043: * <p>Will rethrow an exception that happened on root context startup,
044: * to differentiate between a failed context startup and no context at all.
045: * @param fc the FacesContext to find the web application context for
046: * @return the root WebApplicationContext for this web app, or <code>null</code> if none
047: * @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
048: */
049: public static WebApplicationContext getWebApplicationContext(
050: FacesContext fc) {
051: Assert.notNull(fc, "FacesContext must not be null");
052: Object attr = fc
053: .getExternalContext()
054: .getApplicationMap()
055: .get(
056: WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
057: if (attr == null) {
058: return null;
059: }
060: if (attr instanceof RuntimeException) {
061: throw (RuntimeException) attr;
062: }
063: if (attr instanceof Error) {
064: throw (Error) attr;
065: }
066: if (!(attr instanceof WebApplicationContext)) {
067: throw new IllegalStateException(
068: "Root context attribute is not of type WebApplicationContext: "
069: + attr);
070: }
071: return (WebApplicationContext) attr;
072: }
073:
074: /**
075: * Find the root WebApplicationContext for this web app, which is
076: * typically loaded via ContextLoaderListener or ContextLoaderServlet.
077: * <p>Will rethrow an exception that happened on root context startup,
078: * to differentiate between a failed context startup and no context at all.
079: * @param fc the FacesContext to find the web application context for
080: * @return the root WebApplicationContext for this web app
081: * @throws IllegalStateException if the root WebApplicationContext could not be found
082: * @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
083: */
084: public static WebApplicationContext getRequiredWebApplicationContext(
085: FacesContext fc) throws IllegalStateException {
086:
087: WebApplicationContext wac = getWebApplicationContext(fc);
088: if (wac == null) {
089: throw new IllegalStateException(
090: "No WebApplicationContext found: no ContextLoaderListener registered?");
091: }
092: return wac;
093: }
094:
095: /**
096: * Return the best available mutex for the given session:
097: * that is, an object to synchronize on for the given session.
098: * <p>Returns the session mutex attribute if available; usually,
099: * this means that the HttpSessionMutexListener needs to be defined
100: * in <code>web.xml</code>. Falls back to the Session reference itself
101: * if no mutex attribute found.
102: * <p>The session mutex is guaranteed to be the same object during
103: * the entire lifetime of the session, available under the key defined
104: * by the <code>SESSION_MUTEX_ATTRIBUTE</code> constant. It serves as a
105: * safe reference to synchronize on for locking on the current session.
106: * <p>In many cases, the Session reference itself is a safe mutex
107: * as well, since it will always be the same object reference for the
108: * same active logical session. However, this is not guaranteed across
109: * different servlet containers; the only 100% safe way is a session mutex.
110: * @param fc the FacesContext to find the session mutex for
111: * @return the mutex object (never <code>null</code>)
112: * @see org.springframework.web.util.WebUtils#SESSION_MUTEX_ATTRIBUTE
113: * @see org.springframework.web.util.HttpSessionMutexListener
114: */
115: public static Object getSessionMutex(FacesContext fc) {
116: Assert.notNull(fc, "FacesContext must not be null");
117: ExternalContext ec = fc.getExternalContext();
118: Object mutex = ec.getSessionMap().get(
119: WebUtils.SESSION_MUTEX_ATTRIBUTE);
120: if (mutex == null) {
121: mutex = ec.getSession(true);
122: }
123: return mutex;
124: }
125:
126: }
|