Created
February 10, 2015 13:54
-
-
Save kungfoo/8a507b1657c82ae51d7b to your computer and use it in GitHub Desktop.
FileDownloader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class FileDownloader extends AbstractExtension { | |
private boolean overrideContentType = true; | |
/** | |
* Creates a new file downloader for the given resource. To use the | |
* downloader, you should also {@link #extend(AbstractClientConnector)} the | |
* component. | |
* | |
* @param resource | |
* the resource to download when the user clicks the extended | |
* component. | |
*/ | |
public FileDownloader(Resource resource) { | |
if (resource == null) { | |
throw new IllegalArgumentException("resource may not be null"); | |
} | |
setResource("dl", resource); | |
} | |
public void extend(AbstractComponent target) { | |
super.extend(target); | |
} | |
/** | |
* Gets the resource set for download. | |
* | |
* @return the resource that will be downloaded if clicking the extended | |
* component | |
*/ | |
public Resource getFileDownloadResource() { | |
return getResource("dl"); | |
} | |
/** | |
* Sets the resource that is downloaded when the extended component is | |
* clicked. | |
* | |
* @param resource | |
* the resource to download | |
*/ | |
public void setFileDownloadResource(Resource resource) { | |
setResource("dl", resource); | |
} | |
/** | |
* Sets whether the content type of served resources should be overriden to | |
* <code>application/octet-stream</code> to reduce the risk of a browser | |
* plugin choosing to display the resource instead of downloading it. This | |
* is by default set to <code>true</code>. | |
* <p> | |
* Please note that this only affects Connector resources (e.g. | |
* {@link FileResource} and {@link ClassResource}) but not other resource | |
* types (e.g. {@link ExternalResource} or {@link ThemeResource}). | |
* </p> | |
* | |
* @param overrideContentType | |
* <code>true</code> to override the content type if possible; | |
* <code>false</code> to use the original content type. | |
*/ | |
public void setOverrideContentType(boolean overrideContentType) { | |
this.overrideContentType = overrideContentType; | |
} | |
/** | |
* Checks whether the content type should be overridden. | |
* | |
* @see #setOverrideContentType(boolean) | |
* | |
* @return <code>true</code> if the content type will be overridden when | |
* possible; <code>false</code> if the original content type will be | |
* used. | |
*/ | |
public boolean isOverrideContentType() { | |
return overrideContentType; | |
} | |
@Override | |
public boolean handleConnectorRequest(VaadinRequest request, | |
VaadinResponse response, String path) throws IOException { | |
if (!path.matches("dl(/.*)?")) { | |
// Ignore if it isn't for us | |
return false; | |
} | |
VaadinSession session = getSession(); | |
session.lock(); | |
DownloadStream stream; | |
try { | |
Resource resource = getFileDownloadResource(); | |
if (!(resource instanceof ConnectorResource)) { | |
return false; | |
} | |
stream = ((ConnectorResource) resource).getStream(); | |
if (stream.getParameter("Content-Disposition") == null) { | |
// Content-Disposition: attachment generally forces download | |
stream.setParameter("Content-Disposition", | |
"attachment; filename=\"" + stream.getFileName() + "\""); | |
} | |
// Content-Type to block eager browser plug-ins from hijacking | |
// the file | |
if (isOverrideContentType()) { | |
stream.setContentType("application/octet-stream;charset=UTF-8"); | |
} | |
} finally { | |
session.unlock(); | |
} | |
stream.writeResponse(request, response); | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment