]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.eclipse.ui.workbench/src/org/argeo/eclipse/ui/workbench/jcr/internal/parts/ImportFileSystemWizard.java
Remove JcrSecurityModel from supported APIs
[lgpl/argeo-commons.git] / org.argeo.eclipse.ui.workbench / src / org / argeo / eclipse / ui / workbench / jcr / internal / parts / ImportFileSystemWizard.java
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.workbench.jcr.internal.parts;
17
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.InputStream;
21
22 import javax.jcr.Binary;
23 import javax.jcr.Node;
24 import javax.jcr.Property;
25 import javax.jcr.nodetype.NodeType;
26
27 import org.apache.commons.io.FileUtils;
28 import org.apache.commons.io.IOUtils;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.argeo.ArgeoException;
32 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
33 import org.argeo.eclipse.ui.specific.UploadFileWizardPage;
34 import org.eclipse.core.runtime.IProgressMonitor;
35 import org.eclipse.jface.dialogs.MessageDialog;
36 import org.eclipse.jface.operation.IRunnableWithProgress;
37 import org.eclipse.jface.wizard.Wizard;
38
39 public class ImportFileSystemWizard extends Wizard {
40 private final static Log log = LogFactory
41 .getLog(ImportFileSystemWizard.class);
42
43 private UploadFileWizardPage importPage;
44 private final Node folder;
45
46 public ImportFileSystemWizard(Node folder) {
47 this.folder = folder;
48 setWindowTitle("Import from file system");
49 }
50
51 @Override
52 public void addPages() {
53 importPage = new UploadFileWizardPage();
54 addPage(importPage);
55 setNeedsProgressMonitor(importPage.getNeedsProgressMonitor());
56 }
57
58 /**
59 * Called when the user click on 'Finish' in the wizard. The real upload to
60 * the JCR repository is done here.
61 */
62 @Override
63 public boolean performFinish() {
64
65 // Initialization
66 final String objectType = importPage.getObjectType();
67 final String objectPath = importPage.getObjectPath();
68
69 // We do not display a progress bar for one file only
70 if (UploadFileWizardPage.FILE_ITEM_TYPE.equals(objectType)) {
71 // In Rap we must force the "real" upload of the file
72 // importPage.performFinish();
73 try {
74 Node fileNode = folder.addNode(importPage.getObjectName(),
75 NodeType.NT_FILE);
76 Node resNode = fileNode.addNode(Property.JCR_CONTENT,
77 NodeType.NT_RESOURCE);
78 Binary binary = null;
79 InputStream is = null;
80 try {
81 is = importPage.getFileInputStream();
82 binary = folder.getSession().getValueFactory()
83 .createBinary(is);
84 resNode.setProperty(Property.JCR_DATA, binary);
85 } finally {
86 if (binary != null)
87 binary.dispose();
88 IOUtils.closeQuietly(is);
89 }
90 folder.getSession().save();
91 } catch (Exception e) {
92 e.printStackTrace();
93 return false;
94 }
95 return true;
96 } else if (UploadFileWizardPage.FOLDER_ITEM_TYPE.equals(objectType)) {
97 if (objectPath == null || !new File(objectPath).exists()) {
98 ErrorFeedback.show("Directory " + objectPath
99 + " does not exist");
100 return false;
101 }
102
103 Boolean failed = false;
104 final File dir = new File(objectPath).getAbsoluteFile();
105 final Long sizeB = directorySize(dir, 0l);
106 final Stats stats = new Stats();
107 Long begin = System.currentTimeMillis();
108 try {
109 getContainer().run(true, true, new IRunnableWithProgress() {
110 public void run(IProgressMonitor monitor) {
111 try {
112 Integer sizeKB = (int) (sizeB / FileUtils.ONE_KB);
113 monitor.beginTask("", sizeKB);
114 importDirectory(folder, dir, monitor, stats);
115 monitor.done();
116 } catch (Exception e) {
117 if (e instanceof RuntimeException)
118 throw (RuntimeException) e;
119 else
120 throw new ArgeoException("Cannot import "
121 + objectPath, e);
122 }
123 }
124 });
125 } catch (Exception e) {
126 ErrorFeedback.show("Cannot import " + objectPath, e);
127 failed = true;
128 }
129
130 Long duration = System.currentTimeMillis() - begin;
131 Long durationS = duration / 1000l;
132 String durationStr = (durationS / 60) + " min " + (durationS % 60)
133 + " s";
134 StringBuffer message = new StringBuffer("Imported\n");
135 message.append(stats.fileCount).append(" files\n");
136 message.append(stats.dirCount).append(" directories\n");
137 message.append(FileUtils.byteCountToDisplaySize(stats.sizeB));
138 if (failed)
139 message.append(" of planned ").append(
140 FileUtils.byteCountToDisplaySize(sizeB));
141 message.append("\n");
142 message.append("in ").append(durationStr).append("\n");
143 if (failed)
144 MessageDialog.openError(getShell(), "Import failed",
145 message.toString());
146 else
147 MessageDialog.openInformation(getShell(), "Import successful",
148 message.toString());
149
150 return true;
151 }
152 return false;
153
154 }
155
156 /** Recursively computes the size of the directory in bytes. */
157 protected Long directorySize(File dir, Long currentSize) {
158 Long size = currentSize;
159 File[] files = dir.listFiles();
160 for (File file : files) {
161 if (file.isDirectory()) {
162 size = directorySize(file, size);
163 } else {
164 size = size + file.length();
165 }
166 }
167 return size;
168 }
169
170 /**
171 * Import recursively a directory and its content to the repository.
172 */
173 protected void importDirectory(Node folder, File dir,
174 IProgressMonitor monitor, Stats stats) {
175 try {
176 File[] files = dir.listFiles();
177 for (File file : files) {
178 if (file.isDirectory()) {
179 Node childFolder = folder.addNode(file.getName(),
180 NodeType.NT_FOLDER);
181 importDirectory(childFolder, file, monitor, stats);
182 folder.getSession().save();
183 stats.dirCount++;
184 } else {
185 Long fileSize = file.length();
186 // we skip temporary files that are created by apps when a
187 // file is being edited.
188 // TODO : make this configurable.
189 if (file.getName().lastIndexOf('~') != file.getName()
190 .length() - 1) {
191
192 monitor.subTask(file.getName() + " ("
193 + FileUtils.byteCountToDisplaySize(fileSize)
194 + ") " + file.getCanonicalPath());
195 try {
196 Node fileNode = folder.addNode(file.getName(),
197 NodeType.NT_FILE);
198 Node resNode = fileNode.addNode(
199 Property.JCR_CONTENT, NodeType.NT_RESOURCE);
200 Binary binary = null;
201 try {
202 binary = folder
203 .getSession()
204 .getValueFactory()
205 .createBinary(new FileInputStream(file));
206 resNode.setProperty(Property.JCR_DATA, binary);
207 } finally {
208 if (binary != null)
209 binary.dispose();
210 }
211 folder.getSession().save();
212 stats.fileCount++;
213 stats.sizeB = stats.sizeB + fileSize;
214 } catch (Exception e) {
215 log.warn("Import of "
216 + file
217 + " ("
218 + FileUtils
219 .byteCountToDisplaySize(fileSize)
220 + ") failed: " + e);
221 folder.getSession().refresh(false);
222 }
223 monitor.worked((int) (fileSize / FileUtils.ONE_KB));
224 }
225 }
226 }
227 } catch (Exception e) {
228 throw new ArgeoException("Cannot import " + dir + " to " + folder,
229 e);
230 }
231 }
232
233 static class Stats {
234 public Long fileCount = 0l;
235 public Long dirCount = 0l;
236 public Long sizeB = 0l;
237 }
238 }