001package org.andromda.cartridges.meta.metafacades; 002 003import java.util.ArrayList; 004import java.util.Collection; 005import java.util.Iterator; 006import java.util.List; 007 008/** 009 * @author <a href="http://www.mbohlen.de">Matthias Bohlen </a> 010 * @author Chad Brandon 011 * @author Cyril Combe 012 * @since 10.12.2003 013 */ 014public class MethodData implements Comparable 015{ 016 private String metafacadeName; 017 private String visibility; 018 private boolean isAbstract; 019 private String name; 020 private String returnTypeName; 021 private String documentation; 022 private final List<ArgumentData> arguments = new ArrayList<ArgumentData>(); 023 private final List<String> exceptions = new ArrayList<String>(); 024 025 /** 026 * @param metafacadeNameIn 027 * @param visibilityIn 028 * @param isAbstractIn 029 * @param returnTypeNameIn 030 * @param nameIn 031 * @param documentationIn 032 */ 033 public MethodData( 034 String metafacadeNameIn, 035 String visibilityIn, 036 boolean isAbstractIn, 037 String returnTypeNameIn, 038 String nameIn, 039 String documentationIn) 040 { 041 this.metafacadeName = metafacadeNameIn; 042 this.visibility = visibilityIn; 043 this.isAbstract = isAbstractIn; 044 this.name = nameIn; 045 this.returnTypeName = returnTypeNameIn; 046 this.documentation = documentationIn; 047 } 048 049 /** 050 * @param argument 051 */ 052 public void addArgument(ArgumentData argument) 053 { 054 this.arguments.add(argument); 055 } 056 057 /** 058 * @return arguments 059 */ 060 public Collection<ArgumentData> getArguments() 061 { 062 return this.arguments; 063 } 064 065 /** 066 * @param typeName 067 */ 068 public void addException(String typeName) 069 { 070 this.exceptions.add(typeName); 071 } 072 073 /** 074 * @return exceptions 075 */ 076 public Collection<String> getExceptions() 077 { 078 return this.exceptions; 079 } 080 081 /** 082 * Gets the metafacade name. 083 * 084 * @return the name of the metafacade 085 */ 086 public String getMetafacadeName() 087 { 088 return this.metafacadeName; 089 } 090 091 /** 092 * Gets the name of the method. 093 * 094 * @return the name. 095 */ 096 public String getName() 097 { 098 return this.name; 099 } 100 101 /** 102 * Gets the name of the return type for this method. 103 * 104 * @return the return type name. 105 */ 106 public String getReturnTypeName() 107 { 108 return this.returnTypeName; 109 } 110 111 /** 112 * Builds a string representing a declaration for this method. 113 * 114 * @param suppressAbstractDeclaration 115 * optionally suppress the "abstract" modifier 116 * @return String the declaration 117 */ 118 public String buildMethodDeclaration(boolean suppressAbstractDeclaration) 119 { 120 String declaration = this.visibility + ' ' 121 + ((this.isAbstract && !suppressAbstractDeclaration) ? "abstract " : "") 122 + ((this.returnTypeName != null) ? (this.returnTypeName + ' ') : "") + this.name + '('; 123 124 declaration += getTypedArgumentList(); 125 /*for (final Iterator iterator = this.arguments.iterator(); iterator.hasNext();) 126 { 127 final ArgumentData argument = (ArgumentData)iterator.next(); 128 declaration += (argument.getFullyQualifiedTypeName() + " " + argument.getName()); 129 if (iterator.hasNext()) 130 { 131 declaration += ", "; 132 } 133 }*/ 134 declaration += ')'; 135 136 if (!this.exceptions.isEmpty()) 137 { 138 declaration += " throws "; 139 for (final Iterator<String> iterator = this.exceptions.iterator(); iterator.hasNext();) 140 { 141 String exception = iterator.next(); 142 declaration += exception; 143 if (iterator.hasNext()) 144 { 145 declaration += ", "; 146 } 147 } 148 } 149 150 return declaration; 151 } 152 153 /** 154 * Builds a string representing a comma separated parameter type + name list. 155 * 156 * @return String the declaration 157 */ 158 public String getTypedArgumentList() 159 { 160 return getTypedArgumentList(null); 161 } 162 163 /** 164 * Builds a string representing a comma separated parameter type + name list. 165 * 166 * @param modifier Optional modifier before each parameter 167 * @return String the declaration 168 */ 169 public String getTypedArgumentList(String modifier) 170 { 171 String declaration = ""; 172 173 for (final Iterator<ArgumentData> iterator = this.arguments.iterator(); iterator.hasNext();) 174 { 175 final ArgumentData argument = iterator.next(); 176 if (modifier!=null) 177 { 178 declaration += modifier + ' '; 179 } 180 declaration += (argument.getFullyQualifiedTypeName() + ' ' + argument.getName()); 181 if (iterator.hasNext()) 182 { 183 declaration += ", "; 184 } 185 } 186 return declaration; 187 } 188 189 /** 190 * Builds a string representing a call to the method. 191 * 192 * @return String how a call would look like 193 */ 194 public String buildMethodCall() 195 { 196 String call = getName() + '('; 197 198 for (final Iterator<ArgumentData> iterator = this.arguments.iterator(); iterator.hasNext();) 199 { 200 final ArgumentData argument = iterator.next(); 201 call += argument.getName(); 202 if (iterator.hasNext()) 203 { 204 call += ", "; 205 } 206 } 207 call += ')'; 208 return call; 209 } 210 211 /** 212 * Builds a signature which can be used as a key into a map. Consists of the methodName, number of arguments, 213 * return type, the name and the f.q. types of the arguments. 214 * 215 * @return String the key that identifies this method 216 */ 217 public String buildCharacteristicKey() 218 { 219 String key = ((this.returnTypeName != null) ? (this.returnTypeName + ' ') : "") + this.name + '('; 220 221 for (final Iterator<ArgumentData> iterator = this.arguments.iterator(); iterator.hasNext();) 222 { 223 final ArgumentData argument = iterator.next(); 224 key += argument.getFullyQualifiedTypeName(); 225 if (iterator.hasNext()) 226 { 227 key += ','; 228 } 229 } 230 key += ')'; 231 232 return key; 233 } 234 235 /** 236 * Indicates whether or not this method is abstract. 237 * 238 * @return true/false 239 */ 240 public boolean isAbstract() 241 { 242 return this.isAbstract; 243 } 244 245 /** 246 * Gets the visibility of this method. 247 * 248 * @return the visibility. 249 */ 250 public String getVisibility() 251 { 252 return this.visibility; 253 } 254 255 /** 256 * Gets the documentation for this method. 257 * 258 * @return the documentation. 259 */ 260 public String getDocumentation() 261 { 262 return this.documentation; 263 } 264 265 /** 266 * Tells if this method returns something. 267 * 268 * @return boolean 269 */ 270 public boolean isReturnTypePresent() 271 { 272 return this.returnTypeName != null && !"void".equals(this.returnTypeName); 273 } 274 275 /** 276 * @see Comparable#compareTo(Object) 277 */ 278 public int compareTo(final Object object) 279 { 280 MethodData other = (MethodData)object; 281 final int result = getMetafacadeName().compareTo(other.getMetafacadeName()); 282 283 // Use the characteristic key in order to have a deterministic order, starting with method name and number of arguments 284 return (result != 0) ? result : (name + arguments.size() + ", " + buildCharacteristicKey()) 285 .compareTo(other.getName() + other.getArguments().size() + ", " + other.buildCharacteristicKey()); 286 } 287 288 /** 289 * @see Object#toString() 290 */ 291 @Override 292 public String toString() 293 { 294 return this.buildMethodDeclaration(false); 295 } 296}