KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > javadoc > httpfs > HTTPFileObject


1 /**************************************************************************
2 *
3 * The contents of this file are subject to the terms of the Common Development
4 * and Distribution License (the License). You may not use this file except in
5 * compliance with the License.
6 *
7 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
8 * or http://www.netbeans.org/cddl.txt.
9 *
10 * When distributing Covered Code, include this CDDL Header Notice in each file
11 * and include the License file at http://www.netbeans.org/cddl.txt.
12 * If applicable, add the following below the CDDL Header, with the fields
13 * enclosed by brackets [] replaced by your own identifying information:
14 * "Portions Copyrighted [year] [name of copyright owner]"
15 *
16 * The Original Software is the HTTP Javadoc Filesystem.
17 * The Initial Developer of the Original Software is Jeffrey A. Keyser.
18 * Portions created by Jeffrey A. Keyser are Copyright (C) 2000-2002.
19 * All Rights Reserved.
20 *
21 * Contributor(s): Jeffrey A. Keyser.
22 *
23 **************************************************************************/

24
25
26 package org.netbeans.modules.javadoc.httpfs;
27
28 import java.io.*;
29 import java.net.URL JavaDoc;
30 import java.net.HttpURLConnection JavaDoc;
31 import java.util.*;
32 import javax.swing.text.html.*;
33 import javax.swing.text.BadLocationException JavaDoc;
34
35 import org.openide.filesystems.*;
36 import org.openide.util.NbBundle;
37
38
39 /**
40  * <p>Represents an individual file found on the file sysetm.</p>
41  *
42  * @since 1.0
43  */

