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.module.googlesitemap.app.actions;
35
36 import info.magnolia.cms.core.Path;
37 import info.magnolia.i18nsystem.SimpleTranslator;
38 import info.magnolia.module.googlesitemap.service.SiteMapXMLUtil;
39 import info.magnolia.ui.api.action.AbstractAction;
40 import info.magnolia.ui.api.action.ActionExecutionException;
41 import info.magnolia.ui.api.context.UiContext;
42 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
43 import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
44
45 import java.io.File;
46 import java.io.FileInputStream;
47 import java.io.FileNotFoundException;
48 import java.io.FileOutputStream;
49 import java.io.IOException;
50 import java.io.InputStream;
51
52 import javax.inject.Inject;
53 import javax.jcr.RepositoryException;
54 import javax.xml.bind.JAXBException;
55
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59 import com.vaadin.server.Page;
60 import com.vaadin.server.StreamResource;
61
62
63
64
65
66 public class ExportSiteMapToXMLAction<T extends ExportSiteMapToXMLActionDefinition> extends AbstractAction<T> {
67
68 public static final String XML_EXTENSION = ".xml";
69
70 private Logger log = LoggerFactory.getLogger(getClass());
71
72 private FileOutputStream fileOutputStream;
73
74 private SimpleTranslator translator;
75
76 private JcrNodeAdapter siteMapNode;
77
78 private SiteMapXMLUtil xmlUtil;
79
80 private UiContext uiContext;
81
82 private File fileOutput;
83
84 @Inject
85 public ExportSiteMapToXMLAction(T definition, JcrNodeAdapter siteMapNode, UiContext uiContext, SimpleTranslator translator, SiteMapXMLUtil xmlUtil) {
86 super(definition);
87 this.siteMapNode = siteMapNode;
88 this.uiContext = uiContext;
89 this.translator = translator;
90 this.xmlUtil = xmlUtil;
91 }
92
93 @Override
94 public void execute() throws ActionExecutionException {
95 try {
96 String sw = xmlUtil.generateSiteMapXML(siteMapNode.getJcrItem());
97 fileOutput = File.createTempFile(siteMapNode.getItemId().toString(), XML_EXTENSION, Path.getTempDirectory());
98 fileOutputStream = new FileOutputStream(fileOutput);
99 fileOutputStream.write(sw.toString().getBytes());
100 openFileInBlankWindow(siteMapNode.getNodeName() + XML_EXTENSION, "application/octet-stream");
101 } catch (RepositoryException e) {
102 onError(e);
103 } catch (JAXBException e) {
104 onError(e);
105 } catch (IOException e) {
106 onError(e);
107 }
108 }
109
110 protected void onError(Exception e) {
111 log.error("Error occurred during site map export", e);
112 String message = translator.translate("siteMaps.export.failed");
113 uiContext.openNotification(MessageStyleTypeEnum.ERROR, true, message + ":" + e.getMessage());
114 }
115
116 protected void openFileInBlankWindow(String fileName, String mimeType) {
117 StreamResource.StreamSource source = new StreamResource.StreamSource() {
118 @Override
119 public InputStream getStream() {
120 try {
121 return new DeleteOnCloseFileInputStream(fileOutput);
122 } catch (IOException e) {
123 return null;
124 }
125 }
126 };
127 StreamResource resource = new StreamResource(source, fileName);
128 resource.setCacheTime(-1);
129 resource.getStream().setParameter("Content-Disposition", "attachment; filename=" + fileName + "\"");
130 resource.setMIMEType(mimeType);
131 resource.setCacheTime(0);
132 Page.getCurrent().open(resource, "", true);
133 }
134
135
136
137
138
139 private class DeleteOnCloseFileInputStream extends FileInputStream {
140 private File file;
141 private final Logger log = LoggerFactory.getLogger(DeleteOnCloseFileInputStream.class);
142
143 public DeleteOnCloseFileInputStream(File file) throws FileNotFoundException {
144 super(file);
145 this.file = file;
146 }
147
148 @Override
149 public void close() throws IOException {
150 super.close();
151 if (file.exists() && !file.delete()) {
152 log.warn("Could not delete temporary export file {}", file.getAbsolutePath());
153 }
154 }
155 }
156 }