View Javadoc
1 /* 2 ContractChecker 3 4 Copyright (C) 2003 Jose San Leandro Armend?riz 5 jsanleandro@yahoo.es 6 chousz@yahoo.com 7 8 This library is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public 10 License as published by the Free Software Foundation; either 11 version 2 of the License, or (at your option) any later version. 12 13 This library is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 General Public License for more details. 17 18 You should have received a copy of the GNU General Public 19 License along with this library; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 22 Thanks to ACM S.L. for distributing this library under the GPL license. 23 Contact info: jsr000@terra.es 24 Postal Address: c/Playa de Lagoa, 1 25 Urb. Valdecaba?as 26 Boadilla del monte 27 28660 Madrid 28 Spain 29 30 ****************************************************************************** 31 * 32 * Filename: $RCSfile: ContractCheckerDoclet.java,v $ 33 * 34 * Author: Jose San Leandro Armend?riz 35 * 36 * Description: QDox doclet for retrieving methods' pre- and post-conditions. 37 * 38 * Last modified by: $Author: chous $ at $Date: 2004/01/11 19:44:06 $ 39 * 40 * File version: $Revision: 1.8 $ 41 * 42 * Project version: $Name: $ 43 * 44 * $Id: ContractCheckerDoclet.java,v 1.8 2004/01/11 19:44:06 chous Exp $ 45 * 46 */ 47 package org.acmsl.contractchecker; 48 49 /* 50 * Importing project-specific classes. 51 */ 52 import org.acmsl.contractchecker.ContractCheckerAspectTemplate; 53 import org.acmsl.contractchecker.ContractCheckerAspectTemplateGenerator; 54 import org.acmsl.contractchecker.ContractCheckerException; 55 56 /* 57 * Importing Qdox classes. 58 */ 59 import com.thoughtworks.qdox.ant.AbstractQdoxTask; 60 import com.thoughtworks.qdox.model.DocletTag; 61 import com.thoughtworks.qdox.model.JavaClass; 62 import com.thoughtworks.qdox.model.JavaMethod; 63 import com.thoughtworks.qdox.model.JavaSource; 64 65 /* 66 * Importing Ant classes. 67 */ 68 import org.apache.tools.ant.BuildException; 69 import org.apache.tools.ant.types.FileSet; 70 import org.apache.tools.ant.types.Path; 71 72 /* 73 * Importing some JDK classes. 74 */ 75 import java.io.IOException; 76 import java.io.File; 77 import java.util.ArrayList; 78 import java.util.Collection; 79 import java.util.Iterator; 80 import java.util.List; 81 82 /*** 83 * QDox doclet for retrieving methods' pre- and post-conditions. 84 * @author <a href="mailto:jsanleandro@yahoo.es">Jose San Leandro</a> 85 * @version $Revision: 1.8 $ 86 */ 87 public class ContractCheckerDoclet 88 extends AbstractQdoxTask 89 { 90 /*** 91 * The precondition tag. 92 */ 93 public static final String PRECONDITION_TAG = 94 "precondition"; 95 96 /*** 97 * The default exception. 98 */ 99 public static final String DEFAULT_VIOLATION_EXCEPTION = 100 ContractViolation.class.getName(); 101 102 /*** 103 * Cached empty javaclass array. 104 */ 105 protected static final JavaClass[] EMPTY_JAVACLASS_ARRAY = 106 new JavaClass[0]; 107 108 /*** 109 * Cached empty javamethod array. 110 */ 111 protected static final JavaMethod[] EMPTY_JAVAMETHOD_ARRAY = 112 new JavaMethod[0]; 113 114 /*** 115 * Cached empty contractcheckeraspecttemplate array. 116 */ 117 protected static final ContractCheckerAspectTemplate[] 118 EMPTY_ASPECTTEMPLATE_ARRAY = new ContractCheckerAspectTemplate[0]; 119 120 /*** 121 * The output folder. 122 */ 123 private File m__OutputFolder; 124 125 /*** 126 * The aspectj template factory class. 127 */ 128 private String m__strTemplateFactoryClass; 129 130 /*** 131 * The input files. 132 */ 133 private Path m__InputPath; 134 135 /*** 136 * The contract violation exception. 137 */ 138 private String m__strViolationException; 139 140 /*** 141 * Specifies the output folder. 142 * @param folder the output folder. 143 */ 144 public void setOutputfolder(File folder) 145 { 146 m__OutputFolder = folder; 147 } 148 149 /*** 150 * Retrieves the output folder. 151 * @return such folder. 152 */ 153 public File getOutputfolder() 154 { 155 return m__OutputFolder; 156 } 157 158 /*** 159 * Specifies the template factory class. 160 * @param factoryClass the factory class. 161 */ 162 public void setTemplatefactoryclass(String factoryClass) 163 { 164 m__strTemplateFactoryClass = factoryClass; 165 } 166 167 /*** 168 * Retrieves the template factory class. 169 * @return such class. 170 */ 171 public String getTemplatefactoryclass() 172 { 173 return m__strTemplateFactoryClass; 174 } 175 176 /*** 177 * Specifies the input path. 178 * @param input the input. 179 */ 180 public void setInput(Path input) 181 { 182 m__InputPath = input; 183 } 184 185 /*** 186 * Retrieves the input path. 187 * @return such path. 188 */ 189 public Path getInput() 190 { 191 return m__InputPath; 192 } 193 194 /*** 195 * Specifies the contract violation exception. 196 * @param exception such exception. 197 */ 198 public void setViolationexception(String exception) 199 { 200 m__strViolationException = exception; 201 } 202 203 /*** 204 * Retrieves the contract violation exception. 205 * @return such exception. 206 */ 207 public String getViolationexception() 208 { 209 return m__strViolationException; 210 } 211 212 /*** 213 * Builds the file sets. 214 */ 215 protected void buildFileSets() 216 { 217 ContractCheckerUtils t_Utils = ContractCheckerUtils.getInstance(); 218 219 Path t_Input = getInput(); 220 221 if ( (t_Utils != null) 222 && (t_Input != null)) 223 { 224 FileSet[] t_aFileSets = t_Utils.toFileSets(t_Input); 225 226 if (t_aFileSets != null) 227 { 228 for (int t_iFileSetIndex = 0; 229 t_iFileSetIndex < t_aFileSets.length; 230 t_iFileSetIndex++) 231 { 232 addFileset(t_aFileSets[t_iFileSetIndex]); 233 } 234 } 235 } 236 } 237 238 /*** 239 * Processes given sources. 240 * @param sources the source code to process. 241 */ 242 protected void processSources(JavaSource[] sources) 243 { 244 if (sources != null) 245 { 246 for (int t_iSourceIndex = 0; 247 t_iSourceIndex < sources.length; 248 t_iSourceIndex++) 249 { 250 processSource(sources[t_iSourceIndex]); 251 } 252 } 253 } 254 255 /*** 256 * Processes given source. 257 * @param source the source to process. 258 */ 259 protected void processSource(JavaSource source) 260 { 261 if (source != null) 262 { 263 super.allSources.add(source); 264 JavaClass[] t_aClasses = source.getClasses(); 265 processClasses(t_aClasses); 266 } 267 } 268 269 /*** 270 * Processes given classes. 271 * @param classes the classes to process. 272 */ 273 protected void processClasses(JavaClass[] classes) 274 { 275 if (classes != null) 276 { 277 for (int t_iClassIndex = 0; 278 t_iClassIndex < classes.length; 279 t_iClassIndex++) 280 { 281 processClass(classes[t_iClassIndex]); 282 } 283 } 284 } 285 286 /*** 287 * Processes given class. 288 * @param javaClass the class to process. 289 */ 290 protected void processClass(JavaClass javaClass) 291 { 292 if (javaClass != null) 293 { 294 super.allClasses.add(javaClass); 295 } 296 } 297 298 /*** 299 * Tag information retrieval starting point. 300 * @throws BuildException if the source code cannot be processed. 301 */ 302 public void execute() 303 throws BuildException 304 { 305 buildFileSets(); 306 307 super.execute(); 308 309 try 310 { 311 Collection t_cGuardedClasses = 312 findGuardedClasses(super.allClasses); 313 314 ContractCheckerAspectTemplateFactory t_Factory = 315 instantiateFactory(getTemplatefactoryclass()); 316 317 String t_strViolationException = getViolationexception(); 318 319 if (t_strViolationException == null) 320 { 321 t_strViolationException = DEFAULT_VIOLATION_EXCEPTION; 322 } 323 324 ContractCheckerAspectTemplate[] t_aTemplates = 325 buildTemplates( 326 t_cGuardedClasses, t_Factory, t_strViolationException); 327 328 writeTemplates(t_aTemplates, getOutputfolder()); 329 } 330 catch (ContractCheckerException contractCheckerException) 331 { 332 throw 333 new BuildException( 334 "Cannot continue", contractCheckerException); 335 } 336 } 337 338 /*** 339 * Creates the factory instance. 340 * @param className the factory class name. 341 * @return the factory instance. 342 * @throws ContractCheckerException if the factory cannot be 343 * instantiated. 344 */ 345 protected ContractCheckerAspectTemplateFactory instantiateFactory( 346 String className) 347 throws ContractCheckerException 348 { 349 ContractCheckerAspectTemplateFactory result = null; 350 351 if (className != null) 352 { 353 try 354 { 355 Class t_Class = Class.forName(className); 356 357 if (t_Class != null) 358 { 359 Object t_Factory = t_Class.newInstance(); 360 361 if ( (t_Factory != null) 362 && ( t_Factory 363 instanceof ContractCheckerAspectTemplateFactory)) 364 { 365 result = 366 (ContractCheckerAspectTemplateFactory) t_Factory; 367 } 368 else 369 { 370 throw 371 new ContractCheckerException( 372 "invalid.template.factory.class"); 373 } 374 } 375 } 376 catch (Exception exception) 377 { 378 throw 379 new ContractCheckerException( 380 "cannot.instantiate.template.factory", 381 exception); 382 } 383 } 384 385 if (result == null) 386 { 387 result = ContractCheckerAspectTemplateGenerator.getInstance(); 388 } 389 390 return result; 391 } 392 393 /*** 394 * Finds the guarded classes from given collection. 395 * @param classes the complete class set. 396 * @return the subset consisting only in guarded classes. 397 */ 398 protected Collection findGuardedClasses(Collection classes) 399 { 400 Collection result = new ArrayList(); 401 402 if (classes != null) 403 { 404 Iterator t_itClassIterator = classes.iterator(); 405 406 if (t_itClassIterator != null) 407 { 408 while (t_itClassIterator.hasNext()) 409 { 410 JavaClass t_CurrentClass = 411 (JavaClass) t_itClassIterator.next(); 412 413 if (t_CurrentClass != null) 414 { 415 JavaMethod[] t_Methods = 416 findGuardedMethods( 417 t_CurrentClass.getMethods(), true); 418 419 if ( (t_Methods != null) 420 && (t_Methods.length > 0)) 421 { 422 result.add(t_CurrentClass); 423 } 424 } 425 } 426 } 427 } 428 429 return result; 430 } 431 432 /*** 433 * Finds the guarded method from given collection. 434 * @param methods the complete method set. 435 * @param stopOnFirst whether to stop on first guarded method. 436 * Therefore, if it's set to <code>true</code> the resulting 437 * array will contain 0 or 1 element. 438 * @return the subset consisting only in guarded methods. 439 */ 440 protected static JavaMethod[] findGuardedMethods( 441 JavaMethod[] methods, boolean stopOnFirst) 442 { 443 Collection t_cResult = new ArrayList(); 444 445 if (methods != null) 446 { 447 for (int t_iMethodIndex = 0; 448 t_iMethodIndex < methods.length; 449 t_iMethodIndex++) 450 { 451 JavaMethod t_CurrentMethod = methods[t_iMethodIndex]; 452 453 if (t_CurrentMethod != null) 454 { 455 DocletTag[] t_Tags = 456 t_CurrentMethod.getTagsByName( 457 PRECONDITION_TAG); 458 459 if ( (t_Tags != null) 460 && (t_Tags.length > 0)) 461 { 462 t_cResult.add(t_CurrentMethod); 463 464 if (stopOnFirst) 465 { 466 break; 467 } 468 } 469 } 470 } 471 } 472 473 return (JavaMethod[]) t_cResult.toArray(EMPTY_JAVAMETHOD_ARRAY); 474 } 475 476 /*** 477 * Builds the templates for given classes. 478 * @param classes the classes. 479 * @param factory the template factory. 480 * @param defaultException the default exception. 481 * @return the associated contract-checker templates. 482 */ 483 protected ContractCheckerAspectTemplate[] buildTemplates( 484 Collection classes, 485 ContractCheckerAspectTemplateFactory factory, 486 String defaultException) 487 { 488 List t_lResult = new ArrayList(); 489 490 if (classes != null) 491 { 492 Iterator t_itClassIterator = classes.iterator(); 493 494 if (t_itClassIterator != null) 495 { 496 JavaClass t_CurrentClass = null; 497 498 while (t_itClassIterator.hasNext()) 499 { 500 t_CurrentClass = 501 (JavaClass) t_itClassIterator.next(); 502 503 ContractCheckerAspectTemplate t_Template = 504 buildTemplate( 505 t_CurrentClass, factory, defaultException); 506 507 if (t_Template != null) 508 { 509 int t_iTemplatePosition = 510 t_lResult.indexOf(t_Template); 511 512 if (t_iTemplatePosition > -1) 513 { 514 t_Template = 515 (ContractCheckerAspectTemplate) 516 t_lResult.get(t_iTemplatePosition); 517 } 518 else 519 { 520 t_lResult.add(t_Template); 521 } 522 523 t_Template.addClass(t_CurrentClass); 524 } 525 } 526 } 527 } 528 529 return 530 (ContractCheckerAspectTemplate[]) 531 t_lResult.toArray(EMPTY_ASPECTTEMPLATE_ARRAY); 532 } 533 534 /*** 535 * Builds a ContractCheckerAspectTemplate from information provided 536 * by given class. 537 * @param javaClass the Java class. 538 * @param factory the template factory. 539 * @param defaultException the default exception. 540 * @return such kind of template. 541 */ 542 protected ContractCheckerAspectTemplate buildTemplate( 543 JavaClass javaClass, 544 ContractCheckerAspectTemplateFactory factory, 545 String defaultException) 546 { 547 ContractCheckerAspectTemplate result = null; 548 549 if (javaClass != null) 550 { 551 // Inversion of control pattern. 552 result = 553 buildTemplate( 554 javaClass.getName(), 555 javaClass.getFullyQualifiedName(), 556 factory, 557 defaultException, 558 ContractCheckerUtils.getInstance()); 559 } 560 561 return result; 562 } 563 564 /*** 565 * Builds a ContractCheckerAspectTemplate from information provided 566 * by given class. 567 * @param name the Java class' name. 568 * @param qualifiedName the Java class' qualified name. 569 * @param factory the template factory. 570 * @param defaultException the default exception. 571 * @param contractCheckerUtils the helper instance. 572 * @return such kind of template. 573 */ 574 protected ContractCheckerAspectTemplate buildTemplate( 575 String name, 576 String qualifiedName, 577 ContractCheckerAspectTemplateFactory factory, 578 String defaultException, 579 ContractCheckerUtils contractCheckerUtils) 580 { 581 ContractCheckerAspectTemplate result = null; 582 583 if ( (name != null) 584 && (qualifiedName != null) 585 && (factory != null) 586 && (defaultException != null) 587 && (contractCheckerUtils != null)) 588 { 589 String t_strPackageName = name; 590 591 int t_iIndex = 592 qualifiedName.lastIndexOf(name) - 1; 593 594 if (t_iIndex > -1) 595 { 596 t_strPackageName = 597 qualifiedName.substring(0, t_iIndex); 598 } 599 600 result = 601 factory.createContractCheckerAspectTemplate( 602 contractCheckerUtils.retrieveAspectPackage( 603 t_strPackageName), 604 defaultException); 605 } 606 607 return result; 608 } 609 610 /*** 611 * Writes given templates. 612 * @param templates the templates to write. 613 * @param outputFolder the output folder. 614 * @return <code>true</code> if the templates are written successfully. 615 * @throws ContractCheckerException if the template cannot be written for 616 * any reason. 617 */ 618 protected boolean writeTemplates( 619 ContractCheckerAspectTemplate[] templates, 620 File outputFolder) 621 throws ContractCheckerException 622 { 623 boolean result = false; 624 625 if ( (templates != null) 626 && (outputFolder != null)) 627 { 628 try 629 { 630 ContractCheckerAspectTemplateGenerator t_Generator = 631 ContractCheckerAspectTemplateGenerator.getInstance(); 632 633 if (t_Generator != null) 634 { 635 for (int t_iTemplateIndex = 0; 636 t_iTemplateIndex < templates.length; 637 t_iTemplateIndex++) 638 { 639 t_Generator.write( 640 templates[t_iTemplateIndex], 641 outputFolder); 642 } 643 644 result = true; 645 } 646 } 647 catch (IOException ioException) 648 { 649 throw 650 new ContractCheckerException( 651 "Cannot write the templates", ioException); 652 } 653 } 654 655 return result; 656 } 657 }

This page was automatically generated by Maven