]> git.argeo.org Git - lgpl/argeo-commons.git/blob - trunk/server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/wizards/ImportFileSystemWizard.java
[maven-release-plugin] copy for tag argeo-commons-2.1.11
[lgpl/argeo-commons.git] / trunk / server / plugins / org.argeo.jcr.ui.explorer / src / main / java / org / argeo / jcr / ui / explorer / wizards / 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.jcr.ui.explorer.wizards;
17
18 import java.io.File;
19 import java.io.FileInputStream;
20
21 import javax.jcr.Binary;
22 import javax.jcr.Node;
23 import javax.jcr.Property;
24 import javax.jcr.nodetype.NodeType;
25
26 import org.apache.commons.io.FileUtils;
27 import org.apache.commons.io.IOUtils;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.argeo.ArgeoException;
31 import org.argeo.eclipse.ui.ErrorFeedback;
32 import org.argeo.eclipse.ui.specific.ImportToServerWizardPage;
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 (ImportToServerWizardPage.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 try {
80 binary = folder.getSession().getValueFactory()
81 .createBinary(importPage.getFileInputStream());
82 resNode.setProperty(Property.JCR_DATA, binary);
83 } finally {
84 if (binary != null)
85 binary.dispose();
86 IOUtils.closeQuietly(importPage.getFileInputStream());
87 }
88 folder.getSession().save();
89 } catch (Exception e) {
90 e.printStackTrace();
91 return false;
92 }
93 return true;
94 } else if (ImportToServerWizardPage.FOLDER_ITEM_TYPE.equals(objectType)) {
95 if (objectPath == null || !new File(objectPath).exists()) {
96 ErrorFeedback.show("Directory " + objectPath
97 + " does not exist");
98 return false;
99 }
100
101 Boolean failed = false;
102 final File dir = new File(objectPath).getAbsoluteFile();
103 final Long sizeB = directorySize(dir, 0l);
104 final Stats stats = new Stats();
105 Long begin = System.currentTimeMillis();
106 try {
107 getContainer().run(true, true, new IRunnableWithProgress() {
108 public void run(IProgressMonitor monitor) {
109 try {
110 Integer sizeKB = (int) (sizeB / FileUtils.ONE_KB);
111 monitor.beginTask("", sizeKB);
112 importDirectory(folder, dir, monitor, stats);
113 monitor.done();
114 } catch (Exception e) {
115 if (e instanceof RuntimeException)
116 throw (RuntimeException) e;
117 else
118 throw new ArgeoException("Cannot import "
119 + objectPath, e);
120 }
121 }
122 });
123 } catch (Exception e) {
124 ErrorFeedback.show("Cannot import " + objectPath, e);
125 failed = true;
126 }
127
128 Long duration = System.currentTimeMillis() - begin;
129 Long durationS = duration / 1000l;
130 String durationStr = (durationS / 60) + " min " + (durationS % 60)
131 + " s";
132 StringBuffer message = new StringBuffer("Imported\n");
133 message.append(stats.fileCount).append(" files\n");
134 message.append(stats.dirCount).append(" directories\n");
135 message.append(FileUtils.byteCountToDisplaySize(stats.sizeB));
136 if (failed)
137 message.append(" of planned ").append(
138 FileUtils.byteCountToDisplaySize(sizeB));
139 message.append("\n");
140 message.append("in ").append(durationStr).append("\n");
141 if (failed)
142 MessageDialog.openError(getShell(), "Import failed",
143 message.toString());
144 else
145 MessageDialog.openInformation(getShell(), "Import successful",
146 message.toString());
147
148 return true;
149 }
150 return false;
151
152 }
153
154 /** Recursively computes the size of the directory in bytes. */
155 protected Long directorySize(File dir, Long currentSize) {
156 Long size = currentSize;
157 File[] files = dir.listFiles();
158 for (File file : files) {
159 if (file.isDirectory()) {
160 size = directorySize(file, size);
161 } else {
162 size = size + file.length();
163 }
164 }
165 return size;
166 }
167
168 /**
169 * Import recursively a directory and its content to the repository.
170 */
171 protected void importDirectory(Node folder, File dir,
172 IProgressMonitor monitor, Stats stats) {
173 try {
174 File[] files = dir.listFiles();
175 for (File file : files) {
176 if (file.isDirectory()) {
177 Node childFolder = folder.addNode(file.getName(),
178 NodeType.NT_FOLDER);
179 importDirectory(childFolder, file, monitor, stats);
180 folder.getSession().save();
181 stats.dirCount++;
182 } else {
183 Long fileSize = file.length();
184
185 // we skip tempory files that are created by apps when a
186 // file is being edited.
187 // TODO : make this configurable.
188 if (file.getName().lastIndexOf('~') != file.getName()
189 .length() - 1) {
190
191 monitor.subTask(file.getName() + " ("
192 + FileUtils.byteCountToDisplaySize(fileSize)
193 + ") " + file.getCanonicalPath());
194 try {
195 Node fileNode = folder.addNode(file.getName(),
196 NodeType.NT_FILE);
197 Node resNode = fileNode.addNode(
198 Property.JCR_CONTENT, NodeType.NT_RESOURCE);
199 Binary binary = null;
200 try {
201 binary = folder
202 .getSession()
203 .getValueFactory()
204 .createBinary(new FileInputStream(file));
205 resNode.setProperty(Property.JCR_DATA, binary);
206 } finally {
207 if (binary != null)
208 binary.dispose();
209 }
210 folder.getSession().save();
211 stats.fileCount++;
212 stats.sizeB = stats.sizeB + fileSize;
213 } catch (Exception e) {
214 log.warn("Import of "
215 + file
216 + " ("
217 + FileUtils
218 .byteCountToDisplaySize(fileSize)
219 + ") failed: " + e);
220 folder.getSession().refresh(false);
221 }
222 monitor.worked((int) (fileSize / FileUtils.ONE_KB));
223 }
224 }
225 }
226 } catch (Exception e) {
227 throw new ArgeoException("Cannot import " + dir + " to " + folder,
228 e);
229 }
230 }
231
232 static class Stats {
233 public Long fileCount = 0l;
234 public Long dirCount = 0l;
235 public Long sizeB = 0l;
236 }
237 }