KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > vfs > webdav > methods > GET


1 /* ========================================================================== *
2  * Copyright (C) 2004-2005 Pier Fumagalli <http://www.betaversion.org/~pier/> *
3  * All rights reserved. *
4  * ========================================================================== *
5  * *
6  * Licensed under the Apache License, Version 2.0 (the "License"). You may *
7  * not use this file except in compliance with the License. You may obtain a *
8  * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. *
9  * *
10  * Unless required by applicable law or agreed to in writing, software *
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT *
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
13  * License for the specific language governing permissions and limitations *
14  * under the License. *
15  * *
16  * ========================================================================== */

17 package com.sslexplorer.vfs.webdav.methods;
18
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.io.OutputStream JavaDoc;
22 import java.io.PrintWriter JavaDoc;
23 import java.text.SimpleDateFormat JavaDoc;
24 import java.util.Date JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.StringTokenizer JavaDoc;
27 import java.util.Vector JavaDoc;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.commons.vfs.RandomAccessContent;
32 import org.apache.commons.vfs.util.RandomAccessMode;
33
34 import com.sslexplorer.boot.Util;
35 import com.sslexplorer.vfs.VFSInputStream;
36 import com.sslexplorer.vfs.VFSLockManager;
37 import com.sslexplorer.vfs.VFSResource;
38 import com.sslexplorer.vfs.webdav.DAVTransaction;
39 import com.sslexplorer.vfs.webdav.LockedException;
40
41 /**
42  * <p>
43  * <a HREF="http://www.rfc-editor.org/rfc/rfc2616.txt">HTTP</a>
44  * <code>GET</code> metohd implementation.
45  * </p>
46  *
47  * @author <a HREF="../../../../../../">Pier Fumagalli</a>
48  */

