001: /*
002: * Copyright 2005 Joe Walker
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: package org.directwebremoting.spring;
017:
018: import java.util.ArrayList;
019: import java.util.Arrays;
020: import java.util.Collection;
021: import java.util.Collections;
022: import java.util.List;
023: import java.util.Map;
024:
025: import org.apache.commons.logging.LogFactory;
026: import org.apache.commons.logging.Log;
027: import org.directwebremoting.Container;
028: import org.directwebremoting.extend.ContainerConfigurationException;
029: import org.directwebremoting.impl.DefaultContainer;
030: import org.springframework.beans.BeansException;
031: import org.springframework.beans.factory.BeanFactory;
032: import org.springframework.beans.factory.BeanFactoryAware;
033: import org.springframework.beans.factory.InitializingBean;
034: import org.springframework.beans.factory.ListableBeanFactory;
035: import org.springframework.util.ClassUtils;
036:
037: /**
038: * A <code>Container</code> implementation that looks up all beans from the
039: * configuration specified in a Spring context.
040: * It loads the configuration from a Spring web application context.
041: * @author Bram Smeets
042: * @author Joe Walker [joe at getahead dot ltd dot uk]
043: */
044: public class SpringContainer extends DefaultContainer implements
045: Container, BeanFactoryAware, InitializingBean {
046: /* (non-Javadoc)
047: * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
048: */
049: public void setBeanFactory(BeanFactory beanFactory)
050: throws BeansException {
051: this .beanFactory = beanFactory;
052: }
053:
054: /* (non-Javadoc)
055: * @see org.directwebremoting.impl.DefaultContainer#addParameter(java.lang.String, java.lang.Object)
056: */
057: @SuppressWarnings("unchecked")
058: @Override
059: public void addParameter(String askFor, Object valueParam)
060: throws ContainerConfigurationException {
061: try {
062: Class<?> clz = ClassUtils.forName(askFor);
063: if (log.isDebugEnabled()) {
064: log
065: .debug("trying to resolve the following class from the Spring bean container: "
066: + clz.getName());
067: }
068:
069: Map<String, Object> beansOfType = ((ListableBeanFactory) beanFactory)
070: .getBeansOfType(clz);
071: if (log.isDebugEnabled()) {
072: log.debug("beans: " + beansOfType + " - "
073: + beansOfType.size());
074: }
075:
076: if (beansOfType.isEmpty()) {
077: log.debug("adding parameter the normal way");
078: super .addParameter(askFor, valueParam);
079: } else if (beansOfType.size() > 1) {
080: // TODO: handle multiple declarations
081: throw new ContainerConfigurationException(
082: "multiple beans of type '"
083: + clz.getName()
084: + "' were found in the spring configuration");
085: } else {
086: beans.put(askFor, beansOfType.values().iterator()
087: .next());
088: }
089: } catch (ClassNotFoundException ex) {
090: super .addParameter(askFor, valueParam);
091: }
092: }
093:
094: /* (non-Javadoc)
095: * @see org.directwebremoting.impl.DefaultContainer#getBean(java.lang.String)
096: */
097: @Override
098: public Object getBean(String id) {
099: Object reply;
100: try {
101: reply = beanFactory.getBean(id);
102: } catch (BeansException ex) {
103: // Spring throws on not-found, we return null.
104: reply = super .getBean(id);
105: }
106:
107: return reply;
108: }
109:
110: /* (non-Javadoc)
111: * @see org.directwebremoting.impl.DefaultContainer#getBeanNames()
112: */
113: @Override
114: public Collection<String> getBeanNames() {
115: List<String> names = new ArrayList<String>();
116:
117: // Snarf the beans from Spring
118: if (beanFactory instanceof ListableBeanFactory) {
119: ListableBeanFactory listable = (ListableBeanFactory) beanFactory;
120: names.addAll(Arrays.asList(listable
121: .getBeanDefinitionNames()));
122: } else {
123: log
124: .warn("List of beanNames does not include Spring beans since your BeanFactory is not a ListableBeanFactory.");
125: }
126:
127: // And append the DWR ones
128: names.addAll(super .getBeanNames());
129:
130: return Collections.unmodifiableCollection(names);
131: }
132:
133: /* (non-Javadoc)
134: * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
135: */
136: public void afterPropertiesSet() throws Exception {
137: callInitializingBeans();
138: }
139:
140: /**
141: * The Spring BeanFactory that we read from
142: */
143: protected BeanFactory beanFactory;
144:
145: /**
146: * The log stream
147: */
148: private static final Log log = LogFactory
149: .getLog(SpringContainer.class);
150: }
|