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 org.directwebremoting.create.AbstractCreator;
019: import org.springframework.aop.support.AopUtils;
020: import org.springframework.beans.BeansException;
021: import org.springframework.beans.FatalBeanException;
022: import org.springframework.beans.factory.BeanFactory;
023: import org.springframework.beans.factory.BeanFactoryAware;
024: import org.springframework.beans.factory.InitializingBean;
025: import org.springframework.util.Assert;
026:
027: /**
028: * A creator that proxies to the specified bean. <br>
029: * Note that it can be configured with additional include rules,
030: * exclude rules, filters and authentication rules using the
031: * specified creator configuration.
032: * @see CreatorConfig
033: * @author Bram Smeets
034: */
035: public class BeanCreator extends AbstractCreator implements
036: BeanFactoryAware, InitializingBean {
037: /**
038: * Is called by the Spring container after all properties have been set. <br>
039: * It is implemented in order to initialize the beanClass field correctly and to make sure
040: * that either the bean id or the bean itself have been set on this creator.
041: * @see org.springframework.beans.factory.InitializingBean
042: */
043: public void afterPropertiesSet() {
044: // make sure that either the bean or the beanId have been set correctly
045: if (bean != null) {
046: this .beanClass = bean.getClass();
047: } else if (beanId != null) {
048: this .beanClass = beanFactory.getType(beanId);
049: } else {
050: throw new FatalBeanException(
051: "You should either set the bean property directly or set the beanId property");
052: }
053:
054: // make sure to handle cglib proxies correctly
055: if (AopUtils.isCglibProxyClass(this .beanClass)) {
056: this .beanClass = this .beanClass.getSuperclass();
057: }
058: }
059:
060: /**
061: * Accessor for the class that this creator allows access to. <br>
062: * It returns the class specified by the <code>beanClass</code>
063: * property. In case no class name has been set, it returns the
064: * class of the specified bean.
065: * @return the type of this allowed class
066: */
067: public Class<?> getType() {
068: return beanClass;
069: }
070:
071: /**
072: * Accessor for the instance of this creator. <br>
073: * It returns the specified bean property.
074: * @return the bean instance of this creator
075: */
076: public Object getInstance() {
077: synchronized (monitor) {
078: if (bean == null) {
079: Assert.notNull(beanId,
080: "The bean id needs to be specified");
081: bean = beanFactory.getBean(beanId);
082: }
083: }
084:
085: return bean;
086: }
087:
088: /**
089: * Sets the bean for this bean creator.
090: * @param bean the bean for this creator
091: */
092: public void setBean(Object bean) {
093: this .bean = bean;
094: }
095:
096: /**
097: * Sets the bean class for this creator. <br>
098: * Use this property to specify a different class or interface for
099: * instance in case the specified bean is a proxy or implementation
100: * and we want to expose the interface.
101: * @param beanClass the class of the bean to remote
102: */
103: public void setBeanClass(Class<?> beanClass) {
104: this .beanClass = beanClass;
105: }
106:
107: /**
108: * Sets the id of the bean to remote using DWR. <br>
109: * Either set this property on the creator, or set the bean to be
110: * remoted directly on this creator.
111: * @param beanId the id of the bean to remote
112: */
113: public void setBeanId(String beanId) {
114: this .beanId = beanId;
115: }
116:
117: /**
118: * Sets the configuration for this creator. <br>
119: * Use the configuration to specify include and exclude rules, filters
120: * and/or authentication rules.
121: * @see org.directwebremoting.spring.CreatorConfig
122: * @param config the configuration for this creator
123: */
124: public void setConfig(CreatorConfig config) {
125: this .config = config;
126: }
127:
128: /**
129: * Gets the configuration for this creator.
130: * @return the configuration for this creator
131: */
132: public CreatorConfig getConfig() {
133: return config;
134: }
135:
136: /**
137: * Sets the bean factory that contains this BeanCreator.
138: * @param beanFactory the beanFactory that created this BeanCreator
139: * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
140: */
141: public void setBeanFactory(BeanFactory beanFactory)
142: throws BeansException {
143: this .beanFactory = beanFactory;
144:
145: }
146:
147: /**
148: * The bean for this creator.
149: */
150: private Object bean;
151:
152: /**
153: * The optional bean class for this creator.
154: */
155: private Class<?> beanClass;
156:
157: /**
158: * The optional bean name.
159: */
160: private String beanId;
161:
162: /**
163: * The beanFactory context that creates this creator.
164: */
165: private BeanFactory beanFactory;
166:
167: /**
168: * The optional creator configuration for this creator.
169: */
170: private CreatorConfig config;
171:
172: /** Monitor object to synchronize on during inititalization. */
173: private final Object monitor = new Object();
174:
175: }
|