001 /*
002 * Copyright 2002-2004 The Apache Software Foundation
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.apache.commons.clazz.reflect.extended;
017
018 import java.lang.reflect.Method;
019 import java.util.Map;
020
021 import org.apache.commons.clazz.Clazz;
022 import org.apache.commons.clazz.reflect.ReflectedClazz;
023 import org.apache.commons.clazz.reflect.common.AccessorMethodParseResults;
024 import org.apache.commons.clazz.reflect.common.ReflectedPropertyParseResults;
025
026 /**
027 * Holds parse results for individual accessor methods for a
028 * mapped property.
029 *
030 * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
031 * @version $Id: ReflectedMappedPropertyParseResults.java 155436 2005-02-26 13:17:48Z dirkv $
032 */
033 public class ReflectedMappedPropertyParseResults
034 extends ReflectedPropertyParseResults
035 {
036 private AccessorMethodParseResults getMethodParseResults;
037 private AccessorMethodParseResults putMethodParseResults;
038 private AccessorMethodParseResults removeMethodParseResults;
039 private AccessorMethodParseResults keySetMethodParseResults;
040
041 /**
042 * Constructor for ReflectedMappedPropertyParseResults.
043 */
044 public ReflectedMappedPropertyParseResults(
045 ReflectedClazz clazz, String propertyName)
046 {
047 super(clazz, propertyName);
048 }
049
050 protected String getPropertyCategory() {
051 return "mapped";
052 }
053
054 /**
055 * Returns <code>true</code> if the property is
056 * java.util.Map or implements java.util.Map.
057 */
058 protected boolean isMap() {
059 if (readMethodParseResults != null
060 && isMap(readMethodParseResults.getType())) {
061 return true;
062 }
063 if (writeMethodParseResults != null
064 && isMap(writeMethodParseResults.getType())) {
065 return true;
066 }
067 return false;
068 }
069
070 private boolean isMap(Class javaClass) {
071 return javaClass != null && Map.class.isAssignableFrom(javaClass);
072 }
073
074 public Class getKeyType() {
075 if (getMethodParseResults != null) {
076 return getMethodParseResults.getParameterType();
077 }
078 if (putMethodParseResults != null) {
079 return putMethodParseResults.getParameterType();
080 }
081 if (removeMethodParseResults != null) {
082 return removeMethodParseResults.getParameterType();
083 }
084 return null;
085 }
086
087 public Class getContentType() {
088 if (getMethodParseResults != null) {
089 return getMethodParseResults.getType();
090 }
091 if (putMethodParseResults != null) {
092 return putMethodParseResults.getType();
093 }
094 if (removeMethodParseResults != null) {
095 return removeMethodParseResults.getType();
096 }
097 return null;
098
099 }
100
101 public void setGetMethodParseResults(
102 AccessorMethodParseResults getMethodParseResults)
103 {
104 checkForExtraneousAccessor(
105 this.getMethodParseResults,
106 getMethodParseResults);
107 this.getMethodParseResults = getMethodParseResults;
108 }
109
110 public Method getGetMethod() {
111 if (getMethodParseResults == null) {
112 return null;
113 }
114 return getMethodParseResults.getMethod();
115 }
116
117
118 public void setPutMethodParseResults(
119 AccessorMethodParseResults putMethodParseResults)
120 {
121 checkForExtraneousAccessor(
122 this.putMethodParseResults,
123 putMethodParseResults);
124 this.putMethodParseResults = putMethodParseResults;
125 }
126
127 public Method getPutMethod() {
128 if (putMethodParseResults == null) {
129 return null;
130 }
131 return putMethodParseResults.getMethod();
132 }
133
134 public void setRemoveMethodParseResults(
135 AccessorMethodParseResults removeMethodParseResults)
136 {
137 checkForExtraneousAccessor(
138 this.removeMethodParseResults,
139 removeMethodParseResults);
140 this.removeMethodParseResults = removeMethodParseResults;
141 }
142
143 public Method getRemoveMethod() {
144 if (removeMethodParseResults == null) {
145 return null;
146 }
147 return removeMethodParseResults.getMethod();
148 }
149
150 public void setKeySetMethodParseResults(
151 AccessorMethodParseResults keySetMethodParseResults)
152 {
153 checkForExtraneousAccessor(
154 this.keySetMethodParseResults,
155 keySetMethodParseResults);
156 this.keySetMethodParseResults = keySetMethodParseResults;
157 }
158
159 public Method getKeySetMethod() {
160 if (keySetMethodParseResults == null) {
161 return null;
162 }
163 return keySetMethodParseResults.getMethod();
164 }
165
166 /**
167 * Combines parse results from another instance of
168 * <code>ReflectedMappedPropertyParseResults</code> with
169 * results contained by this object.
170 * <p>
171 * Node that the property name is not copied from the
172 * <code>other</code> object.
173 */
174 public void merge(ReflectedMappedPropertyParseResults other) {
175 super.merge(other);
176 if (other.readMethodParseResults != null) {
177 setReadMethodParseResults(other.readMethodParseResults);
178 }
179 if (other.writeMethodParseResults != null) {
180 setWriteMethodParseResults(other.writeMethodParseResults);
181 }
182 if (other.getMethodParseResults != null) {
183 setGetMethodParseResults(other.getMethodParseResults);
184 }
185 if (other.putMethodParseResults != null) {
186 setPutMethodParseResults(other.putMethodParseResults);
187 }
188 if (other.removeMethodParseResults != null) {
189 setRemoveMethodParseResults(other.removeMethodParseResults);
190 }
191 if (other.keySetMethodParseResults != null) {
192 setKeySetMethodParseResults(other.keySetMethodParseResults);
193 }
194 }
195
196 protected void appendDescription(StringBuffer buffer) {
197 super.appendDescription(buffer);
198 Class keyType = getKeyType();
199 if (keyType != null) {
200 buffer.append("\n [key type] ");
201 buffer.append(Clazz.getCanonicalClassName(keyType));
202 }
203
204 Class contentType = getContentType();
205 if (contentType != null) {
206 buffer.append("\n [content type] ");
207 buffer.append(Clazz.getCanonicalClassName(contentType));
208 }
209 }
210
211 protected void appendMethodDescriptions(StringBuffer buffer) {
212 super.appendMethodDescriptions(buffer);
213 if (getMethodParseResults != null) {
214 buffer.append("\n [get~(key)] ");
215 buffer.append(getMethodParseResults.getMethod());
216 }
217 if (putMethodParseResults != null) {
218 buffer.append("\n [set~(key,v)] ");
219 buffer.append(putMethodParseResults.getMethod());
220 }
221 if (removeMethodParseResults != null) {
222 buffer.append("\n [remove~(key)] ");
223 buffer.append(removeMethodParseResults.getMethod());
224 }
225 if (keySetMethodParseResults != null) {
226 buffer.append("\n [get~KeySet()] ");
227 buffer.append(keySetMethodParseResults.getMethod());
228 }
229 }
230
231 public boolean checkConsistency() {
232 if (!super.checkConsistency()) {
233 return false;
234 }
235
236 if (readMethodParseResults == null && getMethodParseResults == null) {
237 return false;
238 }
239
240 if (readMethodParseResults != null) {
241 Class type = readMethodParseResults.getType();
242 if (writeMethodParseResults != null) {
243 if (!type.equals(writeMethodParseResults.getType())) {
244 return false;
245 }
246 }
247 }
248
249 Class keyType = null;
250 Class contentType = null;
251
252 if (getMethodParseResults != null) {
253 keyType = getMethodParseResults.getParameterType();
254 contentType = getMethodParseResults.getType();
255 }
256
257 if (putMethodParseResults != null) {
258 if (keyType == null) {
259 keyType = putMethodParseResults.getParameterType();
260 }
261 else {
262 if (!keyType.equals(putMethodParseResults.getParameterType())) {
263 return false;
264 }
265 }
266
267 if (contentType == null) {
268 contentType = putMethodParseResults.getType();
269 }
270 else {
271 if (!contentType.equals(
272 putMethodParseResults.getType())) {
273 return false;
274 }
275 }
276 }
277
278 if (removeMethodParseResults != null) {
279 if (keyType != null
280 && !keyType.
281 equals(removeMethodParseResults.getParameterType())) {
282 return false;
283 }
284
285 if (contentType != null) {
286 Class removeType = removeMethodParseResults.getType();
287 if (removeType != null && !contentType.equals(removeType)) {
288 return false;
289 }
290 }
291 }
292
293 return true;
294 }
295
296 protected boolean appendInconsistencyDescriptions(StringBuffer buffer) {
297 if (!super.appendInconsistencyDescriptions(buffer)) {
298 return false;
299 }
300
301 if (readMethodParseResults == null && getMethodParseResults == null) {
302 buffer.append(
303 "\n - Does not have either get() or get(key) method");
304 return true;
305 }
306
307 if (readMethodParseResults != null) {
308 Class type = readMethodParseResults.getType();
309 if (writeMethodParseResults != null) {
310 if (!type.equals(writeMethodParseResults.getType())) {
311 buffer.append(
312 "\n - Get() and set(v) types do not match");
313 }
314 }
315 }
316
317 Class keyType = null;
318 Class contentType = null;
319
320 if (getMethodParseResults != null) {
321 keyType = getMethodParseResults.getParameterType();
322 contentType = getMethodParseResults.getType();
323 }
324
325 if (putMethodParseResults != null) {
326 if (keyType == null) {
327 keyType = putMethodParseResults.getParameterType();
328 }
329 else {
330 if (!keyType.equals(putMethodParseResults.getParameterType())) {
331 buffer.append(
332 "\n - Key type mismatch between "
333 + "get(key) and set(key,v)");
334 }
335 }
336
337 if (contentType == null) {
338 contentType = putMethodParseResults.getType();
339 }
340 else {
341 if (!contentType.equals(
342 putMethodParseResults.getType())) {
343 buffer.append(
344 "\n - Content type mismatch between "
345 + "get(key) and set(key,v)");
346 }
347 }
348 }
349
350 if (removeMethodParseResults != null) {
351 if (keyType != null
352 && !keyType.
353 equals(removeMethodParseResults.getParameterType())) {
354 buffer.append(
355 "\n - Key type mismatch between "
356 + "get(key) and remove(key)");
357 }
358
359 if (contentType != null) {
360 Class removeType = removeMethodParseResults.getType();
361 if (removeType != null && !contentType.equals(removeType)) {
362 buffer.append(
363 "\n - Content type mismatch between "
364 + "get(key) and set(key,v)");
365 }
366 }
367 }
368 return true;
369 }
370 }