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.context.support;
018:
019: import org.apache.commons.logging.Log;
020: import org.apache.commons.logging.LogFactory;
021:
022: import org.springframework.beans.BeansException;
023: import org.springframework.context.ApplicationContext;
024: import org.springframework.context.ApplicationContextAware;
025: import org.springframework.context.ApplicationContextException;
026:
027: /**
028: * Convenient superclass for application objects that want to be aware of
029: * the application context, e.g. for custom lookup of collaborating beans
030: * or for context-specific resource access. It saves the application
031: * context reference and provides an initialization callback method.
032: * Furthermore, it offers numerous convenience methods for message lookup.
033: *
034: * <p>There is no requirement to subclass this class: It just makes things
035: * a little easier if you need access to the context, e.g. for access to
036: * file resources or to the message source. Note that many application
037: * objects do not need to be aware of the application context at all,
038: * as they can receive collaborating beans via bean references.
039: *
040: * <p>Many framework classes are derived from this class, particularly
041: * within the web support.
042: *
043: * @author Rod Johnson
044: * @author Juergen Hoeller
045: * @see org.springframework.web.context.support.WebApplicationObjectSupport
046: */
047: public abstract class ApplicationObjectSupport implements
048: ApplicationContextAware {
049:
050: /** Logger that is available to subclasses */
051: protected final Log logger = LogFactory.getLog(getClass());
052:
053: /** ApplicationContext this object runs in */
054: private ApplicationContext applicationContext;
055:
056: /** MessageSourceAccessor for easy message access */
057: private MessageSourceAccessor messageSourceAccessor;
058:
059: public final void setApplicationContext(ApplicationContext context)
060: throws BeansException {
061: if (context == null && !isContextRequired()) {
062: // Reset internal context state.
063: this .applicationContext = null;
064: this .messageSourceAccessor = null;
065: } else if (this .applicationContext == null) {
066: // Initialize with passed-in context.
067: if (!requiredContextClass().isInstance(context)) {
068: throw new ApplicationContextException(
069: "Invalid application context: needs to be of type ["
070: + requiredContextClass().getName()
071: + "]");
072: }
073: this .applicationContext = context;
074: this .messageSourceAccessor = new MessageSourceAccessor(
075: context);
076: initApplicationContext();
077: } else {
078: // Ignore reinitialization if same context passed in.
079: if (this .applicationContext != context) {
080: throw new ApplicationContextException(
081: "Cannot reinitialize with different application context: current one is ["
082: + this .applicationContext
083: + "], passed-in one is [" + context
084: + "]");
085: }
086: }
087: }
088:
089: /**
090: * Determine whether this application object needs to run in an ApplicationContext.
091: * <p>Default is "false". Can be overridden to enforce running in a context
092: * (i.e. to throw IllegalStateException on accessors if outside a context).
093: * @see #getApplicationContext
094: * @see #getMessageSourceAccessor
095: */
096: protected boolean isContextRequired() {
097: return false;
098: }
099:
100: /**
101: * Determine the context class that any context passed to
102: * <code>setApplicationContext</code> must be an instance of.
103: * Can be overridden in subclasses.
104: * @see #setApplicationContext
105: */
106: protected Class requiredContextClass() {
107: return ApplicationContext.class;
108: }
109:
110: /**
111: * Subclasses can override this for custom initialization behavior.
112: * Gets called by <code>setApplicationContext</code> after setting the context instance.
113: * <p>Note: Does </i>not</i> get called on reinitialization of the context
114: * but rather just on first initialization of this object's context reference.
115: * @throws ApplicationContextException in case of initialization errors
116: * @throws BeansException if thrown by ApplicationContext methods
117: * @see #setApplicationContext
118: */
119: protected void initApplicationContext() throws BeansException {
120: }
121:
122: /**
123: * Return the ApplicationContext instance used by this object.
124: */
125: public final ApplicationContext getApplicationContext()
126: throws IllegalStateException {
127: if (this .applicationContext == null && isContextRequired()) {
128: throw new IllegalStateException(
129: "ApplicationObjectSupport instance [" + this
130: + "] does not run in an ApplicationContext");
131: }
132: return applicationContext;
133: }
134:
135: /**
136: * Return a MessageSourceAccessor for the application context
137: * used by this object, for easy message access.
138: * @throws IllegalStateException if not running in an ApplicationContext
139: */
140: protected final MessageSourceAccessor getMessageSourceAccessor()
141: throws IllegalStateException {
142: if (this .messageSourceAccessor == null && isContextRequired()) {
143: throw new IllegalStateException(
144: "ApplicationObjectSupport instance [" + this
145: + "] does not run in an ApplicationContext");
146: }
147: return this.messageSourceAccessor;
148: }
149:
150: }
|