View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         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,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.eclipse.ui.specific;
17  
18  import static org.argeo.eclipse.ui.util.SingleSourcingConstants.FILE_SCHEME;
19  import static org.argeo.eclipse.ui.util.SingleSourcingConstants.SCHEME_HOST_SEPARATOR;
20  
21  import java.io.IOException;
22  import java.nio.file.Files;
23  import java.nio.file.Path;
24  import java.nio.file.Paths;
25  
26  import javax.servlet.ServletException;
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  
30  import org.argeo.eclipse.ui.EclipseUiUtils;
31  import org.argeo.eclipse.ui.util.SingleSourcingConstants;
32  import org.eclipse.rap.rwt.service.ServiceHandler;
33  
34  /**
35   * RWT specific Basic Default service handler that retrieves a file on the
36   * server file system using its absolute path and forwards it to the end user
37   * browser.
38   * 
39   * Clients might extend to provide context specific services
40   */
41  public class OpenFileService implements ServiceHandler {
42  	public OpenFileService() {
43  	}
44  
45  	public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
46  		String fileName = request.getParameter(SingleSourcingConstants.PARAM_FILE_NAME);
47  		String uri = request.getParameter(SingleSourcingConstants.PARAM_FILE_URI);
48  
49  		// Use buffered array to directly write the stream?
50  		if (!uri.startsWith(SingleSourcingConstants.FILE_SCHEME))
51  			throw new IllegalArgumentException(
52  					"Open file service can only handle files that are on the server file system");
53  
54  		// Set the Metadata
55  		response.setContentLength((int) getFileSize(uri));
56  		if (EclipseUiUtils.isEmpty(fileName))
57  			fileName = getFileName(uri);
58  		response.setContentType(getMimeType(uri, fileName));
59  		String contentDisposition = "attachment; filename=\"" + fileName + "\"";
60  		response.setHeader("Content-Disposition", contentDisposition);
61  
62  		// Useless for current use
63  		// response.setHeader("Content-Transfer-Encoding", "binary");
64  		// response.setHeader("Pragma", "no-cache");
65  		// response.setHeader("Cache-Control", "no-cache, must-revalidate");
66  
67  		Path path = Paths.get(getAbsPathFromUri(uri));
68  		Files.copy(path, response.getOutputStream());
69  
70  		// FIXME we always use temporary files for the time being.
71  		// the deleteOnClose file only works when the JVM is closed so we
72  		// explicitly delete to avoid overloading the server
73  		if (path.startsWith("/tmp"))
74  			path.toFile().delete();
75  	}
76  
77  	protected long getFileSize(String uri) throws IOException {
78  		if (uri.startsWith(SingleSourcingConstants.FILE_SCHEME)) {
79  			Path path = Paths.get(getAbsPathFromUri(uri));
80  			return Files.size(path);
81  		}
82  		return -1l;
83  	}
84  
85  	protected String getFileName(String uri) {
86  		if (uri.startsWith(SingleSourcingConstants.FILE_SCHEME)) {
87  			Path path = Paths.get(getAbsPathFromUri(uri));
88  			return path.getFileName().toString();
89  		}
90  		return null;
91  	}
92  
93  	private String getAbsPathFromUri(String uri) {
94  		if (uri.startsWith(FILE_SCHEME))
95  			return uri.substring((FILE_SCHEME + SCHEME_HOST_SEPARATOR).length());
96  		// else if (uri.startsWith(JCR_SCHEME))
97  		// return uri.substring((JCR_SCHEME + SCHEME_HOST_SEPARATOR).length());
98  		else
99  			throw new IllegalArgumentException("Unknown URI prefix for" + uri);
100 	}
101 
102 	protected String getMimeType(String uri, String fileName) throws IOException {
103 		if (uri.startsWith(FILE_SCHEME)) {
104 			Path path = Paths.get(getAbsPathFromUri(uri));
105 			String mimeType = Files.probeContentType(path);
106 			if (EclipseUiUtils.notEmpty(mimeType))
107 				return mimeType;
108 		}
109 		return "application/octet-stream";
110 	}
111 }