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 }