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 }