44 class HTTPFileObject extends FileObject {
45     
46     private static final long serialVersionUID = 200104;
47
48     // File system that owns this file
49
transient HTTPFileSystem parentFileSystem;
50     // Path of this file under the URL of the file system.
51
String JavaDoc uriStem;
52     // Directory object that contains this file
53
transient private HTTPFileObject parentFileObject;
54     // Child file objects of this file if it is a directory
55
transient private Map childFileObjects;
56     // URL to this file
57
transient URL JavaDoc fileURL;
58     // The file name part of this file
59
transient private String JavaDoc fullFileName;
60     // The first part of this file's file name
61
transient private String JavaDoc fileName;
62     // The extension of this file
63
transient private String JavaDoc fileExtension;
64     // Flags whether the HTTP header of this file has been read
65
transient private boolean wasFileHeaderRead;
66     // The size of this file
67
transient private long fileSize;
68     // The MIME type of this file
69
transient private String JavaDoc fileMIMEType;
70     // The last modified date of this file
71
transient private Date fileDate;
72     // All file attributes for this file, as read from the HTTP headers
73
transient private Hashtable fileAttributes;
74     // Flags whether this folder's contents were read yet
75
transient private boolean areFolderContentsKnown;
76     // List of listeners for this file object
77
transient private Vector listeners;
78         
79     /**
80      * Constructs a <code>HTTPFileObject</code> with the path and file systems
81      * passed.
82      *
83      * @param uriStem The path to this file in the file system.
84      * @param parentFileSystem The file system that contains this file.
85      *
86      * @since 1.0
87      */

88     HTTPFileObject( String JavaDoc uriStem, HTTPFileSystem parentFileSystem ) {
89
90         initialize( uriStem, parentFileSystem );
91
92     }
93     
94     
95     /**
96      * Constructs an empty <code>HTTPFileObject</code>. This constructor is only
97      * expected to be used during deserialization.
98      *
99      * @since 1.0
100      */

101     protected HTTPFileObject(
102     ) {
103
104     }
105
106
107     /**
108      * Initializes this object with the path and file systems passed.
109      *
110      * @param uriStem The path to this file in the file system.
111      * @param parentFileSystem The file system that contains this file.
112      *
113      * @since 1.0
114      */

115     private void initialize(
116         String JavaDoc uriStem,
117         HTTPFileSystem parentFileSystem
118     ) {
119
120         try {
121
122             // initialize this file object
123
this.parentFileSystem = parentFileSystem;
124             this.parentFileObject = null;
125             this.childFileObjects = Collections.synchronizedMap( new Hashtable( ) );
126             this.uriStem = uriStem;
127             this.fileURL = new java.net.URL JavaDoc( parentFileSystem.baseURL, "." + uriStem );//NOI18N
128
this.fileAttributes = new Hashtable( 0 );
129             this.areFolderContentsKnown = true;
130             this.listeners = new Vector( );
131             this.fullFileName = ""; //NOI18N
132
this.fileName = ""; //NOI18N
133
this.fileExtension = ""; //NOI18N
134

135
136             // If this is a directory,
137
if( isFolder( ) ) {
138
139                 // Flag the header as read (there is no header for this file)
140
this.wasFileHeaderRead = true;
141
142                 // Trim the trailing slash from the file name
143
this.fullFileName = uriStem.substring( 0, uriStem.length( ) - 1 );
144
145             // If this is a file object (not a directory),
146
} else {
147
148                 // Create default values for items read from the header
149
this.wasFileHeaderRead = false;
150                 this.fileSize = -1;
151                 this.fileMIMEType = ""; //NOI18N
152
this.fileDate = new Date( );
153                 this.fullFileName = uriStem;
154
155             }
156             // Trim everything after the last slash as the file name
157
this.fullFileName = this.fullFileName.substring( this.fullFileName.lastIndexOf( '/' ) + 1 );
158
159             // If the full file name contains a period,
160
if( this.fullFileName.lastIndexOf( '.' ) != -1 ) {
161
162                 // Split the file name into its two parts
163
this.fileName = this.fullFileName.substring( 0, this.fullFileName.lastIndexOf( '.' ) );
164                 this.fileExtension = this.fullFileName.substring( this.fullFileName.lastIndexOf( '.' ) + 1 );
165
166             } else {
167
168                 this.fileName = this.fullFileName;
169
170             }
171
172         } catch( java.net.MalformedURLException JavaDoc e ) {
173
174             // Ignore - should never occur
175

176         }
177
178     }
179
180
181     /**
182      * Writes this object when it is serialized.
183      *
184      * @param out Serialization output stream.
185      *
186      * @since 1.0
187      */

188     private void writeObject(ObjectOutputStream out) throws IOException {
189
190         // Write out the name of the filesystem and this file
191
out.writeObject( parentFileSystem.getSystemName( ) );
192         out.writeObject( uriStem );
193
194     }
195
196
197     /**
198      * Reads this object when it is unserialized.
199      *
200      * @param in Serialization input stream.
201      *
202      * @since 1.0
203      */

204     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException JavaDoc {
205
206         // Name of the parent filesystem when it was saved
207
String JavaDoc fileSystemName;
208         // Mounted filesystem with the above name
209
HTTPFileSystem newParentFileSystem;
210         // Name of the file
211
String JavaDoc newURIStem;
212
213         // Read the name of the parent filesystem and find it if mounted
214
fileSystemName = (String JavaDoc)in.readObject( );
215         newParentFileSystem = (HTTPFileSystem)Repository.getDefault( ).findFileSystem( fileSystemName );
216
217         // Read the name of this file and initialize it
218
newURIStem = (String JavaDoc)in.readObject( );
219         initialize( newURIStem, newParentFileSystem );
220     }
221
222
223     /**
224      * This method reads the information about this file that is found in the HTTP header.
225      *
226      * @since 1.0
227      */

228     private void readFileHeader( ) {
229         
230         try {
231             // Open a connection to the web server to read this file's header, which
232
// has the side effect of reading the headers for this file
233
getFileConnection( "HEAD" ).disconnect( ); //NOI18N
234

235         } catch( IOException e ) {
236             
237             // Ignore errors
238
}
239     }
240     
241     
242     /**
243      * Obtains a connection to the web server for this file with the selected request
244      * method.
245      *
246      * @param requestMethod The request method to use when opening this connection.
247      *
248      * @return Connection object to this URL.
249      *
250      * @throws IOException If there was an error opening the connection.
251      *
252      * @since 1.0
253      */

254     private HttpURLConnection JavaDoc getFileConnection( String JavaDoc requestMethod ) throws IOException {
255         
256         // Connection to the web server for this file
257
HttpURLConnection JavaDoc fileConnection;
258
259         
260         // Open the connection
261
fileConnection = (HttpURLConnection JavaDoc)fileURL.openConnection( );
262         fileConnection.setUseCaches( true );
263         fileConnection.setRequestMethod( requestMethod );
264         
265         // If the headers have not yet been read for this file,
266
if( !wasFileHeaderRead ) {
267             
268             // Read the headers now
269
readFileHeadersFromConnection( fileConnection );
270             
271         }
272         return fileConnection;
273     }
274     
275     
276     /**
277      * Obtains a connection to the web server for this file with the "GET" method.
278      *
279      * @return Connection object to this URL.
280      *
281      * @throws IOException If there was an error opening the connection.
282      *
283      * @since 1.0
284      */

285     private HttpURLConnection JavaDoc getFileConnection( ) throws IOException {
286         
287         return getFileConnection( "GET" ); //NOI18N
288
}
289     
290     
291     /**
292      * Given a connection to a file on a web server, reads the attributes for this
293      * file that can be found in its HTTP headers.
294      *
295      * @param fileConnection Connection to the web server.
296      *
297      * @since 1.0
298      */

299     private void readFileHeadersFromConnection( HttpURLConnection JavaDoc fileConnection ) {
300         
301         // Index of the header being added to the attributes of this file
302
// int headerIndex;
303

304         fileSize = fileConnection.getContentLength( );
305         fileMIMEType = fileConnection.getContentType( );
306         fileDate = new Date( fileConnection.getLastModified( ) );
307 /* headerIndex = 0;
308         while( fileConnection.getHeaderField( headerIndex ) != null ) {
309
310                 fileAttributes.put( fileConnection.getHeaderFieldKey( headerIndex ), fileConnection.getHeaderField( fileConnection.getHeaderFieldKey( headerIndex ) ) );
311                 headerIndex++;
312
313         }*/

314         wasFileHeaderRead = true;
315         
316     }
317     
318     
319     /**
320      * Returns the file system that owns this file.
321      *
322      * @return Parent filesystem.
323      *
324      * @throws FileStateInvalidException If the parent of this file object is
325      * not known.
326      *
327      * @since 1.0
328      */

329     public org.openide.filesystems.FileSystem getFileSystem( ) throws FileStateInvalidException {
330         
331         if( parentFileSystem != null ) {
332             
333             return parentFileSystem;
334             
335         } else {
336             
337             throw new FileStateInvalidException( NbBundle.getMessage(HTTPFileObject.class, "MSG_FilesystemNotFound" ) ); //NOI18N
338

339         }
340     }
341     
342     
343     /**
344      * Returns the name of this file.
345      *
346      * @since 1.0
347      */

348     public String JavaDoc getName( ) {
349         
350         return fileName;
351     }
352     
353     
354     /**
355      * Returns the extension of this file.
356      *
357      * @since 1.0
358      */

359     public String JavaDoc getExt(
360     ) {
361         
362         return fileExtension;
363         
364     }
365     
366     
367     /**
368      * Returns the name and extension of this file.
369      *
370      * @since 1.0
371      */

372     public String JavaDoc getNameExt(
373     ) {
374         
375         return fullFileName;
376         
377     }
378     
379     
380     /**
381      * Returns the size of this file in bytes.
382      *
383      * @since 1.0
384      */

385     public long getSize( ) {
386         
387         if( !wasFileHeaderRead ) {
388             readFileHeader( );
389         }
390         return fileSize;
391     }
392     
393     
394     /**
395      * Returns the MIME type of this file.
396      *
397      * @since 1.0
398      */

399     public String JavaDoc getMIMEType( ) {
400         if( !wasFileHeaderRead ) {
401             readFileHeader( );
402         }
403         return fileMIMEType;
404     }
405     
406     
407     /**
408      * Returns the parent dircetory object of this file.
409      *
410      * @since 1.0
411      */

412     public FileObject getParent( ) {
413         return parentFileObject;
414     }
415     
416     
417     /**
418      * Returns the date this file was last modified.
419      *
420      * @since 1.0
421      */

422     public Date lastModified( ) {
423         if( !wasFileHeaderRead ) {
424             readFileHeader( );
425         }
426         return fileDate;
427     }
428     
429     
430     /**
431      * Always returns "true" for this read-only filesystem.
432      *
433      * @since 1.0
434      */

435     public boolean isReadOnly( ) {
436         return true;
437     }
438     
439     
440     /**
441      * Returns a flag specifying whether this file is valid or not.
442      *
443      * @since 1.0
444      */

445     public boolean isValid( ) {
446         return fileURL != null;
447     }
448     
449     
450     /**
451      * Returns "true" if this is the root file object of this file system.
452      *
453      * @since 1.0
454      */

455     public boolean isRoot( ) {
456         return uriStem.equals( "/" ); //NOI18N
457
}
458     
459     
460     /**
461      * Returns "true" if this is a directory.
462      *
463      * @since 1.0
464      */

465     public boolean isFolder(
466     ) {
467         
468         return uriStem.endsWith( "/" ); //NOI18N
469

470     }
471     
472     
473     /**
474      * Returns "true" if this is a file, and not a folder.
475      *
476      * @since 1.0
477      */

478     public boolean isData(
479     ) {
480         
481         return !isFolder( );
482         
483     }
484     
485     
486     /**
487      * Called by NetBeans to lock this file. Always returns FileLock.NONE for this
488      * read-only file system.
489      *
490      * @reuturn FileLock.NONE.
491      *
492      * @throws IOException If there was an error locking this file.
493      *
494      * @since 1.0
495      */

496     public FileLock lock(
497     ) throws IOException {
498         
499         return FileLock.NONE;
500         
501     }
502     
503     
504     /**
505      * Called by NetBeans to create a new file in this file system. Always throws an
506      * {@link IOException} for this read-only file system.
507      *
508      * @param fileName The file name of the file to create.
509      * @param extension The extension of the file to create.
510      *
511      * @throws IOException If there was an error creating this file.
512      *
513      * @since 1.0
514      */

515     public FileObject createData(
516         String JavaDoc fileName,
517         String JavaDoc extension
518     ) throws IOException {
519         
520         throw new IOException( );
521         
522     }
523     
524     
525     /**
526      * Called by NetBeans to create a new directory in this file system. Always
527      * throws an {@link IOException} for this read-only file system.
528      *
529      * @param fileName The name of the directory to create.
530      *
531      * @throws IOException If there was an error creating this directory.
532      *
533      * @since 1.0
534      */

535     public FileObject createFolder(
536     String JavaDoc fileName
537     ) throws IOException {
538         
539         throw new IOException( );
540         
541     }
542     
543     
544     /**
545      * Called by NetBeans to rename a file. Always throws an
546      * {@link IOException} for this read-only file system.
547      *
548      * @param lock The lock on this file.
549      * @param fileName The new file name for this file.
550      * @param extension The new extension for this file.
551      *
552      * @throws IOException If there was an error renaming this file.
553      *
554      * @since 1.0
555      */

556     public void rename(
557         FileLock lock,
558         String JavaDoc fileName,
559         String JavaDoc extension
560     ) throws IOException {
561         
562         throw new IOException( );
563     }
564     
565     
566     /**
567      * Called by NetBeans to delete this file. Always throws an
568      * {@link IOException} for this read-only file system.
569      *
570      * @param lock The lock on this file.
571      *
572      * @throws IOException If there was an error deleting this file.
573      *
574      * @since 1.0
575      */

576     public void delete( FileLock lock ) throws IOException {
577         throw new IOException( );
578     }
579     
580     
581     /**
582      * Called by NetBeans to set the importance of this file. Does tothing for this
583      * read-only file system.
584      *
585      * @param isImportant Flags whether this file is important or not.
586      *
587      * @since 1.0
588      */

589     public void setImportant( boolean isImportant ) {
590         // File system is read-only - ignore this call
591
}
592     
593     
594     /**
595      * Returns the list of attributes available for this file.
596      *
597      * @since 1.0
598      */

599     public java.util.Enumeration JavaDoc getAttributes() {
600         
601         if( !wasFileHeaderRead ) {
602             
603             readFileHeader( );
604             
605         }
606         return fileAttributes.keys( );
607     }
608     
609     
610     /**
611      * Returns the value of the named attribute for this file.
612      *
613      * @param attributeName The name of the attribute whose value should be returned.
614      *
615      * @return Value of the attribute, or null if not found.
616      *
617      * @since 1.0
618      */

619     public Object JavaDoc getAttribute( String JavaDoc attributeName ) {
620         
621         if( !wasFileHeaderRead ) {
622             readFileHeader( );
623         }
624         return fileAttributes.get( attributeName );
625     }
626     
627     
628     /**
629      * Changes the specified attribute for this file. Always throws an
630      * {@link IOException} for this read-only file system.
631      *
632      * @param attributeName The name of the attribute to change.
633      * @param newValue the new value for this attribute.
634      *
635      * @throws IOException If there was an error setting this attribute.
636      *
637      * @since 1.0
638      */

639     public void setAttribute(
640         String JavaDoc attributeName,
641         Object JavaDoc newValue
642     ) throws IOException {
643         
644         throw new IOException( );
645     }
646     
647     
648     /**
649      * Returns a list of files that belong to this directory.
650      *
651      * @since 1.0
652      */

653     public FileObject[] getChildren( ) {
654         
655         return (FileObject[])getChildFileObjects( true ).values( ).toArray( new FileObject[ 0 ] );
656     }
657     
658     
659     /**
660      * Returns a file within this directory with the passed name, or "null" if the
661      * file doesn't exist.
662      *
663      * @param fileName The name of the file to return.
664      * @param extension The extension of the file to return.
665      *
666      * @return File object in this filesystem, or null of not found.
667      *
668      * @since 1.0
669      */

670     public FileObject getFileObject( String JavaDoc fileName, String JavaDoc extension ) {
671         
672         if( extension != null && extension.equals( "" ) == false ) { //NOI18N
673
return child( fileName + "." + extension ); //NOI18N
674
} else {
675             return child( fileName );
676         }
677     }
678     
679     
680     /**
681      * Returns an {@link HTTPFileInputStream} object to read the contents of this
682      * file.
683      *
684      * @throws FileNotFoundException If the file doesn't exist.
685      *
686      * @since 1.0
687      */

688     public InputStream getInputStream() throws FileNotFoundException {
689         
690         try {
691             return new HTTPFileInputStream( getFileConnection( ) );
692         } catch( IOException e ) {
693             throw new java.io.FileNotFoundException JavaDoc( e.getMessage( ) );
694         }
695     }
696     
697     
698     /**
699      * Intended to open an OutputStream to change the contents of this file. Always
700      * throws an {@link IOException} for this read-only file system.
701      *
702      * @param lock The lock on this file.
703      *
704      * @return InputStream to this file.
705      *
706      * @since 1.0
707      */

708     public OutputStream getOutputStream(FileLock lock) throws IOException {
709         throw new IOException( );
710     }
711     
712     
713     /**
714      * Adds an object to the list of objects that will receive notifications of file
715      * changes. Does nothing for this read-only file system, since the files will
716      * not have change events.
717      *
718      * @param listener The listener object to add to this file's list.
719      *
720      * @since 1.0
721      */

722     public void addFileChangeListener(FileChangeListener listener) {
723
724         listeners.add( listener );
725
726     }
727     
728     
729     /**
730      * Removes an object from the list of objects that will receive notifications of
731      * file changes. Does nothing for this read-only file system, since the files
732      * will not have change events.
733      *
734      * @param listener The listener object to remove from this file's list.
735      *
736      * @since 1.0
737      */

738     public void removeFileChangeListener(FileChangeListener listener) {
739
740         listeners.remove( listener );
741
742     }
743     
744     
745     /**
746      * Adds a file object to the list of files of this directory object.
747      *
748      * @param newChildFileObject The file object to add.
749      *
750      * @since 1.0
751      */

752     void addChild( HTTPFileObject newChildFileObject ) {
753
754         newChildFileObject.parentFileObject = this;
755         childFileObjects.put( newChildFileObject.getNameExt( ), newChildFileObject );
756
757         // If there are any listeners and the contents of the folder have been read,
758
if( !listeners.isEmpty( ) && areFolderContentsKnown ) {
759
760             // Notify the listeners that this item has been added
761
if( newChildFileObject.isData( ) ) {
762
763                 fireFileDataCreatedEvent( listeners.elements( ), new FileEvent( this, newChildFileObject, true ) );
764
765             } else {
766
767                 fireFileFolderCreatedEvent( listeners.elements( ), new FileEvent( this, newChildFileObject, true ) );
768
769             }
770
771         }
772
773     }
774
775
776     /**
777      * Removes all child file objects from this directory object.
778      *
779      * @since 3.4
780      */

781     void removeAllChildren(
782     ) {
783
784         // Iterator through list of chlildren
785
Iterator childIterator;
786         // Next file to remove
787
HTTPFileObject childFile;
788
789
790         synchronized( childFileObjects ) {
791
792             childIterator = childFileObjects.values( ).iterator( );
793             while( childIterator.hasNext( ) ) {
794
795                 childFile = (HTTPFileObject)childIterator.next( );
796                 childIterator.remove( );
797                 childFile.parentFileObject = null;
798
799                 // If there are any listeners and the contents of the folder have been read,
800
if( !listeners.isEmpty( ) && areFolderContentsKnown ) {
801
802                     // Notify the listeners that this file has been removed
803
fireFileDeletedEvent( listeners.elements( ), new FileEvent( this, childFile, true ) );
804
805                 }
806
807             }
808
809         }
810
811     }
812
813
814     /**
815      * Adds a file object with the passed name to the list of files of this directory
816      * object.
817      *
818      * @param newChildFileName The name of the new file object to add.
819      *
820      * @since 1.0
821      */

822     void addChild( String JavaDoc newChildFileName ) {
823         addChild( new HTTPFileObject( newChildFileName, parentFileSystem ) );
824     }
825     
826     
827     /**
828      * Adds a new file object with the passed name to the list of file objects for
829      * this directory, if the file exists. Returns a flag specifying whether the
830      * file existed and was added or not.
831      *
832      * @param newChildFileName The name of the new file object to add.
833      *
834      * @return Whether the named file was found on the web server or not.
835      *
836      * @since 1.0
837      */

838     boolean addOptionalChild( String JavaDoc newChildFileName ) {
839         // Connection to the web server for this file
840
HttpURLConnection JavaDoc fileConnection;
841         // New file object
842
HTTPFileObject childFileObject;
843         // Flags whether the file was added or not
844
boolean wasFileAdded;
845         
846         
847         fileConnection = null;
848         try {
849             
850             // Create the new file object
851
childFileObject = new HTTPFileObject( newChildFileName, parentFileSystem );
852             fileConnection = childFileObject.getFileConnection( "HEAD" ); //NOI18N
853

854             // If the file exists,
855
if( fileConnection.getResponseCode( ) < 400 ) {
856                 
857                 // Add the new file
858
addChild( childFileObject );
859                 wasFileAdded = true;
860                 
861             } else {
862                 
863                 wasFileAdded = false;
864             }
865             
866         } catch( Exception JavaDoc e ) {
867             
868             wasFileAdded = false;
869             
870         } finally {
871             
872             // Always close the connection to the web server once it has been opened
873
if( fileConnection != null ) {
874                 
875                 fileConnection.disconnect( );
876             }
877             
878         }
879         return wasFileAdded;
880     }
881     
882     
883     /**
884      * Returns a file within this directory with the passed name, or "null" if the
885      * file doesn't exist.
886      *
887      * @param fullFileName The full name of the file to return.
888      *
889      * @return Child file object, or null if not found.
890      *
891      * @since 1.0
892      */

893     HTTPFileObject child( String JavaDoc fullFileName ) {
894         
895         return child( fullFileName, true );
896
897     }
898     
899
900     /**
901      * Returns a file within this directory with the passed name, or "null" if the
902      * file doesn't exist. May or may not read the package contents if not yet
903      * read.
904      *
905      * @param fullFileName The full name of the file to return.
906      * @param readPackageContents Flag to specify whether the package contents
907      * should be read if not know.
908      *
909      * @return Child file object, or null if not found.
910      *
911      * @since 1.0
912      */

913     HTTPFileObject child( String JavaDoc fullFileName, boolean readPackageContents ) {
914         
915         return (HTTPFileObject)getChildFileObjects( readPackageContents ).get( fullFileName );
916
917     }
918
919
920     /**
921      * Returns the Map that contains all of the child FileObjects. This
922      * provides synchronized access to the methods that read the contents of the
923      * folder.
924      *
925      * @param readPackageContents Flags whether this package's contents should be
926      * read if unknown.
927      *
928      * @return Hashtale of child file objects for this file.
929      *
930      * @since 1.0
931      */

932     private Map getChildFileObjects( boolean readPackageContents ) {
933         
934         // If this is a directory that has not been read yet and the root object has been initialized,
935
if( readPackageContents ) {
936
937             synchronized( childFileObjects ) {
938
939                 if( !areFolderContentsKnown ) {
940
941                     // Read the list of files in this package directory
942
readPackageContents( );
943
944                 }
945
946             }
947
948         }
949         return childFileObjects;
950
951     }
952
953
954     /**
955      * Called to mark this directory as one that contains package files.
956      *
957      * @since 1.0
958      */

959     void makePackage() {
960         areFolderContentsKnown = false;
961     }
962     
963     
964     /**
965      * Called to read all of the contents of this package directory into memory.
966      *
967      * @since 1.0
968      */

969     private void readPackageContents( ) {
970         
971         // File object for this package's "package-summary.html" file
972
HTTPFileObject packageSummaryFile;
973         // Object for this package's "class-use/" directory
974
HTTPFileObject classUseDirectory;
975         // InputStream to read the "package-summary.html" file
976
InputStream packageFileInputStream;
977         // Kit to read and parse an HTML file
978
HTMLEditorKit editorKit;
979         // HTML document representation of "package-summary.html" file
980
HTMLDocument htmlDoc;
981         // Iterator through "A" tags of the above file
982
HTMLDocument.Iterator tagIterator;
983         // The file name for the class file in this directory
984
String JavaDoc classFileName;
985         
986         
987         // Find the standard files found in a package directory
988
packageSummaryFile = new HTTPFileObject( uriStem + "package-summary.html", parentFileSystem ); //NOI18N
989
addChild( packageSummaryFile );
990         addOptionalChild( uriStem + "package-frame.html" ); //NOI18N
991
addOptionalChild( uriStem + "package-tree.html" ); //NOI18N
992
if( addOptionalChild( uriStem + "package-use.html" ) ) { //NOI18N
993

994             classUseDirectory = new HTTPFileObject( uriStem + "class-use/", parentFileSystem ); //NOI18N
995
addChild( classUseDirectory );
996             
997         } else {
998             
999             classUseDirectory = null;
1000            
1001        }
1002        
1003        try {
1004            
1005            // Read the "package-summary.html" file into memory
1006
packageFileInputStream = packageSummaryFile.getInputStream( );
1007            editorKit = new HTMLEditorKit();
1008            htmlDoc = (HTMLDocument)editorKit.createDefaultDocument();
1009            editorKit.read( new InputStreamReader( packageFileInputStream ), htmlDoc, 0);
1010            
1011            // Find all of the "A" tags in the file
1012
tagIterator = htmlDoc.getIterator( HTML.Tag.A );
1013            while( tagIterator.isValid( ) ) {
1014                
1015                // Find the target of the link tag
1016
classFileName = (String JavaDoc)tagIterator.getAttributes( ).getAttribute( HTML.Attribute.HREF );
1017                if( classFileName != null ) {
1018                    
1019                    // If the link points to file in this directory that is also not a standard package file,
1020
if( classFileName.indexOf( '/' ) == -1 && !classFileName.startsWith( "." ) //NOI18N
1021
&& !classFileName.startsWith( "#" ) && classFileName.indexOf( ':' ) == -1 //NOI18N
1022
&& !classFileName.startsWith( "package-" ) ) { //NOI18N
1023

1024                        // Add the file to this package directory
1025
addChild( uriStem + classFileName );
1026                        
1027                        // If there is a "class-use/" dircetory,
1028
if( classUseDirectory != null ) {
1029                            // Add the corresponding file in that directory
1030
classUseDirectory.addChild( classUseDirectory.uriStem + classFileName );
1031                        }
1032                    }
1033                }
1034                tagIterator.next( );
1035            }
1036            packageFileInputStream.close( );
1037            
1038        } catch( BadLocationException JavaDoc e ) {
1039            // Ignore the classes of this package
1040
} catch( IOException e ) {
1041            // Ignore the classes of this package
1042
} finally {
1043            areFolderContentsKnown = true;
1044        }
1045    }
1046
1047}
1048
Popular Tags