View Javadoc

1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.plugins.s2.el;
17  
18  import static org.seasar.framework.message.MessageFormatter.getMessage;
19  
20  import java.beans.FeatureDescriptor;
21  import java.util.ArrayList;
22  import java.util.Iterator;
23  import java.util.List;
24  
25  import javax.el.ELContext;
26  import javax.el.ELException;
27  import javax.el.ELResolver;
28  import javax.el.PropertyNotFoundException;
29  import javax.el.PropertyNotWritableException;
30  
31  import org.seasar.cubby.spi.beans.Attribute;
32  import org.seasar.cubby.spi.beans.BeanDesc;
33  import org.seasar.cubby.spi.beans.BeanDescFactory;
34  
35  /**
36   * S2Container の public フィールドをプロパティとして認識させるための {@link ELResolver} です。
37   * 
38   * @author baba
39   */
40  public class S2BeanELResolver extends ELResolver {
41  
42  	/** 読み込み専用。 */
43  	private final boolean readOnly;
44  
45  	/**
46  	 * インスタンスを生成します。
47  	 */
48  	public S2BeanELResolver() {
49  		this(false);
50  	}
51  
52  	/**
53  	 * インスタンスを生成します。
54  	 * 
55  	 * @param readOnly
56  	 *            読み込み専用とする場合は <code>true</code>、そうでない場合は <code>false</code>
57  	 */
58  	public S2BeanELResolver(final boolean readOnly) {
59  		super();
60  		this.readOnly = readOnly;
61  	}
62  
63  	/**
64  	 * {@inheritDoc}
65  	 */
66  	@Override
67  	public Object getValue(final ELContext context, final Object base,
68  			final Object property) throws NullPointerException,
69  			PropertyNotFoundException, ELException {
70  		if (context == null) {
71  			throw new NullPointerException();
72  		}
73  		if (base == null || property == null) {
74  			return null;
75  		}
76  
77  		final String propertyName = property.toString();
78  		final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(base.getClass());
79  		if (!beanDesc.hasPropertyAttribute(propertyName)) {
80  			return null;
81  		}
82  
83  		try {
84  			final Attribute attributeDesc = beanDesc
85  					.getPropertyAttribute(propertyName);
86  			final Object value = attributeDesc.getValue(base);
87  			context.setPropertyResolved(true);
88  			return value;
89  		} catch (final Exception e) {
90  			return null;
91  		}
92  	}
93  
94  	/**
95  	 * {@inheritDoc}
96  	 */
97  	@Override
98  	public Class<?> getType(final ELContext context, final Object base,
99  			final Object property) {
100 		if (context == null) {
101 			throw new NullPointerException();
102 		}
103 
104 		if (base == null || property == null) {
105 			return null;
106 		}
107 
108 		final String propertyName = property.toString();
109 		final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(base.getClass());
110 		if (!beanDesc.hasPropertyAttribute(propertyName)) {
111 			return null;
112 		}
113 
114 		try {
115 			final Attribute attributeDesc = beanDesc
116 					.getPropertyAttribute(propertyName);
117 			final Class<?> propertyType = attributeDesc.getType();
118 			context.setPropertyResolved(true);
119 			return propertyType;
120 		} catch (final Exception e) {
121 			return null;
122 		}
123 	}
124 
125 	/**
126 	 * {@inheritDoc}
127 	 */
128 	@Override
129 	public void setValue(final ELContext context, final Object base,
130 			final Object property, final Object value) {
131 		if (context == null) {
132 			throw new NullPointerException();
133 		}
134 		if (base == null || property == null) {
135 			return;
136 		}
137 
138 		final String propertyName = property.toString();
139 		final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(base.getClass());
140 		if (!beanDesc.hasPropertyAttribute(propertyName)) {
141 			return;
142 		}
143 
144 		if (this.readOnly) {
145 			throw new PropertyNotWritableException(getMessage("ECUB0001",
146 					new Object[] { base.getClass().getName() }));
147 		}
148 
149 		try {
150 			final Attribute attributeDesc = beanDesc
151 					.getPropertyAttribute(propertyName);
152 			attributeDesc.setValue(base, value);
153 			context.setPropertyResolved(true);
154 		} catch (final Exception e) {
155 		}
156 	}
157 
158 	/**
159 	 * {@inheritDoc}
160 	 */
161 	@Override
162 	public boolean isReadOnly(final ELContext context, final Object base,
163 			final Object property) {
164 		if (context == null) {
165 			throw new NullPointerException();
166 		}
167 		if (base == null || property == null) {
168 			return false;
169 		}
170 
171 		final String propertyName = property.toString();
172 		final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(base.getClass());
173 		if (!beanDesc.hasPropertyAttribute(propertyName)) {
174 			return true;
175 		}
176 
177 		if (this.readOnly) {
178 			return true;
179 		}
180 
181 		try {
182 			final Attribute attributeDesc = beanDesc
183 					.getPropertyAttribute(propertyName);
184 			final boolean readOnly = !attributeDesc.isWritable();
185 			context.setPropertyResolved(true);
186 			return readOnly;
187 		} catch (final Exception e) {
188 			return false;
189 		}
190 	}
191 
192 	/**
193 	 * {@inheritDoc}
194 	 */
195 	@Override
196 	public Iterator<FeatureDescriptor> getFeatureDescriptors(
197 			final ELContext context, final Object base) {
198 		if (context == null) {
199 			throw new NullPointerException();
200 		}
201 
202 		if (base == null) {
203 			return null;
204 		}
205 
206 		final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(base.getClass());
207 		try {
208 			final List<FeatureDescriptor> descriptors = new ArrayList<FeatureDescriptor>();
209 			for (final Attribute attributeDesc : beanDesc
210 					.findtPropertyAttributes()) {
211 				final String propertyName = attributeDesc.getName();
212 				final FeatureDescriptor descriptor = new FeatureDescriptor();
213 				descriptor.setDisplayName(propertyName);
214 				descriptor.setExpert(false);
215 				descriptor.setHidden(false);
216 				descriptor.setName(propertyName);
217 				descriptor.setPreferred(true);
218 				descriptor.setValue(RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE);
219 				descriptor.setValue(TYPE, attributeDesc.getType());
220 				descriptors.add(descriptor);
221 			}
222 
223 			return descriptors.iterator();
224 		} catch (final Exception e) {
225 			// do nothing
226 		}
227 		return null;
228 	}
229 
230 	/**
231 	 * {@inheritDoc}
232 	 */
233 	@Override
234 	public Class<?> getCommonPropertyType(final ELContext context,
235 			final Object base) {
236 		if (context == null) {
237 			throw new NullPointerException();
238 		}
239 
240 		if (base != null) {
241 			return Object.class;
242 		}
243 
244 		return null;
245 	}
246 
247 }