View Javadoc

1   /*
2    * Copyright 2002-2004 The Apache Software Foundation
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, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.clazz.reflect.common;
17  
18  import java.lang.reflect.Method;
19  import java.util.List;
20  
21  import org.apache.commons.clazz.Clazz;
22  import org.apache.commons.clazz.reflect.ReflectedClazz;
23  
24  /**
25   * Holds parse results for individual accessor methods for a 
26   * list property.
27   * 
28   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
29   * @version $Id: ReflectedListPropertyParseResults.java 155436 2005-02-26 13:17:48Z dirkv $
30   */
31  public class ReflectedListPropertyParseResults 
32              extends ReflectedPropertyParseResults
33  {
34      private AccessorMethodParseResults getMethodParseResults;
35      private AccessorMethodParseResults setMethodParseResults;
36      private AccessorMethodParseResults addMethodParseResults;
37      private AccessorMethodParseResults addIndexedMethodParseResults;
38      private AccessorMethodParseResults removeMethodParseResults;
39      private AccessorMethodParseResults removeIndexedMethodParseResults;
40      
41      private AccessorMethodParseResults sizeMethodParseResults;
42      
43  
44      /**
45       * Constructor for ReflectedMappedPropertyParseResults.
46       */
47      public ReflectedListPropertyParseResults(
48              ReflectedClazz clazz, String propertyName) 
49      {
50          super(clazz, propertyName);
51      }
52      
53      protected String getPropertyCategory() {
54          return "list";
55      }
56      
57      /**
58       * Returns <code>true</code> if the property is an array or 
59       * implements java.util.List.
60       */
61      public boolean isList() {
62          if (readMethodParseResults != null
63              && isList(readMethodParseResults.getType())) {
64              return true;
65          }
66          if (writeMethodParseResults != null
67              && isList(writeMethodParseResults.getType())) {
68              return true;
69          }
70          return false;
71      }
72          
73      /**
74       * Returns <code>true</code> if javaClass is an array or 
75       * implements java.util.List.
76       */
77      protected boolean isList(Class javaClass) {
78          return javaClass != null
79              && (List.class.isAssignableFrom(javaClass) || javaClass.isArray());
80      }
81      
82      /**
83       * Returns the type of the list/array element, if known. 
84       * Returns <code>null</code> otherwise.
85       */
86      public Class getContentType() {
87          if (getMethodParseResults != null) {
88              return getMethodParseResults.getType();
89          }
90          if (setMethodParseResults != null) {
91              return setMethodParseResults.getType();
92          }
93          if (addMethodParseResults != null) {
94              return addMethodParseResults.getType();
95          }
96          if (addIndexedMethodParseResults != null) {
97              return addIndexedMethodParseResults.getType();
98          }
99          if (removeMethodParseResults != null) {
100             return removeMethodParseResults.getType();
101         }
102         if (readMethodParseResults != null) {
103             Class type = readMethodParseResults.getType();
104             if (type.isArray()) {
105                 return type.getComponentType();
106             }
107         }
108         if (writeMethodParseResults != null) {
109             Class type = writeMethodParseResults.getType();
110             if (type.isArray()) {
111                 return type.getComponentType();
112             }
113         }
114         return null;
115     }
116 
117     public void setGetMethodParseResults(
118                 AccessorMethodParseResults getMethodParseResults) 
119     {
120         checkForExtraneousAccessor(
121             this.getMethodParseResults,
122             getMethodParseResults);
123         this.getMethodParseResults = getMethodParseResults;
124     }
125 
126     public Method getGetMethod() {
127         if (getMethodParseResults == null) {
128             return null;
129         }
130         return getMethodParseResults.getMethod();
131     }
132     
133     public void setSetMethodParseResults(
134                 AccessorMethodParseResults setMethodParseResults) 
135     {
136         checkForExtraneousAccessor(
137             this.setMethodParseResults,
138             setMethodParseResults);
139         this.setMethodParseResults = setMethodParseResults;
140     }
141 
142     public Method getSetMethod() {
143         if (setMethodParseResults == null) {
144             return null;
145         }
146         return setMethodParseResults.getMethod();
147     }
148     
149     public void setAddMethodParseResults(
150                 AccessorMethodParseResults addMethodParseResults) 
151     {
152         checkForExtraneousAccessor(
153             this.addMethodParseResults,
154             addMethodParseResults);
155         this.addMethodParseResults = addMethodParseResults;
156     }
157 
158     public Method getAddMethod() {
159         if (addMethodParseResults == null) {
160             return null;
161         }
162         return addMethodParseResults.getMethod();
163     }
164     
165     public void setAddIndexedMethodParseResults(
166                 AccessorMethodParseResults addIndexedMethodParseResults) 
167     {
168         checkForExtraneousAccessor(
169             this.addIndexedMethodParseResults,
170             addIndexedMethodParseResults);
171         this.addIndexedMethodParseResults = addIndexedMethodParseResults;
172     }
173     
174     public Method getAddIndexedMethod() {
175         if (addIndexedMethodParseResults == null) {
176             return null;
177         }
178         return addIndexedMethodParseResults.getMethod();
179     }
180         
181     public void setRemoveMethodParseResults(
182                 AccessorMethodParseResults removeMethodParseResults) 
183     {
184         checkForExtraneousAccessor(
185             this.removeMethodParseResults,
186             removeMethodParseResults);
187         this.removeMethodParseResults = removeMethodParseResults;
188     }
189     
190     public Method getRemoveMethod() {
191         if (removeMethodParseResults == null) {
192             return null;
193         }
194         return removeMethodParseResults.getMethod();
195     }
196     
197     public void setRemoveIndexedMethodParseResults(
198                 AccessorMethodParseResults removeIndexedMethodParseResults)
199     {
200         checkForExtraneousAccessor(
201             this.removeIndexedMethodParseResults,
202             removeIndexedMethodParseResults);
203         this.removeIndexedMethodParseResults = removeIndexedMethodParseResults;
204     }
205 
206     public Method getRemoveIndexedMethod() {
207         if (removeIndexedMethodParseResults == null) {
208             return null;
209         }
210         return removeIndexedMethodParseResults.getMethod();
211     }
212 
213 
214     public void setSizeMethodParseResults(
215                 AccessorMethodParseResults sizeMethodParseResults) 
216     {
217         checkForExtraneousAccessor(
218             this.sizeMethodParseResults,
219             sizeMethodParseResults);
220         this.sizeMethodParseResults = sizeMethodParseResults;
221     }
222     
223     public Method getSizeMethod() {
224         if (sizeMethodParseResults == null) {
225             return null;
226         }
227         return sizeMethodParseResults.getMethod();
228     }
229     
230     /**
231      * Combines parse results from another instance of 
232      * <code>ReflectedMappedPropertyParseResults</code> with
233      * results contained by this object.
234      * <p>
235      * Node that the property name is not copied from the 
236      * <code>other</code> object.
237      */        
238     public void merge(ReflectedListPropertyParseResults other) {
239         super.merge(other);
240         if (other.readMethodParseResults != null) {
241             setReadMethodParseResults(other.readMethodParseResults);
242         }
243         if (other.writeMethodParseResults != null) {
244             setWriteMethodParseResults(other.writeMethodParseResults);
245         }
246         if (other.getMethodParseResults != null) {
247             setGetMethodParseResults(other.getMethodParseResults);
248         }
249         if (other.setMethodParseResults != null) {
250             setSetMethodParseResults(other.setMethodParseResults);
251         }
252         if (other.addMethodParseResults != null) {
253             setAddMethodParseResults(other.addMethodParseResults);
254         }
255         if (other.addIndexedMethodParseResults != null) {
256             setAddIndexedMethodParseResults(other.addIndexedMethodParseResults);
257         }
258         if (other.removeMethodParseResults != null) {
259             setRemoveMethodParseResults(other.removeMethodParseResults);
260         }
261         if (other.sizeMethodParseResults != null) {
262             setSizeMethodParseResults(other.sizeMethodParseResults);
263         }
264     }
265     
266     protected void appendDescription(StringBuffer buffer) {
267         super.appendDescription(buffer);
268         Class contentType = getContentType();
269         if (contentType != null) {
270             buffer.append("\n  [content type]   ");
271             buffer.append(Clazz.getCanonicalClassName(contentType));
272         }
273     }
274     
275     protected void appendMethodDescriptions(StringBuffer buffer) {
276         super.appendMethodDescriptions(buffer);
277         if (getMethodParseResults != null) {
278             buffer.append("\n    [get~(int)]    ");
279             buffer.append(getMethodParseResults.getMethod());
280         }
281         if (setMethodParseResults != null) {
282             buffer.append("\n    [set~(int,v)]  ");
283             buffer.append(setMethodParseResults.getMethod());
284         }
285         if (addMethodParseResults != null) {
286             buffer.append("\n    [add~(v)]      ");
287             buffer.append(addMethodParseResults.getMethod());
288         }
289         if (addIndexedMethodParseResults != null) {
290             buffer.append("\n    [add~(int,v)]  ");
291             buffer.append(addIndexedMethodParseResults.getMethod());
292         }
293         if (removeMethodParseResults != null) {
294             buffer.append("\n    [remove~(v)]   ");
295             buffer.append(removeMethodParseResults.getMethod());
296         }
297         if (removeIndexedMethodParseResults != null) {
298             buffer.append("\n    [remove~(i)]   ");
299             buffer.append(removeIndexedMethodParseResults.getMethod());
300         }
301         if (sizeMethodParseResults != null) {
302             buffer.append("\n    [get~Count()]  ");
303             buffer.append(sizeMethodParseResults.getMethod());
304         }
305     }
306     
307     public boolean checkConsistency() {        
308         if (!super.checkConsistency()) {
309             return false;
310         }
311                 
312         if (readMethodParseResults == null && getMethodParseResults == null) {
313             return false;
314         }
315 
316         if (readMethodParseResults != null) {
317             Class type = readMethodParseResults.getType();
318             if (writeMethodParseResults != null) {
319                 if (!type.equals(writeMethodParseResults.getType())) {
320                     return false;
321                 }
322             }
323         }
324                 
325         Class contentType = null;
326          
327         if (getMethodParseResults != null) {
328             contentType = getMethodParseResults.getType();
329         }
330         
331         if (setMethodParseResults != null) {
332             if (contentType == null) {
333                 contentType = setMethodParseResults.getType();
334             }
335             else {
336                 if (!contentType.equals(setMethodParseResults.getType())) {
337                     return false;
338                 }
339             }
340         }
341         
342         if (addMethodParseResults != null) {
343             if (contentType == null) {
344                 contentType = addMethodParseResults.getType();
345             }
346             else {
347                 if (!contentType.equals(addMethodParseResults.getType())) {
348                     return false;
349                 }
350             }
351         }
352         
353         if (addIndexedMethodParseResults != null) {
354             if (contentType == null) {
355                 contentType = addIndexedMethodParseResults.getType();
356             }
357             else {
358                 if (!contentType.equals(
359                         addIndexedMethodParseResults.getType())) {
360                     return false;
361                 }
362             }
363         }
364         
365         if (removeMethodParseResults != null) {
366             if (contentType != null) {
367                 if (!contentType.equals(removeMethodParseResults.getType())) {
368                     return false;
369                 }
370             }
371         }
372         
373         return true;
374     }
375         
376     protected boolean appendInconsistencyDescriptions(StringBuffer buffer) {
377         if (!super.appendInconsistencyDescriptions(buffer)) {
378             return false;
379         }        
380         
381         if (readMethodParseResults == null && getMethodParseResults == null) {
382             buffer.append(
383                 "\n     - Does not have either get() or get(int) method");
384             return true;
385         }
386 
387         if (readMethodParseResults != null) {
388             Class type = readMethodParseResults.getType();
389             if (writeMethodParseResults != null) {
390                 if (!type.equals(writeMethodParseResults.getType())) {
391                     buffer.append(
392                         "\n     - Get() and set(v) types do not match");
393                 }
394             }
395         }
396         
397         Class contentType = null;
398          
399         if (getMethodParseResults != null) {
400             contentType = getMethodParseResults.getType();
401         }
402         
403         if (setMethodParseResults != null) {
404             if (contentType == null) {
405                 contentType = setMethodParseResults.getType();
406             }
407             else {
408                 if (!contentType.equals(setMethodParseResults.getType())) {
409                     buffer.append(
410                         "\n     - Content type mismatch between "
411                             + "get(int) and set(int,v)");
412                 }
413             }
414         }
415         
416         if (addMethodParseResults != null) {
417             if (contentType == null) {
418                 contentType = addMethodParseResults.getType();
419             }
420             else {
421                 if (!contentType.equals(addMethodParseResults.getType())) {
422                     buffer.append(
423                         "\n     - Content type mismatch between "
424                             + "get(int) and add(v)");
425                 }
426             }
427         }
428         
429         if (addIndexedMethodParseResults != null) {
430             if (contentType == null) {
431                 contentType = addIndexedMethodParseResults.getType();
432             }
433             else {
434                 if (!contentType.equals(
435                         addIndexedMethodParseResults.getType())) {
436                     buffer.append(
437                         "\n     - Content type mismatch between "
438                             + "get(int) and add(int,v)");
439                 }
440             }
441         }
442         
443         if (removeMethodParseResults != null) {
444             if (contentType != null) {
445                 Class removeType = removeMethodParseResults.getType(); 
446                 if (removeType != null && !contentType.equals(removeType)) {
447                     buffer.append(
448                         "\n     - Content type mismatch between "
449                             + "get(int) and remove(v)");
450                 }
451             }
452         }        
453         return true;
454     }  
455 }