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.internal.controller.impl;
    17
    18  import java.lang.reflect.Array;
    19  import java.util.Collection;
    20
    21  import org.seasar.cubby.action.RequestParameter;
    22  import org.seasar.cubby.controller.FormWrapper;
    23  import org.seasar.cubby.controller.FormWrapperFactory;
    24  import org.seasar.cubby.converter.ConversionHelper;
    25  import org.seasar.cubby.converter.Converter;
    26  import org.seasar.cubby.converter.impl.ConversionHelperImpl;
    27  import org.seasar.cubby.spi.ConverterProvider;
    28  import org.seasar.cubby.spi.ProviderFactory;
    29  import org.seasar.cubby.spi.beans.Attribute;
    30  import org.seasar.cubby.spi.beans.BeanDesc;
    31  import org.seasar.cubby.spi.beans.BeanDescFactory;
    32
    33  /**
    34   * フォームオブジェクトのラッパーファクトリの実装です。
    35   *
    36   * @author baba
    37   */
    38  public class FormWrapperFactoryImpl implements FormWrapperFactory {
    39
    40  	/** 変換のヘルパクラス。 */
    41  	private final ConversionHelper conversionHelper = new ConversionHelperImpl();
    42
    43  	/**
    44  	 * {@inheritDoc}
    45  	 */
    46  	public FormWrapper create(final Object form) {
    47  		final FormWrapper formObject = new FormWrapperImpl(form);
    48  		return formObject;
    49  	}
    50
    51  	/**
    52  	 * フォームオブジェクトのラッパーの実装です。
    53  	 *
    54  	 * @author baba
    55  	 */
    56  	private class FormWrapperImpl implements FormWrapper {
    57
    58  		/** フォームオブジェクト */
    59  		private final Object form;
    60
    61  		/**
    62  		 * インスタンス化します。
    63  		 *
    64  		 * @param form
    65  		 *            フォームオブジェクト
    66  		 * @param context
    67  		 *            変換中のコンテキスト
    68  		 */
    69  		private FormWrapperImpl(final Object form) {
    70  			this.form = form;
    71  		}
    72
    73  		/**
    74  		 * {@inheritDoc}
    75  		 */
    76  		public boolean hasValues(final String name) {
    77  			if (this.form == null) {
    78  				return false;
    79  			}
    80  			final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(this.form
    81  					.getClass());
    82  			final Attribute attribute = findAttribute(beanDesc, name);
    83  			return attribute != null;
    84  		}
    85
    86  		/**
    87  		 * {@inheritDoc}
    88  		 */
    89  		public String[] getValues(final String name) {
    90  			if (this.form == null) {
    91  				return null;
    92  			}
    93
    94  			final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(this.form
    95  					.getClass());
    96  			final Attribute attribute = findAttribute(beanDesc, name);
    97  			if (attribute == null) {
    98  				return null;
    99  			}
    100 			final Object value = attribute.getValue(this.form);
    101
    102 			if (value == null) {
    103 				return null;
    104 			} else if (value instanceof String[]) {
    105 				return (String[]) value;
    106 			} else {
    107 				final Class<? extends Converter> converterType;
    108 				if (attribute.isAnnotationPresent(RequestParameter.class)) {
    109 					final RequestParameter requestParameter = attribute
    110 							.getAnnotation(RequestParameter.class);
    111 					if (Converter.class.equals(requestParameter.converter())) {
    112 						converterType = null;
    113 					} else {
    114 						converterType = requestParameter.converter();
    115 					}
    116 				} else {
    117 					converterType = null;
    118 				}
    119 				if (value.getClass().isArray()) {
    120 					final int length = Array.getLength(value);
    121 					final String[] array = (String[]) Array.newInstance(
    122 							String.class, length);
    123 					for (int i = 0; i < length; i++) {
    124 						final Object element = Array.get(value, i);
    125 						final String converted = convert(element, converterType);
    126 						Array.set(array, i, converted);
    127 					}
    128 					return array;
    129 				} else if (value instanceof Collection) {
    130 					final Collection<?> collection = (Collection<?>) value;
    131 					final String[] array = (String[]) Array.newInstance(
    132 							String.class, collection.size());
    133 					int i = 0;
    134 					for (final Object element : collection) {
    135 						final String converted = convert(element, converterType);
    136 						Array.set(array, i++, converted);
    137 					}
    138 					return array;
    139 				} else {
    140 					final String[] array = (String[]) Array.newInstance(
    141 							String.class, 1);
    142 					final String converted = convert(value, converterType);
    143 					Array.set(array, 0, converted);
    144 					return array;
    145 				}
    146 			}
    147 		}
    148
    149 		/**
    150 		 * 指定された名前に対応する属性を検索します。
    151 		 *
    152 		 * @param beanDesc
    153 		 *            Java Beans の定義
    154 		 * @param name
    155 		 *            名前
    156 		 * @return 属性の定義
    157 		 */
    158 		private Attribute findAttribute(final BeanDesc beanDesc,
    159 				final String name) {
    160
    161 			for (final Attribute attribute : beanDesc.findAllAttributes()) {
    162 				if (attribute.isAnnotationPresent(RequestParameter.class)) {
    163 					final RequestParameter requestParameter = attribute
    164 							.getAnnotation(RequestParameter.class);
    165 					final String parameterName = requestParameter.name();
    166 					if (parameterName == null || parameterName.length() == 0) {
    167 						if (name.equals(attribute.getName())) {
    168 							return attribute;
    169 						}
    170 					} else {
    171 						if (name.equals(parameterName)) {
    172 							return attribute;
    173 						}
    174 					}
    175 				} else {
    176 					if (name.equals(attribute.getName())) {
    177 						return attribute;
    178 					}
    179 				}
    180 			}
    181
    182 			return null;
    183 		}
    184
    185 		/**
    186 		 * 指定されたオブジェクトを文字列に変換します。
    187 		 *
    188 		 * @param value
    189 		 *            値
    190 		 * @param converterType
    191 		 *            コンバータの型
    192 		 * @return <code>value</code>を変換した文字列
    193 		 */
    194 		private String convert(final Object value,
    195 				final Class<? extends Converter> converterType) {
    196 			if (value == null) {
    197 				return null;
    198 			}
    199 			final ConverterProvider converterProvider = ProviderFactory
    200 					.get(ConverterProvider.class);
    201 			final Converter converter;
    202 			if (converterType == null) {
    203 				converter = converterProvider.getConverter(null, value
    204 						.getClass());
    205 			} else {
    206 				converter = converterProvider.getConverter(converterType);
    207 			}
    208 			if (converter == null) {
    209 				return value.toString();
    210 			} else {
    211 				return converter.convertToString(value, conversionHelper);
    212 			}
    213 		}
    214
    215 	}
    216 }