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.command;
35
36 import info.magnolia.cms.beans.config.MIMEMapping;
37 import info.magnolia.cms.core.FileSystemHelper;
38 import info.magnolia.cms.core.Path;
39 import info.magnolia.commands.impl.BaseRepositoryCommand;
40 import info.magnolia.context.Context;
41 import info.magnolia.i18nsystem.SimpleTranslator;
42 import info.magnolia.jcr.util.NodeTypes;
43 import info.magnolia.jcr.util.NodeUtil;
44 import info.magnolia.objectfactory.Components;
45 import info.magnolia.ui.form.field.upload.UploadReceiver;
46
47 import java.io.File;
48 import java.io.FileOutputStream;
49 import java.io.IOException;
50 import java.io.InputStream;
51 import java.util.Collections;
52 import java.util.Comparator;
53 import java.util.Iterator;
54 import java.util.List;
55
56 import javax.inject.Inject;
57 import javax.jcr.Node;
58 import javax.jcr.RepositoryException;
59
60 import org.apache.commons.collections4.EnumerationUtils;
61 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
62 import org.apache.commons.compress.archivers.zip.ZipFile;
63 import org.apache.commons.io.IOUtils;
64 import org.apache.commons.lang3.StringUtils;
65 import org.vaadin.easyuploads.UploadField;
66
67
68
69
70
71
72
73
74 @Deprecated
75 public class ImportZipCommand extends BaseRepositoryCommand {
76
77 public static final String STREAM_PROPERTY = "inputStream";
78
79 public static final String ENCODING_PROPERTY = "encoding";
80
81 public static final String ZIP_TMP_FILE_PREFIX = "zipupload";
82
83 public static final String ZIP_TMP_FILE_SUFFIX = ".zip";
84
85 public static final String DEFAULT_MIME_TYPE = "application/octet-stream";
86
87 public static final String BACKSLASH_DUMMY = "________backslash________";
88
89 private final SimpleTranslator i18n;
90 private final FileSystemHelper fileSystemHelper;
91
92 private InputStream inputStream;
93
94 protected Context context;
95
96 private String encoding;
97
98 @Inject
99 public ImportZipCommand(SimpleTranslator i18n, FileSystemHelper fileSystemHelper) {
100 this.i18n = i18n;
101 this.fileSystemHelper = fileSystemHelper;
102 }
103
104
105
106
107 @Deprecated
108 public ImportZipCommand(SimpleTranslator i18n) {
109 this(i18n, Components.getComponent(FileSystemHelper.class));
110 }
111
112 @Override
113 public boolean execute(Context context) throws Exception {
114 this.context = context;
115 File tmpFile = null;
116 FileOutputStream tmpStream = null;
117 File tempDirectory = fileSystemHelper.getTempDirectory();
118 try {
119 tmpFile = File.createTempFile(ZIP_TMP_FILE_PREFIX, ZIP_TMP_FILE_SUFFIX, tempDirectory);
120 tmpStream = new FileOutputStream(tmpFile);
121 IOUtils.copy(inputStream, tmpStream);
122 } catch (IOException e) {
123 log.error("Failed to dump zip file to temp file: ", e);
124 throw e;
125 } finally {
126 IOUtils.closeQuietly(tmpStream);
127 IOUtils.closeQuietly(inputStream);
128 }
129
130 if (isValid(tmpFile)) {
131 ZipFile zip = new ZipFile(tmpFile, getEncoding());
132
133
134
135
136 final List zipEntries = EnumerationUtils.toList(zip.getEntries());
137 Collections.sort(zipEntries, new Comparator() {
138 @Override
139 public int compare(Object first, Object second) {
140 ZipArchiveEntry firstEntry = ((ZipArchiveEntry) first);
141 ZipArchiveEntry secondEntry = ((ZipArchiveEntry) second);
142 if (firstEntry.isDirectory() != secondEntry.isDirectory()) {
143
144 return Boolean.compare(secondEntry.isDirectory(), firstEntry.isDirectory());
145 }
146
147 return firstEntry.getName().compareTo(secondEntry.getName());
148 }
149 });
150
151 final Iterator it = zipEntries.iterator();
152 while (it.hasNext()) {
153 ZipArchiveEntry entry = (ZipArchiveEntry) it.next();
154 processEntry(zip, entry);
155 }
156 context.getJCRSession(getRepository()).save();
157 }
158 return false;
159 }
160
161 private void processEntry(ZipFile zip, ZipArchiveEntry entry) throws IOException, RepositoryException {
162 if (entry.getName().startsWith("__MACOSX")) {
163 return;
164 } else if (entry.getName().endsWith(".DS_Store")) {
165 return;
166 }
167
168 if (entry.isDirectory()) {
169 ensureFolder(entry);
170 } else {
171 handleFileEntry(zip, entry);
172 }
173
174 }
175
176 protected void handleFileEntry(ZipFile zip, ZipArchiveEntry entry) throws IOException, RepositoryException {
177 String fileName = entry.getName();
178 if (StringUtils.contains(fileName, "/")) {
179 fileName = StringUtils.substringAfterLast(fileName, "/");
180 }
181
182 String extension = StringUtils.substringAfterLast(fileName, ".");
183 InputStream stream = zip.getInputStream(entry);
184 FileOutputStream os = null;
185 try {
186 UploadReceiver receiver = createReceiver();
187
188 String folderPath = extractEntryPath(entry);
189 if (folderPath.startsWith("/")) {
190 folderPath = folderPath.substring(1);
191 }
192 Node folder = getJCRNode(context);
193 if (StringUtils.isNotBlank(folderPath)) {
194 if (folder.hasNode(folderPath)) {
195 folder = folder.getNode(folderPath);
196 } else {
197 folder = NodeUtil.createPath(folder, folderPath, NodeTypes.Folder.NAME, true);
198 }
199 }
200 receiver.setFieldType(UploadField.FieldType.BYTE_ARRAY);
201 receiver.receiveUpload(fileName, StringUtils.defaultIfEmpty(MIMEMapping.getMIMEType(extension), DEFAULT_MIME_TYPE));
202 receiver.setValue(IOUtils.toByteArray(stream));
203
204 doHandleEntryFromReceiver(folder, receiver);
205 } catch (Exception e) {
206 throw e;
207 } finally {
208 IOUtils.closeQuietly(stream);
209 IOUtils.closeQuietly(os);
210 }
211 }
212
213 protected UploadReceiver createReceiver() {
214 return new UploadReceiver(Path.getTempDirectory(), i18n);
215 }
216
217
218
219
220
221
222
223
224 protected void doHandleEntryFromReceiver(Node folder, UploadReceiver receiver) throws RepositoryException {
225 }
226
227 private void ensureFolder(ZipArchiveEntry entry) throws RepositoryException {
228 String path = extractEntryPath(entry);
229 NodeUtil.createPath(getJCRNode(context), path, NodeTypes.Folder.NAME, true);
230 }
231
232 private String extractEntryPath(ZipArchiveEntry entry) {
233 String entryName = entry.getName();
234 String path = (StringUtils.contains(entryName, "/")) ? StringUtils.substringBeforeLast(entryName, "/") : "/";
235
236 if (!path.startsWith("/")) {
237 path = "/" + path;
238 }
239
240
241 path = StringUtils.replace(path, "/", BACKSLASH_DUMMY);
242 path = Path.getValidatedLabel(path);
243 path = StringUtils.replace(path, BACKSLASH_DUMMY, "/");
244 return path;
245 }
246
247 private boolean isValid(File tmpFile) {
248 return tmpFile != null;
249 }
250
251
252 public InputStream getInputStream() {
253 return inputStream;
254 }
255
256 public void setInputStream(InputStream inputStream) {
257 this.inputStream = inputStream;
258 }
259
260 public String getEncoding() {
261 return encoding;
262 }
263
264 public void setEncoding(String encoding) {
265 this.encoding = encoding;
266 }
267 }