KickJava   Java API By Example, From Geeks To Geeks.

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


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-2005.
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.beans.*;
30 import java.net.*;
31 import java.util.*;
32
33 import org.openide.filesystems.*;
34 import org.openide.filesystems.FileSystem;
35 import org.openide.util.NbBundle;
36 import org.openide.util.SharedClassObject;
37 import org.openide.util.actions.SystemAction;
38
39 /**
40  * <p>Implemets the "HTTP Javadoc Filesystem" bean.</p>
41  *
42  * @since 1.0
43  */

44 public class HTTPFileSystem extends FileSystem implements VetoableChangeListener {
45
46     /**
47      * Property name for the URL of the file system.
48      *
49      * @since 1.0
50      */

51     public static final String JavaDoc PROP_URL = "URL"; //NOI18N
52
/**
53      * Property name for the refresh rate for the file system.
54      *
55      * @since 3.4
56      */

57     public static final String JavaDoc PROP_REFRESH_RATE = "RefreshRate"; // NOI18N
58
/**
59      * Property name for the state of the file system.
60      *
61      * @since 3.4
62      */

63     public static final String JavaDoc PROP_STATE = "State"; // NOI18N
64
/**
65      * Current state is not known.
66      *
67      * @since 3.4
68      */

69     public static final int STATE_UNKNOWN = 0;
70     /**
71      * File system is reading its structure from the web site.
72      *
73      * @since 3.4
74      */

75     public static final int STATE_READING = 1;
76     /**
77      * File system is done reading its structure.
78      *
79      * @since 3.4
80      */

81     public static final int STATE_COMPLETE = 2;
82
83     private static final long serialVersionUID = 200104;
84     // Default URL to use for a new filesystem
85
private static final String JavaDoc DEFAULT_URL = "http://www.netbeans.org/download/apis/"; //NOI18N
86

87     
88     // URL to the Javadocs
89
transient URL baseURL;
90     // Root file object for the mounted filesystem
91
transient HTTPRootFileObject rootFileObject;
92     // Refresh rate in minutes
93
transient int refreshRate;
94     // Current state of the file system
95
transient int currentState;
96             
97     /**
98      * Constructs a <code>HTTPFileSystem</code> file system bean.
99      *
100      * @since 1.0
101      */

102     public HTTPFileSystem() {
103         
104         setHidden( true );
105         addVetoableChangeListener( this );
106         refreshRate = 0;
107         currentState = STATE_UNKNOWN;
108         
109         try{
110             
111             // Set a known URL as the default
112
setURL( DEFAULT_URL ); //NOI18N
113

114         } catch( PropertyVetoException e ) {
115             
116             // I have no idea what else to do if this happens!
117
e.printStackTrace( );
118
119         }
120         
121     }
122     
123     
124     /**
125      * Writes this object when it is serialized.
126      *
127      * @param out Serialization output stream.
128      *
129      * @since 1.0
130      */

131     private void writeObject(ObjectOutputStream out) throws IOException {
132
133         // Write the URL
134
out.writeObject( baseURL.toString( ) );
135
136         // Write the refresh rate
137
out.writeInt( refreshRate );
138
139     }
140     
141     
142     /**
143      * Reads this object when it is unserialized.
144      *
145      * @param in Serialization input stream.
146      *
147      * @since 1.0
148      */

149     private void readObject(ObjectInputStream in)
150         throws IOException, ClassNotFoundException JavaDoc {
151
152         // Make sure this object listens to its own property changes
153
addVetoableChangeListener( this );
154         try {
155
156             // Read the URL
157
setURL( (String JavaDoc)in.readObject( ) );
158
159             // Backward compatibility to old versions of this object
160
try {
161
162                 // Read the refresh rate
163
refreshRate = in.readInt( );
164
165             // If the refresh rate could not be read,
166
} catch( IOException e ) {
167
168                 // Default to not refreshing
169
refreshRate = 0;
170
171             }
172
173         } catch( PropertyVetoException e ) {
174
175             throw new IOException( e.getMessage( ) );
176
177         }
178
179     }
180     
181     
182     /**
183      * Returns the current URL of this file system.
184      *
185      * @since 1.0
186      *
187      * @return URL name for this filesystem.
188      *
189      * @see #setURL(URL)
190      */

191     public String JavaDoc getURL( ) {
192         
193         return baseURL.toString();
194         
195     }
196     
197     
198     /**
199      * Sets a new URL for this file system.
200      *
201      * @param newURL The URL this file system should use.
202      *
203      * @throws PropertyVetoException If the URL doesn't point to a web site, or
204      * if some other property listener vetos this change.
205      *
206      * @since 1.0
207      *
208      * @see #getURL()
209      */

210     public synchronized void setURL( String JavaDoc url )
211         throws PropertyVetoException {
212
213         // Original URL of this filesystem
214
URL oldURL;
215         // Original root file object of this filesystem
216
HTTPRootFileObject oldRootFileObject;
217
218
219         // Save current state of the bean
220
oldURL = baseURL;
221         oldRootFileObject = rootFileObject;
222         
223         try {
224             
225             // Create the new root file object
226
try {
227                 
228                 baseURL = new URL( url );
229                 
230             }
231             catch( java.net.MalformedURLException JavaDoc mlfEx ){
232                 
233                 throw new PropertyVetoException( mlfEx.toString( ), new PropertyChangeEvent( this, PROP_URL, oldURL != null ? oldURL.toExternalForm( ) : null, url ) );
234                 
235             }
236             rootFileObject = new HTTPRootFileObject( this ); //NOI18N
237

238             // Give listeners a chance to reject the URL
239
fireVetoableChange( PROP_URL, oldURL != null ? oldURL.toExternalForm( ) : null, url );
240             
241             // Set the new name of this file system (also fires display name property change event)
242
setSystemName( this.getClass( ).getName( ) + "/" + baseURL.toExternalForm( ) ); //NOI18N
243

244         } catch( PropertyVetoException e ) {
245             
246             // Set bean back to previous state and rethrow this exception
247
baseURL = oldURL;
248             rootFileObject = oldRootFileObject;
249             throw e;
250
251         }
252         firePropertyChange( PROP_URL, oldURL != null ? oldURL.toExternalForm( ) : null, url );
253         firePropertyChange( PROP_ROOT, oldRootFileObject, rootFileObject );
254
255     }
256
257
258     /**
259      * Returns the current refresh rate of this file system.
260      *
261      * @return Refresh rate for this filesystem.
262      *
263      * @see #setRefreshRate(int)
264      *
265      * @since 3.4
266      */

267     public int getRefreshRate(
268     ) {
269
270         return refreshRate;
271
272     }
273
274
275     /**
276      * Changes the current refresh rate of this file system.
277      *
278      * @throws PropertyVetoException If the refresh rate is negative, or if
279      * some other property listener vetos this change.
280      *
281      * @see #getRefreshRate()
282      *
283      * @since 3.4
284      */

285     public void setRefreshRate(
286         int newRefreshRate
287     ) throws PropertyVetoException {
288
289         int oldRefreshRate;
290
291
292         oldRefreshRate = refreshRate;
293         try {
294
295             refreshRate = newRefreshRate;
296
297             // Give listeners a chance to reject the new refresh rate
298
fireVetoableChange( PROP_REFRESH_RATE, new Integer JavaDoc( oldRefreshRate ), new Integer JavaDoc( newRefreshRate ) );
299
300         } catch( PropertyVetoException e ) {
301
302             // Set bean back to previous state and rethrow this exception
303
refreshRate = oldRefreshRate;
304             throw e;
305
306         }
307         firePropertyChange( PROP_REFRESH_RATE, new Integer JavaDoc( oldRefreshRate ), new Integer JavaDoc( newRefreshRate ) );
308
309     }
310
311
312     /**
313      * Returns the current state of this file system.
314      *
315      * @return State code for this filesystem.
316      *
317      * @since 3.4
318      */

319     public int getState(
320     ) {
321
322         return currentState;
323
324     }
325
326
327     /**
328      * Changes the current state of this file system.
329      *
330      * @see #getState()
331      *
332      * @since 3.4
333      */

334     void setState(
335         int newState
336     ) {
337
338         // Previous state
339
int oldState;
340         // Previous display name
341
String JavaDoc oldDisplayName;
342
343
344         // If the state is actually changing,
345
if( newState != currentState ) {
346
347             // Save the current display name
348
oldDisplayName = getDisplayName( );
349
350             // Change the state
351
oldState = currentState;
352             currentState = newState;
353             firePropertyChange( PROP_STATE, new Integer JavaDoc( oldState ), new Integer JavaDoc( newState ) );
354
355             // If the effective display name has changed,
356
if( !oldDisplayName.equals( getDisplayName( ) ) ) {
357
358                 // Fire a property change event for that, too
359
firePropertyChange( PROP_DISPLAY_NAME, oldDisplayName, getDisplayName( ) );
360
361             }
362
363         }
364
365     }
366
367
368     /**
369      * Verifies that the URL or refresh rate given to this filesystem is valid.
370      *
371      * @param propertyChangeEvent Change request for this file system's
372      * properties.
373      *
374      * @since 1.0
375      */

376     public void vetoableChange(
377         PropertyChangeEvent propertyChangeEvent
378     ) throws PropertyVetoException {
379
380         // New URL
381
URL newURL;
382         // New refresh rate
383
int newRefreshRate;
384
385
386         // If the property change event is this object's URL property,
387
if( propertyChangeEvent.getSource( ) == this && propertyChangeEvent.getPropertyName( ).equals( PROP_URL ) ) {
388
389             // Test the URL format
390
try {
391
392                 newURL = new URL( (String JavaDoc)propertyChangeEvent.getNewValue( ) );
393
394             }
395             catch( MalformedURLException mlfEx ){
396
397                 throw new PropertyVetoException( mlfEx.toString( ), propertyChangeEvent );
398
399             }
400         
401             // If this URL doesn't point to an HTTP server,
402
if( !newURL.getProtocol( ).equals( "http" ) && !newURL.getProtocol( ).equals( "https" ) ) { //NOI18N
403

404                 // Reject this URL
405
throw new PropertyVetoException( NbBundle.getMessage(HTTPFileSystem.class, "MSG_NotHTTPProtocol" ), propertyChangeEvent ); //NOI18N
406

407             }
408             // If this URL doesn't point to a directory,
409
if( !newURL.toExternalForm( ).endsWith( "/" ) ){ //NOI18N
410

411                 // Reject this URL
412
throw new PropertyVetoException( NbBundle.getMessage(HTTPFileSystem.class, "MSG_NotDirectory" ), propertyChangeEvent ); //NOI18N
413

414             }
415             
416         // If the property change event is this object's refresh rate property,
417
} else if( propertyChangeEvent.getSource( ) == this && propertyChangeEvent.getPropertyName( ).equals( PROP_REFRESH_RATE ) ) {
418
419             newRefreshRate = ( (Integer JavaDoc)propertyChangeEvent.getNewValue( ) ).intValue( );
420
421             // If the new refresh rate is negative,
422
if( newRefreshRate < 0 ) {
423
424                 // Reject this refresh rate
425
throw new PropertyVetoException( NbBundle.getMessage(HTTPFileSystem.class, "MSG_RefreshRateCannotBeNegative" ), propertyChangeEvent ); //NOI18N
426

427             }
428
429         }
430
431     }
432
433
434     /**
435      * Returns the root directory for the Javadocs.
436      *
437      * @return Root file object of this filesystem.
438      *
439      * @since 1.0
440      */

441     public FileObject getRoot() {
442         
443         return rootFileObject;
444
445     }
446     
447     
448     /**
449      * Provides the name of this file system to be displayed to the user, which is the
450      * URL of the Javadocs.
451      *
452      * @return Name to display in the IDE for this filesystem.
453      *
454      * @since 1.0
455      */

456     public String JavaDoc getDisplayName( ) {
457
458         // Message key to use
459
String JavaDoc messageKey;
460         // Values to pass to the message formatter
461
Object JavaDoc replacementValues[];
462
463         // If the web server is being scanned,
464
if( getState( ) == STATE_READING ) {
465
466             // Use the "scanning" message
467
messageKey = "DisplayName_Scanning"; // NOI18N
468
// If the web server is not being scanned,
469
} else {
470
471             // Use the "normal" message
472
messageKey = "DisplayName_Normal"; // NOI18N
473
}
474
475         return NbBundle.getMessage(HTTPFileSystem.class, messageKey, baseURL.toExternalForm( ) );
476
477     }
478     
479     
480     /**
481      * Returns a file object by its resource name, or "null" if the file was not
482      * found.
483      *
484      * @param resourceName The path of the file under the URL to return.
485      *
486      * @return File object in this filesystem, or null if not found.
487      *
488      * @since 1.0
489      */

490     public FileObject findResource(String JavaDoc resourceName) {
491         
492         // Parser to break up the path to the file
493
StringTokenizer pathParser;
494         // File object to return
495
HTTPFileObject foundFileObject;
496         
497         
498         // Pull apart the directory structure
499
pathParser = new StringTokenizer( resourceName, "/" ); //NOI18N
500
foundFileObject = (HTTPFileObject)getRoot( );
501         
502         // Walk down the path to find the requested file
503
while( foundFileObject != null && pathParser.hasMoreElements( ) ) {
504             
505             foundFileObject = foundFileObject.child( (String JavaDoc)pathParser.nextElement( ) );
506             
507         }
508         return foundFileObject;
509     }
510     
511     
512     /**
513      * Always returns "true" for this read-only file system.
514      *
515      * @return True.
516      *
517      * @since 1.0
518      */

519     public boolean isReadOnly( ) {
520         
521         return true;
522     }
523     
524     
525     /**
526      * Returns the list of actions that can be performed against the files in this
527      * file system.
528      *
529      * @return Array of SystemActions that can be performed on this filesystem.
530      *
531      * @since 1.0
532      *
533      * @see RefeshAction
534      */

535     public org.openide.util.actions.SystemAction[] getActions(
536     ) {
537
538         // Class object for RefreshAction
539
Class JavaDoc refreshActionClass;
540         // Cached instance of RefreshAction
541
RefreshAction refreshAction;
542
543
544         // Get a cached copy of the RefreshAction object
545
refreshActionClass = RefreshAction.class;
546         refreshAction = (RefreshAction)SharedClassObject.findObject( refreshActionClass, true );
547
548         // Return the array of actions
549
return new SystemAction[ ] { refreshAction };
550
551     }
552
553
554     /**
555      * Cleans up this object.
556      *
557      * @since 1.0
558      */

559     protected void finalize( ) throws Throwable JavaDoc {
560
561         removeVetoableChangeListener(this);
562         rootFileObject = null;
563         baseURL = null;
564
565     }
566
567 }
568
Popular Tags