001 /* 002 Copyright (C) 2002-2003 Renaud Pawlak <renaud@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public 015 License along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 017 USA */ 018 019 package org.objectweb.jac.ide; 020 021 import java.io.File; 022 import java.util.Arrays; 023 import java.util.Collection; 024 import java.util.HashSet; 025 import java.util.Iterator; 026 import java.util.List; 027 import java.util.Map; 028 import java.util.Set; 029 import java.util.Vector; 030 import org.objectweb.jac.aspects.gui.DisplayContext; 031 import org.objectweb.jac.aspects.gui.HandlerResult; 032 import org.objectweb.jac.core.ObjectRepository; 033 import org.objectweb.jac.util.Strings; 034 035 /** 036 * This class represents a class meta element. 037 */ 038 public class Class extends Type { 039 040 public String getGenerationName() { 041 return Strings.toUSAscii(getName()); 042 } 043 044 Type superClass; 045 /** 046 * Get the value of superClass. 047 * @return value of superClass. 048 */ 049 public Type getSuperClass() { 050 return superClass; 051 } 052 /** 053 * Set the value of superClass. 054 * @param v Value to assign to superClass. 055 */ 056 public void setSuperClass(Type v) { 057 if (v!=superClass && superClass!=null) { 058 // Remove existing inheritance links from diagrams 059 // This should rather be done with an aspect 060 Collection diagrams = ObjectRepository.getObjects(Diagram.class); 061 Iterator it = diagrams.iterator(); 062 while(it.hasNext()) { 063 Diagram d = (Diagram)it.next(); 064 if (superClass instanceof Class) 065 d.removeInheritanceLink(this,(Class)superClass); 066 } 067 } 068 069 this.superClass = v; 070 } 071 072 /** 073 * Finds a field with a given name 074 * @param name field name 075 * @return a field with the given name, or null 076 */ 077 public Field findField(String name) { 078 Iterator it = getFields().iterator(); 079 while (it.hasNext()) { 080 Field f = (Field)it.next(); 081 if (f.getName().equals(name)) { 082 return f; 083 } 084 } 085 return null; 086 } 087 088 Vector fields = new Vector(); 089 /** 090 * Get the value of fields. 091 * @return value of fields. 092 */ 093 public List getFields() { 094 return fields; 095 } 096 public void addField(Field f) { 097 fields.add(f); 098 } 099 public void removeField(Field f) { 100 fields.remove(f); 101 } 102 103 /** 104 * Returns all fields, including inherited ones 105 */ 106 public List getAllFields() { 107 Vector result = new Vector(); 108 if (superClass instanceof Class) 109 result.addAll(((Class)superClass).getAllFields()); 110 result.addAll(getFields()); 111 return result; 112 } 113 114 Vector methods = new Vector(); 115 /** 116 * Get the value of methods. 117 * @return value of methods. 118 */ 119 public List getMethods() { 120 return methods; 121 } 122 public void addMethod(Method m) { 123 methods.add(m); 124 } 125 public void removeMethod(Method m) { 126 methods.remove(m); 127 } 128 public void addConstructor(Constructor c) { 129 methods.add(c); 130 } 131 132 /** 133 * Gets al methods, including specific 134 * getter,setters,adders,removers and clearers. 135 */ 136 public List getAllMethods() { 137 Vector allMethods = new Vector(); 138 allMethods.addAll(methods); 139 Method m; 140 Iterator it = fields.iterator(); 141 while (it.hasNext()) { 142 Field field = (Field)it.next(); 143 if ((m=field.getSetter())!=null) 144 allMethods.add(m); 145 if ((m=field.getGetter())!=null) 146 allMethods.add(m); 147 } 148 149 it = getNavigableRoles().iterator(); 150 while (it.hasNext()) { 151 RelationRole role = (RelationRole)it.next(); 152 if ((m=role.getGetter())!=null) 153 allMethods.add(m); 154 if ((m=role.getAdder())!=null) 155 allMethods.add(m); 156 if ((m=role.getRemover())!=null) 157 allMethods.add(m); 158 if ((m=role.getClearer())!=null) 159 allMethods.add(m); 160 } 161 return allMethods; 162 } 163 164 public List getInheritedMethods() { 165 if (superClass instanceof Class) { 166 List superMethods = ((Class)superClass).getAllMethods(); 167 List superInheritedMethods = ((Class)superClass).getInheritedMethods(); 168 superMethods.addAll(superInheritedMethods); 169 return superMethods; 170 } else { 171 return new Vector(); 172 } 173 } 174 175 public List getAbstractMethods() { 176 Vector abstractMethods = new Vector(); 177 Iterator i = methods.iterator(); 178 while (i.hasNext()) { 179 Method m = (Method)i.next(); 180 if (m.isAbstract()) { 181 Method m2 = findMethod(m); 182 if (m2==null || m2==m) 183 abstractMethods.add(m); 184 } 185 } 186 if (superClass instanceof Class) { 187 List superMethods = ((Class)superClass).getAbstractMethods(); 188 i = superMethods.iterator(); 189 while (i.hasNext()) { 190 Method m = (Method)i.next(); 191 Method m2 = findMethod(m); 192 if (m2==null || m2==m) 193 abstractMethods.add(m); 194 } 195 } 196 return abstractMethods; 197 } 198 199 /** 200 * Finds a method with a given name and parameters 201 * @param name method name 202 * @param parameters the types of the parameters. 203 * @return a method with the given name and parameter types, or null 204 * @see #findMethod(Method) 205 */ 206 public Method findMethod(String name, List parameters) { 207 Iterator it = getAllMethods().iterator(); 208 while (it.hasNext()) { 209 Method m = (Method)it.next(); 210 if (m.getName().equals(name)) { 211 if (Arrays.asList(m.getParameterTypes()).equals(parameters)) { 212 return m; 213 } 214 } 215 } 216 return null; 217 } 218 219 /** 220 * Finds a method with the same name and the same parameter types 221 * as a given method. 222 * @param method method whose name and parameter types must match 223 * @return a method with the same name and the same parameter types, or null 224 * @see #findMethod(String,List) 225 */ 226 public Method findMethod(Method method) { 227 return findMethod(method.getName(),Arrays.asList(method.getParameterTypes())); 228 } 229 230 public void addMethodIntf(Method m) { 231 addMethod(m); 232 } 233 234 public void removeMethodIntf(Method m) { 235 removeMethod(m); 236 } 237 238 /** 239 * Adds a "public static void main(String[] parameters)" method 240 */ 241 public void addMainMethod() { 242 Method main = new Method(); 243 main.setName("main"); 244 main.setVisibility(Visibility.PUBLIC); 245 main.setStatic(true); 246 Parameter param = new Parameter(); 247 param.setName("parameters"); 248 param.setType(Projects.types.resolveType("String", "java.lang")); 249 param.setArray(true); 250 main.addParameter(param); 251 addMethod(main); 252 } 253 254 Package container; 255 /** 256 * Get the value of container. 257 * @return value of container. 258 */ 259 public Package getContainer() { 260 return container; 261 } 262 /** 263 * Set the value of container. 264 * @param v Value to assign to container. 265 */ 266 public void setContainer(Package v) { 267 this.container = v; 268 } 269 270 public String getFullName() { 271 if (container == null) { 272 return name; 273 } else { 274 return container.getPPath()+"."+name; 275 } 276 } 277 278 public String getGenerationFullName() { 279 if (container == null) { 280 return getGenerationName(); 281 } else { 282 return container.getPPath()+"."+getGenerationName(); 283 } 284 } 285 286 287 /** 288 * Gets navigable roles 289 * @return a collection of RelationRole 290 */ 291 public Collection getNavigableRoles() { 292 Vector result = new Vector(); 293 Iterator it = links.iterator(); 294 while (it.hasNext()) { 295 Role role = (Role)it.next(); 296 if (role instanceof RelationRole && ((RelationRole)role).isNavigable()) 297 result.add(role); 298 } 299 return result; 300 } 301 302 /** 303 * Gets all navigable roles, including those form inherited classes. 304 */ 305 public Collection getAllNavigableRoles() { 306 Vector result = new Vector(); 307 if (superClass instanceof Class) 308 result.addAll(((Class)superClass).getAllNavigableRoles()); 309 result.addAll(getNavigableRoles()); 310 return result; 311 } 312 313 /** 314 * Gets all navigable reference roles (whose cardinality is 1 or 315 * 0-1), including those form inherited classes. 316 */ 317 public Collection getReferenceRoles() { 318 Vector result = new Vector(); 319 if (superClass instanceof Class) 320 result.addAll(((Class)superClass).getReferenceRoles()); 321 322 Iterator it = links.iterator(); 323 while (it.hasNext()) { 324 Role role = (Role)it.next(); 325 if (role instanceof RelationRole) { 326 RelationRole relRole = (RelationRole)role; 327 if (relRole.isNavigable() && !relRole.isMultiple()) { 328 result.add(role); 329 } 330 } 331 } 332 333 return result; 334 } 335 336 public Collection getRelationRoles() { 337 Vector result = new Vector(); 338 Iterator it = links.iterator(); 339 while (it.hasNext()) { 340 Role role = (Role)it.next(); 341 if (role instanceof RelationRole) 342 result.add(role); 343 } 344 return result; 345 } 346 347 public Collection getRelationLinks() { 348 Vector result = new Vector(); 349 Iterator it = links.iterator(); 350 while (it.hasNext()) { 351 Role role = (Role)it.next(); 352 if (role instanceof RelationRole) 353 result.add(role.getLink()); 354 } 355 return result; 356 } 357 358 public Project getProject() { 359 if (container!=null) 360 return container.getProject(); 361 else 362 return null; 363 } 364 365 Vector imports = new Vector(); 366 public List getImports() { 367 return imports; 368 } 369 public void addImport(String _import) { 370 imports.add(_import); 371 } 372 public void removeImport(String _import) { 373 imports.remove(_import); 374 } 375 376 boolean isAbstract = false; 377 public boolean isAbstract() { 378 return isAbstract; 379 } 380 public void setAbstract(boolean value) { 381 isAbstract = value; 382 } 383 384 Set interfaces = new HashSet(); 385 public Set getInterfaces() { 386 return interfaces; 387 } 388 public void addInterface(Interface _interface) { 389 interfaces.add(_interface); 390 } 391 public void removeInterface(Interface _interface) { 392 interfaces.remove(_interface); 393 } 394 395 /** 396 * Adds the necessary fields and methods to implement a interface 397 * @param intf the interface to implement 398 */ 399 public void implementInterface(Interface intf) { 400 Iterator it = intf.getAllFields().iterator(); 401 while (it.hasNext()) { 402 Field intfField = (Field)it.next(); 403 if (findField(intfField.getName())!=null) 404 continue; 405 Field field = new Field(); 406 field.setName(intfField.getName()); 407 field.setType(intfField.getType()); 408 field.setArray(intfField.isArray()); 409 addField(field); 410 } 411 412 it = intf.getAllMethods().iterator(); 413 while (it.hasNext()) { 414 Method intfMethod = (Method)it.next(); 415 if (findMethod(intfMethod)!=null) 416 continue; 417 addMethod(intfMethod.cloneMethod()); 418 } 419 } 420 421 /** 422 * Adds an overriding method 423 * @param method method to override 424 */ 425 public void overrideMethod(Method method) { 426 addMethod(method.cloneMethod()); 427 } 428 429 /** 430 * Adds an implementation for an abstract method 431 * @param method abstract method to implement 432 */ 433 public void implementMethod(Method method) { 434 addMethod(method.cloneMethod()); 435 } 436 437 public HandlerResult gotoLine(DisplayContext context,int lineNumber) { 438 Map lineNumbers = CodeGeneration.getClassLineNumbers(this); 439 if (lineNumbers.isEmpty()) { 440 throw new RuntimeException("No line number information available. Please (re)generate code."); 441 } 442 Member member = null; 443 Iterator i = lineNumbers.entrySet().iterator(); 444 int closestLine = 0; 445 while (i.hasNext()) { 446 Map.Entry entry = (Map.Entry)i.next(); 447 int line = ((Integer)entry.getValue()).intValue(); 448 if (lineNumber > line && line > closestLine) { 449 closestLine = line; 450 member = (Member)entry.getKey(); 451 } 452 } 453 if (member!=null) { 454 if (member instanceof Method) { 455 Method method = (Method)member; 456 return new HandlerResult( 457 context.getDisplay().getCustomizedView("ide"), 458 org.objectweb.jac.core.rtti.ClassRepository.get() 459 .getClass(org.objectweb.jac.ide.Class.class).getField("methods"), 460 method,"body",new Integer(lineNumber-closestLine-1)); 461 } else { 462 return new HandlerResult( 463 context.getDisplay().getCustomizedView("ide"), 464 org.objectweb.jac.core.rtti.ClassRepository.get() 465 .getClass(org.objectweb.jac.ide.Class.class).getField("fields"), 466 member,null,null); 467 } 468 } else { 469 return null; 470 } 471 } 472 } 473