1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.framework.action;
35
36 import com.vaadin.util.EncodeUtil;
37 import info.magnolia.ui.api.action.AbstractAction;
38 import info.magnolia.ui.api.action.ActionExecutionException;
39 import info.magnolia.ui.vaadin.integration.jcr.JcrItemAdapter;
40 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
41 import info.magnolia.ui.vaadin.server.DownloadStreamResource;
42
43 import java.io.InputStream;
44
45 import javax.inject.Inject;
46 import javax.jcr.Binary;
47 import javax.jcr.Node;
48 import javax.jcr.RepositoryException;
49
50 import com.vaadin.server.Page;
51 import com.vaadin.server.StreamResource;
52
53
54
55
56
57
58 public class DownloadBinaryAction<D extends DownloadBinaryActionDefinition> extends AbstractAction<D> {
59
60 private static final String CONTENT_TYPE = "application/octet-stream";
61 private final DownloadBinaryActionDefinition definition;
62 private final JcrItemAdapter item;
63
64 @Inject
65 public DownloadBinaryAction(D definition, JcrItemAdapter item) {
66 super(definition);
67 this.definition = definition;
68 this.item = item;
69 }
70
71 @Override
72 public void execute() throws ActionExecutionException {
73 if (item instanceof JcrNodeAdapter) {
74 final Node node = (Node) item.getJcrItem();
75 final InputStream inputStream;
76 Node binaryNode;
77 String fileName;
78 StreamResource streamResource;
79 try {
80 binaryNode = getBinaryNode(node);
81 fileName = getFileName(binaryNode);
82 inputStream = getInputStream(binaryNode);
83 streamResource = getStreamResource(inputStream, fileName);
84
85 Page.getCurrent().open(streamResource, null, false);
86 } catch (RepositoryException e) {
87 throw new ActionExecutionException(String.format("Error getting binary data from node [%s] to download.", node), e);
88 }
89 }
90 }
91
92
93
94
95
96
97
98 protected DownloadStreamResource getStreamResource(final InputStream inputStream, String fileName) {
99 final DownloadStreamResource resource = new DownloadStreamResource(new StreamResource.StreamSource() {
100 @Override
101 public InputStream getStream() {
102 return inputStream;
103 }
104 }, fileName);
105
106
107
108 resource.setCacheTime(-1);
109 String encodedFilename = EncodeUtil.rfc5987Encode(fileName);
110 resource.getStream().setParameter("Content-Disposition", String.format("attachment;filename=\"%s\"; filename*=utf-8''%s",
111 encodedFilename, encodedFilename));
112 resource.setMIMEType(CONTENT_TYPE);
113 return resource;
114 }
115
116 protected InputStream getInputStream(Node binaryNode) throws RepositoryException {
117 Binary binary = binaryNode.getProperty(definition.getDataProperty()).getBinary();
118 return binary.getStream();
119 }
120
121 protected String getFileName(Node binaryNode) throws RepositoryException {
122 String fileName = binaryNode.getProperty(definition.getFileNameProperty()).getString();
123 String extension = "." + binaryNode.getProperty(definition.getExtensionProperty()).getString();
124 return fileName.endsWith(extension) ? fileName : fileName + extension;
125 }
126
127 protected Node getBinaryNode(Node node) throws RepositoryException {
128 return node.getNode(definition.getBinaryNodeName());
129 }
130
131 }