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.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.clazz.Clazz;
23  import org.apache.commons.clazz.reflect.ReflectedClazz;
24  
25  /**
26   * Base class for <code>Reflected*PropertyParseResults</code> classes;
27   * aggregates parse results for individual accessor methods.
28   * 
29   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
30   * @version $Id: ReflectedPropertyParseResults.java 155436 2005-02-26 13:17:48Z dirkv $
31   */
32  public abstract class ReflectedPropertyParseResults implements Comparable {
33      private ReflectedClazz clazz;
34      private String propertyName;
35      private List aliases;
36  
37      protected AccessorMethodParseResults readMethodParseResults;
38      protected AccessorMethodParseResults writeMethodParseResults;
39      protected List extraneousAccessors;
40  
41      private static final String[] EMPTY_STRING_ARRAY = new String[0];
42  
43      public ReflectedPropertyParseResults(
44          ReflectedClazz clazz,
45          String propertyName) 
46      {
47          this.clazz = clazz;
48          this.propertyName = propertyName;
49      }
50  
51      public ReflectedClazz getClazz() {
52          return clazz;
53      }
54  
55      /**
56       * Returns the propertyName.
57       * @return String
58       */
59      public String getPropertyName() {
60          return propertyName;
61      }
62  
63      public int compareTo(Object object) {
64          String n1 = getPropertyName();
65          String n2 = ((ReflectedPropertyParseResults) object).getPropertyName();
66          return n1.compareTo(n2);
67      }
68  
69      public String[] getAliases() {
70          if (aliases == null) {
71              return EMPTY_STRING_ARRAY;
72          }
73          return (String[]) aliases.toArray(EMPTY_STRING_ARRAY);
74      }
75  
76      public void addAlias(String alias) {
77          if (!alias.equals(propertyName)) {
78              if (aliases == null) {
79                  aliases = new ArrayList();
80                  aliases.add(alias);
81              }
82              else if (!aliases.contains(alias)) {
83                  aliases.add(alias);
84              }
85          }
86      }
87  
88      protected abstract String getPropertyCategory();
89  
90      public void merge(ReflectedPropertyParseResults other) {
91          addAlias(other.getPropertyName());
92          String[] aliases = other.getAliases();
93          for (int i = 0; i < aliases.length; i++) {
94              addAlias(aliases[i]);
95          }
96      }
97  
98      public Class getPropertyType() {
99          if (readMethodParseResults != null) {
100             return readMethodParseResults.getType();
101         }
102         if (writeMethodParseResults != null) {
103             return writeMethodParseResults.getType();
104         }
105         return null;
106     }
107 
108     public Method getReadMethod() {
109         if (readMethodParseResults == null) {
110             return null;
111         }
112         return readMethodParseResults.getMethod();
113     }
114 
115     public Method getWriteMethod() {
116         if (writeMethodParseResults == null) {
117             return null;
118         }
119         return writeMethodParseResults.getMethod();
120     }
121 
122     /**
123      * Sets the readMethodParseResults.
124      * @param readMethodParseResults The readMethodParseResults to set
125      */
126     public void setReadMethodParseResults(
127             AccessorMethodParseResults readMethodParseResults) 
128     {
129         checkForExtraneousAccessor(
130             this.readMethodParseResults,
131             readMethodParseResults);
132         this.readMethodParseResults = readMethodParseResults;
133     }
134 
135     /**
136      * Sets the writeMethodParseResults.
137      * @param writeMethodParseResults The writeMethodParseResults to set
138      */
139     public void setWriteMethodParseResults(
140             AccessorMethodParseResults writeMethodParseResults) 
141     {
142         checkForExtraneousAccessor(
143             this.writeMethodParseResults,
144             writeMethodParseResults);
145         this.writeMethodParseResults = writeMethodParseResults;
146     }
147 
148     /**
149      * Checks if there is an existing parse result recorded and if
150      * so saves it into the extraneousAccessors for error reporting.
151      */
152     protected void checkForExtraneousAccessor(
153         AccessorMethodParseResults currentValue,
154         AccessorMethodParseResults newValue) 
155     {
156         if (currentValue != null
157             && newValue != null
158             && currentValue != newValue) {
159             if (extraneousAccessors == null) {
160                 extraneousAccessors = new ArrayList();
161                 extraneousAccessors.add(currentValue);
162             }
163         }
164     }
165 
166     public boolean checkConsistency() {
167         if (extraneousAccessors != null) {
168             return false;
169         }
170 
171         return true;
172     }
173 
174     public String toString() {
175         boolean consistent = checkConsistency();
176 
177         StringBuffer buffer = new StringBuffer();
178         buffer.append("[");
179         if (consistent) {
180             buffer.append(propertyName);
181             if (!getPropertyCategory().equals("scalar")) {
182                 buffer.append(" (");
183                 buffer.append(getPropertyCategory());
184                 buffer.append(")");
185             }
186         }
187         else {
188             buffer.append("*");
189             buffer.append(propertyName);
190             buffer.append(" - NOT a ");
191             if (!getPropertyCategory().equals("scalar")) {
192                 buffer.append(getPropertyCategory());
193             }
194             buffer.append(" property");
195             appendInconsistencyDescriptions(buffer);
196         }
197         if (aliases != null) {
198             buffer.append("\n  [aliases: ");
199             for (int i = 0; i < aliases.size(); i++) {
200                 if (i != 0) {
201                     buffer.append(", ");
202                 }
203                 buffer.append(aliases.get(i));
204             }
205             buffer.append("]");
206         }
207         appendDescription(buffer);
208         buffer.append("\n  [accessor methods:");
209         appendMethodDescriptions(buffer);
210         buffer.append("\n  ]");
211         buffer.append("\n]");
212         return buffer.toString();
213     }
214 
215     protected void appendDescription(StringBuffer buffer) {
216         Class type = getPropertyType();
217         if (type != null) {
218             buffer.append("\n  [type]           ");
219             buffer.append(Clazz.getCanonicalClassName(type));
220         }
221     }
222 
223     protected void appendMethodDescriptions(StringBuffer buffer) {
224         if (readMethodParseResults != null) {
225             buffer.append("\n    [get~()]       ");
226             buffer.append(readMethodParseResults.getMethod());
227         }
228         if (writeMethodParseResults != null) {
229             buffer.append("\n    [set~(v)]      ");
230             buffer.append(writeMethodParseResults.getMethod());
231         }
232     }
233 
234     protected boolean appendInconsistencyDescriptions(StringBuffer buffer) {
235         if (extraneousAccessors != null) {
236             buffer.append("\n     - Has extraneous accessors:");
237             for (int i = 0; i < extraneousAccessors.size(); i++) {
238                 AccessorMethodParseResults results =
239                     (AccessorMethodParseResults) extraneousAccessors.get(i);
240                 buffer.append("\n         ");
241                 buffer.append(results.getMethod());
242             }
243         }
244         return true;
245     }
246 }