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