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.common;
017
018 import java.lang.reflect.Method;
019 import java.util.ArrayList;
020 import java.util.List;
021
022 import org.apache.commons.clazz.Clazz;
023 import org.apache.commons.clazz.reflect.ReflectedClazz;
024
025 /**
026 * Base class for <code>Reflected*PropertyParseResults</code> classes;
027 * aggregates parse results for individual accessor methods.
028 *
029 * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
030 * @version $Id: ReflectedPropertyParseResults.java 155436 2005-02-26 13:17:48Z dirkv $
031 */
032 public abstract class ReflectedPropertyParseResults implements Comparable {
033 private ReflectedClazz clazz;
034 private String propertyName;
035 private List aliases;
036
037 protected AccessorMethodParseResults readMethodParseResults;
038 protected AccessorMethodParseResults writeMethodParseResults;
039 protected List extraneousAccessors;
040
041 private static final String[] EMPTY_STRING_ARRAY = new String[0];
042
043 public ReflectedPropertyParseResults(
044 ReflectedClazz clazz,
045 String propertyName)
046 {
047 this.clazz = clazz;
048 this.propertyName = propertyName;
049 }
050
051 public ReflectedClazz getClazz() {
052 return clazz;
053 }
054
055 /**
056 * Returns the propertyName.
057 * @return String
058 */
059 public String getPropertyName() {
060 return propertyName;
061 }
062
063 public int compareTo(Object object) {
064 String n1 = getPropertyName();
065 String n2 = ((ReflectedPropertyParseResults) object).getPropertyName();
066 return n1.compareTo(n2);
067 }
068
069 public String[] getAliases() {
070 if (aliases == null) {
071 return EMPTY_STRING_ARRAY;
072 }
073 return (String[]) aliases.toArray(EMPTY_STRING_ARRAY);
074 }
075
076 public void addAlias(String alias) {
077 if (!alias.equals(propertyName)) {
078 if (aliases == null) {
079 aliases = new ArrayList();
080 aliases.add(alias);
081 }
082 else if (!aliases.contains(alias)) {
083 aliases.add(alias);
084 }
085 }
086 }
087
088 protected abstract String getPropertyCategory();
089
090 public void merge(ReflectedPropertyParseResults other) {
091 addAlias(other.getPropertyName());
092 String[] aliases = other.getAliases();
093 for (int i = 0; i < aliases.length; i++) {
094 addAlias(aliases[i]);
095 }
096 }
097
098 public Class getPropertyType() {
099 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 }