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 }