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