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.portlet.handler;
018:
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.Map;
022:
023: import javax.portlet.PortletRequest;
024:
025: import org.springframework.beans.BeansException;
026: import org.springframework.util.Assert;
027:
028: /**
029: * Abstract base class for HandlerMapping implementations that rely on a map
030: * which caches handler objects per lookup key. Supports arbitrary lookup keys,
031: * and automatically resolves handler bean names into handler bean instances.
032: *
033: * @author Juergen Hoeller
034: * @since 2.0
035: * @see #getLookupKey(javax.portlet.PortletRequest)
036: * @see #registerHandler(Object, Object)
037: */
038: public abstract class AbstractMapBasedHandlerMapping extends
039: AbstractHandlerMapping {
040:
041: private boolean lazyInitHandlers = false;
042:
043: private final Map handlerMap = new HashMap();
044:
045: /**
046: * Set whether to lazily initialize handlers. Only applicable to
047: * singleton handlers, as prototypes are always lazily initialized.
048: * Default is false, as eager initialization allows for more efficiency
049: * through referencing the handler objects directly.
050: * <p>If you want to allow your handlers to be lazily initialized,
051: * make them "lazy-init" and set this flag to true. Just making them
052: * "lazy-init" will not work, as they are initialized through the
053: * references from the handler mapping in this case.
054: */
055: public void setLazyInitHandlers(boolean lazyInitHandlers) {
056: this .lazyInitHandlers = lazyInitHandlers;
057: }
058:
059: /**
060: * Determines a handler for the computed lookup key for the given request.
061: * @see #getLookupKey
062: */
063: protected Object getHandlerInternal(PortletRequest request)
064: throws Exception {
065: Object lookupKey = getLookupKey(request);
066: Object handler = this .handlerMap.get(lookupKey);
067: if (handler != null && logger.isDebugEnabled()) {
068: logger.debug("Key [" + lookupKey + "] -> handler ["
069: + handler + "]");
070: }
071: return handler;
072: }
073:
074: /**
075: * Build a lookup key for the given request.
076: * @param request current portlet request
077: * @return the lookup key (never <code>null</code>)
078: * @throws Exception if key computation failed
079: */
080: protected abstract Object getLookupKey(PortletRequest request)
081: throws Exception;
082:
083: /**
084: * Register all handlers specified in the Portlet mode map for the corresponding modes.
085: * @param handlerMap Map with lookup keys as keys and handler beans or bean names as values
086: * @throws BeansException if the handler couldn't be registered
087: */
088: protected void registerHandlers(Map handlerMap)
089: throws BeansException {
090: Assert.notNull(handlerMap, "Handler Map must not be null");
091: for (Iterator it = handlerMap.entrySet().iterator(); it
092: .hasNext();) {
093: Map.Entry entry = (Map.Entry) it.next();
094: registerHandler(entry.getKey(), entry.getValue());
095: }
096: }
097:
098: /**
099: * Register the given handler instance for the given parameter value.
100: * @param lookupKey the key to map the handler onto
101: * @param handler the handler instance or handler bean name String
102: * (a bean name will automatically be resolved into the corrresponding handler bean)
103: * @throws BeansException if the handler couldn't be registered
104: * @throws IllegalStateException if there is a conflicting handler registered
105: */
106: protected void registerHandler(Object lookupKey, Object handler)
107: throws BeansException, IllegalStateException {
108: Assert.notNull(lookupKey, "Lookup key must not be null");
109: Assert.notNull(handler, "Handler object must not be null");
110:
111: // Check for duplicate mapping.
112: Object mappedHandler = this .handlerMap.get(lookupKey);
113: if (mappedHandler != null) {
114: throw new IllegalStateException("Cannot map handler ["
115: + handler + "] to key [" + lookupKey
116: + "]: There's already handler [" + mappedHandler
117: + "] mapped.");
118: }
119:
120: // Eagerly resolve handler if referencing singleton via name.
121: if (!this .lazyInitHandlers && handler instanceof String) {
122: String handlerName = (String) handler;
123: if (getApplicationContext().isSingleton(handlerName)) {
124: handler = getApplicationContext().getBean(handlerName);
125: }
126: }
127:
128: // Add the handler to the map.
129: this .handlerMap.put(lookupKey, handler);
130: if (logger.isDebugEnabled()) {
131: logger.debug("Mapped key [" + lookupKey
132: + "] onto handler [" + handler + "]");
133: }
134: }
135:
136: }
|