View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2005 Kevin Rogers
4   //
5   // This file is part of MillScript.
6   //
7   // MillScript is free software; you can redistribute it and/or modify it under
8   // the terms of the GNU General Public License as published by the Free
9   // Software Foundation; either version 2 of the License, or (at your option)
10  // any later version.
11  //
12  // MillScript is distributed in the hope that it will be useful, but WITHOUT
13  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  // more details.
16  //
17  // You should have received a copy of the GNU General Public License along with
18  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
19  // Place, Suite 330, Boston, MA  02111-1307  USA
20  ////////////////////////////////////////////////////////////////////////////////
21  package org.millscript.commons.vfs.protocols.http;
22  
23  import org.millscript.commons.alert.Alert;
24  import org.millscript.commons.vfs.AbstractVFile;
25  import org.millscript.commons.vfs.VFolder;
26  import org.millscript.commons.vfs.alerts.VCannotOpenEntryAlert;
27  import org.millscript.commons.vfs.alerts.VEntryNotFoundAlert;
28  
29  import gnu.inet.http.ByteArrayResponseBodyReader;
30  import gnu.inet.http.Request;
31  import gnu.inet.http.Response;
32  
33  import java.io.ByteArrayInputStream;
34  import java.io.InputStream;
35  import java.io.OutputStream;
36  
37  /**
38   * This class implements a virtual filesystem file for an HTTP filesystem file.
39   */
40  public class HttpFile extends AbstractVFile< HttpVolume > {
41  
42      /**
43       * Constructs a new HTTP virtual filesystem file with the specified name,
44       * parent folder and volume.
45       *
46       * @param vol   the volume this entry is held on
47       * @param parent    the parent folder for this file
48       * @param name  the name of the file
49       */
50      HttpFile( final HttpVolume vol, final VFolder parent, final String name ) {
51          super( vol, parent, name );
52      }
53  
54      /**
55       * Constructs a new HTTP virtual filesystem file with the specified name,
56       * parent folder. This file will belong to the same volume as the specified
57       * parent folder.
58       *
59       * @param parent    the parent folder for this file
60       * @param name  the name of the file
61       */
62      HttpFile( final HttpFolder parent, final String name ) {
63          super( parent.getVolume(), parent, name );
64      }
65  
66      /**
67       * @see org.millscript.commons.vfs.VEntry#exists()
68       */
69      public boolean exists() {
70          final HttpVolume vol = this.getVolume();
71          // Try to get the segment as a folder
72          Request request = vol.httpConnection.newRequest(
73              "HEAD",
74              this.getAbsolutePath()
75          );
76          // Execute the method and capture the resulting status code
77          Response response = vol.dispatch( request );
78          if ( response.getCode() == 200 ) {
79              // Success
80              return true;
81          } else {
82              return false;
83          }
84      }
85  
86      /**
87       * @see org.millscript.commons.vfs.VFile#getAppendOutputStream()
88       */
89      public OutputStream getAppendOutputStream() {
90          // TODO Auto-generated method stub
91          return null;
92      }
93  
94      /**
95       * @see org.millscript.commons.vfs.VFile#getContentMIMEType()
96       */
97      @Override
98      public String getContentMIMEType() {
99          // TODO - This method can report much better errors based on the HTTP
100         // status code, so do it...
101         final HttpVolume vol = this.getVolume();
102         // Try to get the segment as a folder
103         Request request = vol.httpConnection.newRequest(
104             "HEAD",
105             this.getAbsolutePath()
106         );
107         // Execute the method and capture the resulting status code
108         Response response = vol.dispatch( request );
109         if ( response.getCode() == 200 ) {
110             // Success
111             final String header = response.getHeader( "Content-Type" );
112             // Do we have the content-type header?
113             if ( header != null ) {
114                 final int n = header.indexOf( ';' );
115                 if ( n < 0 ) {
116                     return header;
117                 } else {
118                     return header.substring( 0, n );
119                 }
120             }
121             // There wasn't a content type header in the HTTP response, so fall
122             // through to the default normal calculation
123         } else {
124             // MISHAP: We didn't find the file on the server
125             throw VEntryNotFoundAlert.entryDoesNotExist( this.getName() ).mishap();
126         }
127         // We haven't managed to get a proper MIME type from the HTTP server,
128         // so use our normal calculation based on the filename
129         return super.getContentMIMEType();
130     }
131 
132     /**
133      * @see org.millscript.commons.vfs.VFile#getInputStream()
134      */
135     public InputStream getInputStream() {
136         final HttpVolume vol = this.getVolume();
137         // Try to get the segment as a folder
138         Request request = vol.httpConnection.newRequest(
139             "GET",
140             this.getAbsolutePath()
141         );
142         // Make a body reader to hold the body of the request
143         final ByteArrayResponseBodyReader reader = new ByteArrayResponseBodyReader();
144         request.setResponseBodyReader( reader );
145         // Execute the method and capture the resulting status code
146         Response response = vol.dispatch( request );
147         if ( response.getCode() == 200 ) {
148             // Success
149             return new ByteArrayInputStream( reader.toByteArray() );
150         } else {
151             // OK, into error handling mode
152             throw(
153                 this.handleResponse( response ).remishap()
154             );
155         }
156     }
157 
158     /**
159      * @see org.millscript.commons.vfs.VFile#getOutputStream()
160      */
161     public OutputStream getOutputStream() {
162         // TODO Auto-generated method stub
163         return null;
164     }
165 
166     private Alert handleResponse( final Response response ) {
167         // The entry doesn't exist at all.
168         return VCannotOpenEntryAlert.fileNotFound( this ).culprit(
169             "http response",
170             response.getMessage()
171         ).mishap();
172     }
173 
174 }