001 /* 002 * Copyright (c) 2005 Stephen J. McConnell 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 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.metro.tools; 020 021 import java.io.File; 022 import java.io.FileFilter; 023 import java.io.FileWriter; 024 import java.io.IOException; 025 import java.net.URI; 026 import java.util.List; 027 import java.util.ArrayList; 028 import java.util.LinkedList; 029 import java.util.Hashtable; 030 import java.util.Arrays; 031 import java.util.Map; 032 033 import net.dpml.metro.info.EntryDescriptor; 034 import net.dpml.metro.info.Type; 035 import net.dpml.metro.info.ContextDescriptor; 036 import net.dpml.metro.info.ServiceDescriptor; 037 038 import net.dpml.metro.builder.ComponentTypeDecoder; 039 040 import net.dpml.transit.Transit; 041 042 import net.dpml.util.Resolver; 043 import net.dpml.util.SimpleResolver; 044 045 import org.apache.tools.ant.Task; 046 import org.apache.tools.ant.BuildException; 047 import org.apache.tools.ant.Project; 048 import org.apache.tools.ant.DirectoryScanner; 049 import org.apache.tools.ant.taskdefs.Copy; 050 import org.apache.tools.ant.types.FileSet; 051 052 /** 053 * Create a set of html reports about component types. 054 * 055 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 056 * @version 1.2.0 057 */ 058 public class CatalogTask extends Task 059 { 060 private static final ComponentTypeDecoder COMPONENT_TYPE_DECODER = 061 new ComponentTypeDecoder(); 062 063 private File m_work; 064 private File m_destination; 065 private String m_style; 066 private String m_title; 067 private List m_filesets = new LinkedList(); 068 private Map m_packages = new Hashtable(); 069 070 /** 071 * Set the final destination directory for generated HTML content. 072 * @param destination the destination directory 073 */ 074 public void setDest( File destination ) 075 { 076 m_destination = destination; 077 } 078 079 /** 080 * Optional override of the XSL stylesheet used to transform type descriptors. 081 * @param style the XSL transformation to use 082 */ 083 public void setStyle( String style ) 084 { 085 m_style = style; 086 } 087 088 /** 089 * Optional override of the index page title. 090 * @param title the index page title 091 */ 092 public void setTitle( String title ) 093 { 094 m_title = title; 095 } 096 097 /** 098 * Add a fileset to the set of filesets definted within the catalog generation. If no 099 * filesets are added the default behaviour will be resolve against component types 100 * declared under the current projects ${basedir}/target/classes directory. 101 * 102 * @param set the fileset to add 103 */ 104 public void addFileset( FileSet set ) 105 { 106 m_filesets.add( set ); 107 } 108 109 /** 110 * Task initialization. 111 */ 112 public void init() 113 { 114 String targetDirPath = getProject().getProperty( "project.target.dir" ); 115 File target = new File( targetDirPath ); 116 File reports = new File( target, "reports" ); 117 File types = new File( reports, "catalog" ); 118 m_work = types; 119 } 120 121 /** 122 * Task execution during which all component types declared in the current project or referenced 123 * by nested filesets will be used as the source defintions fro the generation of a Type catalog. 124 */ 125 public void execute() 126 { 127 log( "building catalog index" ); 128 Project proj = getProject(); 129 File[] types = getTypes(); 130 log( "Catalog type count: " + types.length ); 131 if( types.length == 0 ) 132 { 133 return; 134 } 135 else 136 { 137 File reports = getWorkingDirectory(); 138 //File html = new File( reports, "html" ); 139 File html = reports; 140 html.mkdirs(); 141 142 File css = new File( Transit.DPML_PREFS, "dpml/metro/csss/type.css" ); 143 File stylesheet = new File( html, "stylesheet.css" ); 144 final Copy copy = (Copy) getProject().createTask( "copy" ); 145 copy.setFile( css ); 146 copy.setTofile( stylesheet ); 147 copy.execute(); 148 149 for( int i=0; i < types.length; i++ ) 150 { 151 File type = types[i]; 152 processType( reports, type ); 153 } 154 155 createCatalog( html ); 156 } 157 } 158 159 /** 160 * A side effect of type processing is the population of the m_packages map. The 161 * map keys are package names and the map values are list of types within the 162 * respective package. The keys constitute the package list and for each package 163 * we construct an index of types within that package. 164 * 165 * @param root the root html directory 166 */ 167 private void createCatalog( File root ) 168 { 169 createIndex( root ); 170 createPackagesIndex( root ); 171 createTypesIndex( root ); 172 createOverviewPage( root ); 173 } 174 175 /** 176 * Create the list of all types. 177 * @param root the root html directory 178 */ 179 private void createTypesIndex( File root ) 180 { 181 File index = new File( root, "types.html" ); 182 try 183 { 184 FileWriter writer = new FileWriter( index ); 185 writer.write( "<html>" ); 186 writer.write( "\n <head>" ); 187 writer.write( "\n <META http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">" ); 188 writer.write( "\n <title>Package Index</title>" ); 189 writer.write( "\n <link href=\"stylesheet.css\" type=\"text/css\" rel=\"stylesheet\"/>" ); 190 writer.write( "\n </head>" ); 191 writer.write( "\n <body>" ); 192 writer.write( "\n <p><b>Overview</b></p>" ); 193 writer.write( "\n <p><a href=\"packages-overview.html\" target=\"typeFrame\">All Packages</a></p>" ); 194 writer.write( "\n <p><b>All Types</b></p>" ); 195 writer.write( "\n <table>" ); 196 197 List[] lists = (List[]) m_packages.values().toArray( new List[0] ); 198 for( int i=0; i < lists.length; i++ ) 199 { 200 List list = lists[i]; 201 Type[] types = (Type[]) list.toArray( new Type[0] ); 202 for( int j=0; j < types.length; j++ ) 203 { 204 Type type = types[j]; 205 String path = type.getInfo().getClassname().replace( '.', '/' ); 206 String classname = getClassName( type ); 207 String filename = path + ".html"; 208 writer.write( "\n <tr><td><a href=\"" ); 209 writer.write( filename ); 210 writer.write( "\" target=\"typeFrame\">" ); 211 writer.write( classname ); 212 writer.write( "</a></td></tr>" ); 213 } 214 } 215 writer.write( "\n </table>" ); 216 writer.write( "\n </body>" ); 217 writer.write( "\n</html>" ); 218 writer.close(); 219 } 220 catch( Exception e ) 221 { 222 final String error = 223 "Internal error while attempting to create packages list."; 224 throw new BuildException( error, e, getLocation() ); 225 } 226 } 227 228 private void createOverviewPage( File root ) 229 { 230 File overview = new File( root, "packages-overview.html" ); 231 try 232 { 233 FileWriter writer = new FileWriter( overview ); 234 writer.write( "<html>" ); 235 writer.write( "\n <head>" ); 236 writer.write( "\n <META http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">" ); 237 writer.write( "\n <title>Type Packages List</title>" ); 238 writer.write( "\n <link href=\"stylesheet.css\" type=\"text/css\" rel=\"stylesheet\"/>" ); 239 writer.write( "\n </head>" ); 240 writer.write( "\n <body>" ); 241 242 // 243 // add menu containing packages overview links 244 // 245 246 writer.write( "\n <table class=\"menubar\">" ); 247 writer.write( "\n <tr>" ); 248 writer.write( "<td class=\"package\"><a class=\"package\" href=\"packages-overview.html\">" ); 249 writer.write( "overview" ); 250 writer.write( "</a></td>" ); 251 writer.write( "\n </tr>" ); 252 writer.write( "\n </table>" ); 253 254 writer.write( "\n <p class=\"title\">Overview</p>" ); 255 256 writer.write( "\n <table>" ); 257 writer.write( "\n <tr><th>Package</th><th>Components</th></tr>" ); 258 259 boolean flag = true; 260 Object[] keys = m_packages.keySet().toArray(); 261 for( int i=0; i < keys.length; i++ ) 262 { 263 String name = (String) keys[i]; 264 createPackageOverview( root, name ); 265 List list = getPackageList( name ); 266 if( flag ) 267 { 268 writer.write( "\n <tr class=\"p-even\">" ); 269 } 270 else 271 { 272 writer.write( "\n <tr class=\"p-odd\">" ); 273 } 274 flag = !flag; 275 276 writer.write( "<td><a href=\"" ); 277 String path = name.replace( '.', '/' ); 278 writer.write( path + "/overview.html\" target=\"typeFrame\">" ); 279 writer.write( name ); 280 writer.write( "</a></td>" ); 281 writer.write( "<td>" ); 282 Type[] types = (Type[]) list.toArray( new Type[0] ); 283 for( int j=0; j < types.length; j++ ) 284 { 285 Type type = types[j]; 286 String classname = getClassName( type ); 287 String filename = type.getInfo().getClassname().replace( '.', '/' ) + ".html"; 288 if( j > 0 ) 289 { 290 writer.write( ", " ); 291 } 292 writer.write( "<a href=\"" ); 293 writer.write( filename ); 294 writer.write( "\" target=\"typeFrame\">" ); 295 writer.write( classname ); 296 writer.write( "</a>" ); 297 } 298 writer.write( "</td>" ); 299 writer.write( "</tr>" ); 300 } 301 302 writer.write( "\n </table>" ); 303 writer.write( "\n </body>" ); 304 writer.write( "\n</html>" ); 305 writer.close(); 306 } 307 catch( Exception e ) 308 { 309 final String error = 310 "Internal error while attempting to create packages overview."; 311 throw new BuildException( error, e, getLocation() ); 312 } 313 } 314 315 private void createPackagesIndex( File root ) 316 { 317 File packages = new File( root, "packages.html" ); 318 try 319 { 320 FileWriter writer = new FileWriter( packages ); 321 writer.write( "<html>" ); 322 writer.write( "\n <head>" ); 323 writer.write( "\n <META http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">" ); 324 writer.write( "\n <title>Type Packages List</title>" ); 325 writer.write( "\n <link href=\"stylesheet.css\" type=\"text/css\" rel=\"stylesheet\">" ); 326 writer.write( "\n </head>" ); 327 writer.write( "\n <body>" ); 328 329 String title = getTitle(); 330 331 writer.write( "\n <table>" ); 332 writer.write( "\n <tr><td class=\"title\">" + title + "</td></tr>" ); 333 writer.write( "\n </table>" ); 334 335 writer.write( "\n <p><a href=\"types.html\" target=\"typeListFrame\">All Types</a></p>" ); 336 writer.write( "\n <p><b>Packages</b></p>" ); 337 writer.write( "\n <table>" ); 338 339 Object[] keys = m_packages.keySet().toArray(); 340 for( int i=0; i < keys.length; i++ ) 341 { 342 String name = (String) keys[i]; 343 writer.write( "\n <tr><td><a href=\"" ); 344 String path = name.replace( '.', '/' ); 345 writer.write( path + "/package-index.html\" target=\"typeListFrame\">" ); 346 writer.write( name ); 347 writer.write( "</a></td></tr>" ); 348 createPackageIndex( root, name ); 349 } 350 351 writer.write( "\n </table>" ); 352 writer.write( "\n </body>" ); 353 writer.write( "\n</html>" ); 354 writer.close(); 355 } 356 catch( Exception e ) 357 { 358 final String error = 359 "Internal error while attempting to create packages list."; 360 throw new BuildException( error, e, getLocation() ); 361 } 362 } 363 364 private void createPackageIndex( File root, String name ) 365 { 366 String path = name.replace( '.', '/' ); 367 File dir = new File( root, path ); 368 dir.mkdirs(); 369 File index = new File( dir, "package-index.html" ); 370 String offset = getOffset( name ); 371 try 372 { 373 FileWriter writer = new FileWriter( index ); 374 writer.write( "<html>" ); 375 writer.write( "\n <head>" ); 376 writer.write( "\n <META http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">" ); 377 writer.write( "\n <title>Package Index</title>" ); 378 writer.write( "\n <link href=\"" + offset + "/stylesheet.css\" type=\"text/css\" rel=\"stylesheet\"/>" ); 379 writer.write( "\n </head>" ); 380 writer.write( "\n <body>" ); 381 writer.write( "\n <p><b>Overview</b></p>" ); 382 writer.write( "\n <p><a href=\"overview.html\" target=\"typeFrame\">" + name + "</a></p>" ); 383 writer.write( "\n <p><b>Types</b></p>" ); 384 writer.write( "\n <table>" ); 385 386 List list = getPackageList( name ); 387 Type[] types = (Type[]) list.toArray( new Type[0] ); 388 for( int i=0; i < types.length; i++ ) 389 { 390 Type type = types[i]; 391 String classname = getClassName( type ); 392 String filename = classname + ".html"; 393 writer.write( "\n <tr><td><a href=\"" ); 394 writer.write( filename ); 395 writer.write( "\" target=\"typeFrame\">" ); 396 writer.write( classname ); 397 writer.write( "</a></td></tr>" ); 398 } 399 writer.write( "\n </table>" ); 400 writer.write( "\n </body>" ); 401 writer.write( "\n</html>" ); 402 writer.close(); 403 } 404 catch( Exception e ) 405 { 406 final String error = 407 "Internal error while attempting to create packages list."; 408 throw new BuildException( error, e, getLocation() ); 409 } 410 } 411 412 private void createPackageOverview( File root, String name ) 413 { 414 String path = name.replace( '.', '/' ); 415 File dir = new File( root, path ); 416 dir.mkdirs(); 417 File index = new File( dir, "overview.html" ); 418 String offset = getOffset( name ); 419 try 420 { 421 FileWriter writer = new FileWriter( index ); 422 writer.write( "<html>" ); 423 writer.write( "\n <head>" ); 424 writer.write( "\n <META http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">" ); 425 writer.write( "\n <title>Package Overview: " + name + "</title>" ); 426 writer.write( "\n <link href=\"" + offset + "/stylesheet.css\" type=\"text/css\" rel=\"stylesheet\"/>" ); 427 writer.write( "\n </head>" ); 428 writer.write( "\n <body>" ); 429 430 // 431 // add the menubar containing the link to the all packages overview 432 // 433 434 writer.write( "\n <table class=\"menubar\">" ); 435 writer.write( "\n <tr>" ); 436 writer.write( "<td class=\"package\"><a class=\"package\" href=\"" + offset + "/packages-overview.html\">" ); 437 writer.write( "overview" ); 438 writer.write( "</a></td>" ); 439 writer.write( "<td class=\"package-selected\"><a class=\"package-selected\" href=\"overview.html\">" ); 440 writer.write( name ); 441 writer.write( "</a></td>" ); 442 writer.write( "\n </tr>" ); 443 writer.write( "\n </table>" ); 444 445 // 446 // add the package name 447 // 448 449 writer.write( "\n <table>" ); 450 writer.write( "\n <tr><td class=\"title\">" + name + "</td></tr>" ); 451 writer.write( "\n </table>" ); 452 453 writer.write( "\n <table width=\"100%\">" ); 454 writer.write( "\n <tr><th>Type</th><th>Name</th><th>Lifestyle</th></tr>" ); 455 456 // 457 // list all component types in the package 458 // 459 460 boolean flag = true; 461 List list = getPackageList( name ); 462 Type[] types = (Type[]) list.toArray( new Type[0] ); 463 for( int i=0; i < types.length; i++ ) 464 { 465 Type type = types[i]; 466 if( flag ) 467 { 468 writer.write( "\n <tr class=\"p-even\">" ); 469 } 470 else 471 { 472 writer.write( "\n <tr class=\"p-odd\">" ); 473 } 474 flag = !flag; 475 476 String classname = getClassName( type ); 477 String filename = classname + ".html"; 478 writer.write( "\n <td><a href=\"" ); 479 writer.write( filename ); 480 writer.write( "\" target=\"typeFrame\">" ); 481 writer.write( classname ); 482 writer.write( "</a>" ); 483 writer.write( "\n </td>" ); 484 485 writer.write( "\n <td>" ); 486 writer.write( type.getInfo().getName() ); 487 writer.write( "\n </td>" ); 488 489 writer.write( "\n <td>" ); 490 writer.write( type.getInfo().getLifestylePolicy().getName() ); 491 writer.write( "\n </td>" ); 492 493 writer.write( "\n </tr>" ); 494 } 495 writer.write( "\n </table>" ); 496 writer.write( "\n </body>" ); 497 writer.write( "\n</html>" ); 498 writer.close(); 499 } 500 catch( Exception e ) 501 { 502 final String error = 503 "Internal error while attempting to create packages list."; 504 throw new BuildException( error, e, getLocation() ); 505 } 506 } 507 508 private void createTypePage( File root, Type type ) 509 { 510 File html = getReportDestination( root, type, "html" ); 511 html.getParentFile().mkdirs(); 512 String classname = type.getInfo().getClassname(); 513 String cname = getClassName( type ); 514 String packagename = getPackageName( type ); 515 String offset = getOffset( packagename ); 516 List packageList = getPackageList( packagename ); 517 packageList.add( type ); 518 try 519 { 520 FileWriter writer = new FileWriter( html ); 521 writer.write( "<html>" ); 522 writer.write( "\n <head>" ); 523 writer.write( "\n <META http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">" ); 524 writer.write( "\n <title>Component Type: " + classname + "</title>" ); 525 writer.write( "\n <link href=\"" + offset + "/stylesheet.css\" type=\"text/css\" rel=\"stylesheet\"/>" ); 526 writer.write( "\n </head>" ); 527 writer.write( "\n <body>" ); 528 529 // 530 // add menu containing packages and package overview links 531 // 532 533 writer.write( "\n <table class=\"menubar\">" ); 534 writer.write( "\n <tr>" ); 535 writer.write( "<td class=\"package\"><a class=\"package\" href=\"" 536 + offset + "/packages-overview.html\">" ); 537 writer.write( "overview" ); 538 writer.write( "</a></td>" ); 539 writer.write( "<td class=\"package\"><a class=\"package\" href=\"overview.html\">" ); 540 writer.write( packagename ); 541 writer.write( "</a></td>" ); 542 writer.write( "<td class=\"package-selected\">" + cname + "</td>" ); 543 writer.write( "\n </tr>" ); 544 writer.write( "\n </table>" ); 545 546 // 547 // add component type classname as title 548 // 549 550 writer.write( "\n <table>" ); 551 writer.write( "\n <tr><td class=\"type\">" + cname + "</td></tr>" ); 552 writer.write( "\n </table>" ); 553 554 // 555 // write out the InfoDescriptor features 556 // 557 558 writer.write( "\n <table>" ); 559 writer.write( "\n <tr><td class=\"feature\">Version:</td><td>" 560 + type.getInfo().getVersion() + "</td></tr>" ); 561 writer.write( "\n <tr><td class=\"feature\">Name:</td><td>" 562 + type.getInfo().getName() + "</td></tr>" ); 563 writer.write( "\n <tr><td class=\"feature\">Lifestyle:</td><td>" 564 + type.getInfo().getLifestylePolicy().getName() + "</td></tr>" ); 565 writer.write( "\n <tr><td class=\"feature\">Thread-Safe:</td><td>" 566 + type.getInfo().getThreadSafePolicy() + "</td></tr>" ); 567 writer.write( "\n <tr><td class=\"feature\">Collection:</td><td>" 568 + type.getInfo().getCollectionPolicy().getName() + "</td></tr>" ); 569 writer.write( "\n </table>" ); 570 571 // 572 // write out the exported services that the component provides 573 // 574 575 ServiceDescriptor[] services = type.getServiceDescriptors(); 576 writeServiceDescriptors( writer, services ); 577 578 // 579 // write out the context model 580 // 581 582 boolean flag = true; 583 ContextDescriptor context = type.getContextDescriptor(); 584 EntryDescriptor[] entries = context.getEntryDescriptors(); 585 if( entries.length > 0 ) 586 { 587 Arrays.sort( entries ); 588 writer.write( "\n <p class=\"category\">Context</p>" ); 589 writer.write( "\n <table width=\"100%\">" ); 590 for( int j=0; j<entries.length; j++ ) 591 { 592 EntryDescriptor entry = entries[j]; 593 String key = entry.getKey(); 594 String entryClassname = entry.getClassname(); 595 String entryDisplayClassname = getDisplayClassname( entryClassname ); 596 boolean optional = entry.isOptional(); 597 598 if( flag ) 599 { 600 writer.write( "<tr class=\"c-even\">" ); 601 } 602 else 603 { 604 writer.write( "<tr class=\"c-odd\">" ); 605 } 606 writer.write( "<td>" + key + "</td>" ); 607 if( optional ) 608 { 609 writer.write( "<td>optional</td>" ); 610 } 611 else 612 { 613 writer.write( "<td>required</td>" ); 614 } 615 writer.write( "<td>" + entryDisplayClassname + "</td>" ); 616 writer.write( "</tr>" ); 617 flag = !flag; 618 } 619 writer.write( "\n </table>" ); 620 } 621 622 writer.write( "\n </body>" ); 623 writer.write( "\n</html>" ); 624 writer.close(); 625 } 626 catch( Exception e ) 627 { 628 final String error = 629 "Internal error while attempting to create type page."; 630 throw new BuildException( error, e, getLocation() ); 631 } 632 } 633 634 private String getDisplayClassname( String classname ) 635 { 636 if( classname.startsWith( "[L" ) ) 637 { 638 if( classname.endsWith( ";" ) ) 639 { 640 int n = classname.length(); 641 return classname.substring( 2, n-1 ) + "[]"; 642 } 643 else 644 { 645 return classname.substring( 2 ) + "[]"; 646 } 647 } 648 else 649 { 650 return classname; 651 } 652 } 653 654 private void writeServiceDescriptors( FileWriter writer, ServiceDescriptor[] services ) throws IOException 655 { 656 boolean flag = true; 657 if( services.length > 0 ) 658 { 659 writer.write( "\n <p class=\"category\">Services</p>" ); 660 writer.write( "\n <table width=\"100%\">" ); 661 for( int j=0; j < services.length; j++ ) 662 { 663 String service = services[j].getClassname(); 664 if( flag ) 665 { 666 writer.write( "<tr class=\"even\"><td>" + service + "</td></tr>" ); 667 } 668 else 669 { 670 writer.write( "<tr class=\"odd\"><td>" + service + "</td></tr>" ); 671 } 672 flag = !flag; 673 } 674 writer.write( "\n </table>" ); 675 } 676 } 677 678 private List getPackageList( String name ) 679 { 680 List list = (List) m_packages.get( name ); 681 if( null == list ) 682 { 683 list = new ArrayList(); 684 m_packages.put( name, list ); 685 } 686 return list; 687 } 688 689 private void processType( File reports, File source ) 690 { 691 log( source.toString() ); 692 File htmls = reports; 693 try 694 { 695 URI uri = source.toURI(); 696 Resolver resolver = new SimpleResolver(); 697 Type type = COMPONENT_TYPE_DECODER.loadType( uri, resolver ); 698 createTypePage( htmls, type ); 699 } 700 catch( Exception e ) 701 { 702 throw new BuildException( e.getMessage(), e, getLocation() ); 703 } 704 } 705 706 private File getReportDestination( File dir, Type type, String suffix ) 707 { 708 final String classname = type.getInfo().getClassname(); 709 String path = classname.replace( '.', '/' ); 710 String filename = path + "." + suffix; 711 return new File( dir, filename ); 712 } 713 714 private String getClassName( Type type ) 715 { 716 String path = type.getInfo().getClassname(); 717 int n = path.lastIndexOf( "." ); 718 if( n > -1 ) 719 { 720 return path.substring( n + 1 ); 721 } 722 else 723 { 724 return path; 725 } 726 } 727 728 private String getPackageName( Type type ) 729 { 730 String path = type.getInfo().getClassname(); 731 int n = path.lastIndexOf( "." ); 732 if( n > -1 ) 733 { 734 return path.substring( 0, n ); 735 } 736 else 737 { 738 return ""; 739 } 740 } 741 742 private String getBasePath( Type type ) 743 { 744 String base = ""; 745 String path = type.getInfo().getClassname(); 746 while( path.indexOf( "." ) > 0 ) 747 { 748 path = path.substring( path.indexOf( "." ) + 1 ); 749 if( base.equals( "" ) ) 750 { 751 base = ".."; 752 } 753 else 754 { 755 base = base + "/.."; 756 } 757 } 758 return base; 759 } 760 761 private String getOffset( String packagename ) 762 { 763 String base = ".."; 764 String path = packagename; 765 while( path.indexOf( "." ) > 0 ) 766 { 767 path = path.substring( path.indexOf( "." ) + 1 ); 768 base = base + "/.."; 769 } 770 return base; 771 } 772 773 private String getStyle() 774 { 775 if( null == m_style ) 776 { 777 return new File( Transit.DPML_PREFS, "metro/style/type-formatter.xsl" ).toString(); 778 } 779 else 780 { 781 return m_style; 782 } 783 } 784 785 private String getTitle() 786 { 787 if( null == m_title ) 788 { 789 return "DPML Metro Catalog"; 790 } 791 else 792 { 793 return m_title; 794 } 795 } 796 797 private File getWorkingDirectory() 798 { 799 if( null == m_destination ) 800 { 801 return m_work; 802 } 803 else 804 { 805 return m_destination; 806 } 807 } 808 809 private File[] getTypes() 810 { 811 if( m_filesets.size() == 0 ) 812 { 813 String classesDirPath = getProject().getProperty( "project.target.classes.main.dir" ); 814 File classes = new File( classesDirPath ); 815 return getTypes( classes ); 816 } 817 else 818 { 819 ArrayList list = new ArrayList(); 820 Project project = getProject(); 821 FileSet[] filesets = (FileSet[]) m_filesets.toArray( new FileSet[0] ); 822 for( int i=0; i < filesets.length; i++ ) 823 { 824 FileSet fileset = filesets[i]; 825 File basedir = fileset.getDir( project ); 826 DirectoryScanner ds = fileset.getDirectoryScanner( project ); 827 String[] files = ds.getIncludedFiles(); 828 for( int j=0; j < files.length; j++ ) 829 { 830 String path = files[j]; 831 File file = new File( basedir, path ); 832 list.add( file ); 833 } 834 } 835 return (File[]) list.toArray( new File[0] ); 836 } 837 } 838 839 private File[] getTypes( File dir ) 840 { 841 ArrayList list = new ArrayList(); 842 getTypes( list, dir ); 843 return (File[]) list.toArray( new File[0] ); 844 } 845 846 private void getTypes( List list, File dir ) 847 { 848 File[] types = dir.listFiles( new TypeFileFilter() ); 849 for( int i=0; i<types.length; i++ ) 850 { 851 list.add( types[i] ); 852 } 853 File[] dirs = dir.listFiles( new DirectoryFilter() ); 854 for( int i=0; i<dirs.length; i++ ) 855 { 856 getTypes( list, dirs[i] ); 857 } 858 } 859 860 /** 861 * Type file filter impl. 862 */ 863 private static class TypeFileFilter implements FileFilter 864 { 865 /** 866 * Return true if the file is a type. 867 * @param file the file to test 868 * @return true if the file is a type 869 */ 870 public boolean accept( File file ) 871 { 872 return file.getName().endsWith( ".type" ); 873 } 874 } 875 876 /** 877 * Directory filer impl. 878 */ 879 private static class DirectoryFilter implements FileFilter 880 { 881 /** 882 * Return true if the file is a directory. 883 * @param file the file to test 884 * @return true if the file is a directory 885 */ 886 public boolean accept( File file ) 887 { 888 return file.isDirectory(); 889 } 890 } 891 892 private void createIndex( File root ) 893 { 894 String title = getTitle(); 895 File index = new File( root, "index.html" ); 896 try 897 { 898 FileWriter writer = new FileWriter( index ); 899 writer.write( "<html>" ); 900 writer.write( "\n <head>" ); 901 writer.write( "\n <META http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">" ); 902 writer.write( "\n <title>" + title + "</title>" ); 903 writer.write( "\n <link href=\"stylesheet.css\" type=\"text/css\" rel=\"stylesheet\"/>" ); 904 writer.write( "\n </head>" ); 905 writer.write( "\n <frameset cols=\"20%,80%\">" ); 906 writer.write( "\n <frameset rows=\"30%,70%\">" ); 907 writer.write( "\n <frame name=\"packageListFrame\" src=\"packages.html\">" ); 908 writer.write( "\n <frame name=\"typeListFrame\" src=\"types.html\">" ); 909 writer.write( "\n </frameset>" ); 910 writer.write( "\n <frame name=\"typeFrame\" src=\"packages-overview.html\">" ); 911 writer.write( "\n </frameset>" ); 912 writer.write( "\n</html>" ); 913 writer.close(); 914 } 915 catch( Exception e ) 916 { 917 final String error = 918 "Internal error while attempting to create frameset."; 919 throw new BuildException( error, e, getLocation() ); 920 } 921 } 922 }