View Javadoc

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