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