49 public class GET extends HEAD {
50
51     static Log log = LogFactory.getLog(GET.class);
52     
53     /**
54      * <p>
55      * The mime type this method will return for collections.
56      * </p>
57      */

58     public static final String JavaDoc COLLECTION_MIME_TYPE = "text/html";
59
60     /**
61      * <p>
62      * Create a new {@link GET} instance.
63      * </p>
64      */

65     public GET() {
66         super();
67     }
68
69     /**
70      * <p>
71      * Process the <code>GET</code> method.
72      * </p>
73      */

74     public void process(DAVTransaction transaction, VFSResource resource) throws LockedException, IOException JavaDoc {
75         
76         
77         String JavaDoc handle = VFSLockManager.getNewHandle();
78         VFSLockManager.getInstance().lock(resource, transaction.getSessionInfo(), false, true, handle);
79         
80         try {
81             doHead(transaction, resource);
82     
83             try {
84                 if (resource.isCollection() || resource.isMount()) {
85                     String JavaDoc mime = COLLECTION_MIME_TYPE + "; charset=\"utf-8\"";
86                     transaction.setContentType(mime);
87     
88                     Util.noCache(transaction.getResponse());
89                     
90                     PrintWriter JavaDoc out = transaction.write("utf-8");
91                     String JavaDoc path = resource.getFullPath();
92                     out.println("<html>");
93                     out.println("<head>");
94                     out.println("<title>Collection: " + path + "</title>");
95                     out.println("</head>");
96                     out.println("<body>");
97                     out.println("<h2>Collection: " + path + "</h2>");
98                     out.println("<table>");
99                     out.println("<thead>");
100                     out.println("<tr>");
101                     out.println("<td>Name</td>");
102                     out.println("<td>Type</td>");
103                     out.println("<td>Size</td>");
104                     out.println("<td>Date</td>");
105                     out.println("</tr>");
106                     out.println("</thead>");
107                     out.println("<tbody>");
108     
109                     /* Process the parent */
110                     VFSResource parent = resource.getParent();
111                     if (parent != null) {
112                         out.println("<tr>");
113                         out.print("<td><li><a HREF=\"..\">../</a></td>");
114                         out.println("<td>Dir</td><td>");
115                         try {
116                             out.println(parent.getFile().getContent().getSize());
117                         }
118                         catch(Exception JavaDoc e) {
119                         }
120                         out.println("</td><td>");
121                         try {
122                             out.println(SimpleDateFormat.getDateTimeInstance().format(new Date JavaDoc(parent.getFile().getContent().getLastModifiedTime())));
123                         }
124                         catch(Exception JavaDoc e) {
125                         }
126                         out.println("</td></tr>");
127                     }
128     
129                     /* Process the children */
130                     Iterator JavaDoc iterator = resource.getChildren();
131                     if (iterator != null) {
132                         while (iterator.hasNext()) {
133                             VFSResource child = (VFSResource) iterator.next();
134                             String JavaDoc childPath = child.getDisplayName();
135
136                             out.println("<tr>");
137                             out.print("<td><li><a HREF=\"" + child.getWebFolderPath() + "\">" + childPath + "</a></td>");
138                             if(child.isCollection())
139                                 out.println("<td>Dir</td><td>");
140                             else if(child.isResource())
141                                 out.println("<td>Resource</td><td>");
142                             else
143                                 out.println("<td>Unknown</td><td>");
144                             try {
145                                 out.println(child.getFile().getContent().getSize());
146                             }
147                             catch(Exception JavaDoc e) {
148                             }
149                             out.println("</td><td>");
150                             try {
151                                 out.println(SimpleDateFormat.getDateTimeInstance().format(new Date JavaDoc(child.getFile().getContent().getLastModifiedTime())));
152                             }
153                             catch(Exception JavaDoc e) {
154                             }
155                             out.println("</td></tr>");
156                             out.println("</tr>");
157                         }
158                     }
159                     out.println("</tbody>");
160                     out.println("</table>");
161                     out.println("</html>");
162                     out.flush();
163                     if(resource.getMount() != null) {
164                         resource.getMount().resourceAccessList(resource, transaction, null);
165                     }
166                     return;
167                 }
168             } catch (Exception JavaDoc e) {
169                 if(resource.getMount() != null) {
170                     resource.getMount().resourceAccessList(resource, transaction, e);
171                 }
172                 IOException JavaDoc ioe = new IOException JavaDoc(e.getMessage());
173                 ioe.initCause(e);
174                 throw ioe;
175             }
176     
177             int total = 0;
178             try {
179     
180                 Range[] ranges = null;
181                 
182                 try {
183                     ranges = processRangeHeader(transaction, resource);
184                 } catch(IOException JavaDoc ex) {
185                     // Invalid range means send full entity with 200 OK.
186
ranges = null;
187                 }
188                 
189                 transaction.setHeader("Content-Type", resource.getContentType());
190
191                 resource.getMount().resourceAccessDownloading(resource, transaction);
192     
193                 OutputStream JavaDoc out = transaction.getOutputStream();
194                 byte buffer[] = new byte[32768];
195
196                 InputStream JavaDoc in = null;
197                 
198                 try {
199                 
200                     if(ranges == null || ranges.length > 1 /* We dont support multiple ranges yet */) {
201                         /* Processing a normal resource request */
202                         in = resource.getInputStream();
203                         int k;
204                         while ((k = in.read(buffer)) != -1) {
205                             out.write(buffer, 0, k);
206                             total += k;
207                         }
208                     } else {
209                         /* Process a single range */
210                         
211                         RandomAccessContent content = resource.getFile().getContent().getRandomAccessContent(RandomAccessMode.READ);
212         
213                         content.seek(ranges[0].startPosition);
214                         in = content.getInputStream();
215                         
216                         long count = ranges[0].count;
217                         int k;
218                         while(count > 0) {
219                             while ((k = in.read(buffer, 0, (int) (count < buffer.length ? count : buffer.length))) != -1) {
220                                 out.write(buffer, 0, k);
221                                 total += k;
222                                 count -= k;
223                             }
224                         }
225                             
226                         transaction.setHeader("Content-Range", "bytes " + ranges[0].startPosition
227                                 + "-" + ranges[0].startPosition
228                                 + ranges[0].count + "/" + resource.getFile().getContent().getSize());
229                         
230                         transaction.setStatus(206 /* Partial */);
231                         
232                     }
233                 }
234                 finally {
235                     Util.closeStream(in);
236                 }
237                 resource.getMount().resourceAccessDownloadComplete(resource, transaction, null);
238             } catch (IOException JavaDoc ioe) {
239                 resource.getMount().resourceAccessDownloadComplete(resource, transaction, ioe);
240                 throw ioe;
241             }
242         } finally {
243             VFSLockManager.getInstance().unlock(transaction.getSessionInfo(), handle);
244         }
245
246     }
247     
248     private Range[] processRangeHeader(DAVTransaction transaction, VFSResource resource) throws IOException JavaDoc {
249         
250         try {
251             if(transaction.getRequest().getHeader("Range")!=null) {
252                 
253                 String JavaDoc header = transaction.getRequest().getHeader("Range").toLowerCase();
254                 
255                 if(header.startsWith("bytes=")) {
256                     
257                     Vector JavaDoc v = new Vector JavaDoc();
258                     
259                     StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(header.substring(6), ",");
260                     while(tokens.hasMoreTokens()) {
261                         String JavaDoc r = tokens.nextToken();
262
263                         if(log.isDebugEnabled())
264                             log.debug("Processing byte range " + r);
265                         
266                         int idx = r.indexOf('-');
267                         
268                         String JavaDoc startPoint = r.substring(0, idx);
269                         String JavaDoc endPoint = r.substring(idx+1);
270                         
271                         Range newRange = new Range();
272                         
273                         if("".equals(startPoint) && !"".equals(endPoint)) {
274                             
275                             newRange.count = Long.parseLong(endPoint);
276                             newRange.startPosition = resource.getFile().getContent().getSize() - newRange.count;
277                             
278                         } else if(!"".equals(startPoint) && "".equals(endPoint)) {
279                             
280                             newRange.startPosition = Long.parseLong(startPoint);
281                             newRange.count = resource.getFile().getContent().getSize() - newRange.startPosition;
282                             
283                         } else if(!"".equals(startPoint) && !"".equals(endPoint)) {
284                             
285                             newRange.startPosition = Long.parseLong(startPoint);
286                             newRange.count = Long.parseLong(endPoint) - newRange.startPosition;
287                             
288                         } else {
289                             log.error("Unsupported byte range element: " + r);
290                         }
291                     }
292                     
293                     if(v.size() > 0) {
294                         return (Range[]) v.toArray(new Range[0]);
295                     }
296                 }
297                 
298             }
299         } catch (Throwable JavaDoc t) {
300             log.error("Failed to process byte range header " + transaction.getRequest().getHeader("Range"), t);
301             throw new IOException JavaDoc("Invalid range");
302         }
303         
304         return null;
305     }
306     
307     
308     class Range {
309         
310         long startPosition;
311         long count;
312     }
313 }
314
Popular Tags