]> git.argeo.org Git - gpl/argeo-suite.git/blob - argeo/library/ui/DocumentsUiService.java
Prepare next development cycle
[gpl/argeo-suite.git] / argeo / library / ui / DocumentsUiService.java
1 package org.argeo.library.ui;
2
3 import static org.argeo.cms.swt.dialogs.CmsMessageDialog.openConfirm;
4 import static org.argeo.cms.swt.dialogs.CmsMessageDialog.openError;
5 import static org.argeo.cms.swt.dialogs.SingleValueDialog.ask;
6
7 import java.io.File;
8 import java.io.FileInputStream;
9 import java.io.FileOutputStream;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.io.OutputStream;
13 import java.lang.reflect.Method;
14 import java.net.URI;
15 import java.nio.file.DirectoryNotEmptyException;
16 import java.nio.file.FileVisitResult;
17 import java.nio.file.Files;
18 import java.nio.file.Path;
19 import java.nio.file.Paths;
20 import java.nio.file.SimpleFileVisitor;
21 import java.nio.file.attribute.BasicFileAttributes;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.argeo.cms.swt.dialogs.CmsFeedback;
31 import org.argeo.eclipse.ui.EclipseUiUtils;
32 import org.eclipse.jface.viewers.IStructuredSelection;
33 import org.eclipse.swt.SWT;
34 import org.eclipse.swt.widgets.FileDialog;
35 import org.eclipse.swt.widgets.Shell;
36
37 public class DocumentsUiService {
38 private final static Log log = LogFactory.getLog(DocumentsUiService.class);
39
40 // Default known actions
41 public final static String ACTION_ID_CREATE_FOLDER = "createFolder";
42 public final static String ACTION_ID_BOOKMARK_FOLDER = "bookmarkFolder";
43 public final static String ACTION_ID_SHARE_FOLDER = "shareFolder";
44 public final static String ACTION_ID_DOWNLOAD_FOLDER = "downloadFolder";
45 public final static String ACTION_ID_RENAME = "rename";
46 public final static String ACTION_ID_DELETE = "delete";
47 public final static String ACTION_ID_UPLOAD_FILE = "uploadFiles";
48 // public final static String ACTION_ID_OPEN = "open";
49 public final static String ACTION_ID_DELETE_BOOKMARK = "deleteBookmark";
50 public final static String ACTION_ID_RENAME_BOOKMARK = "renameBookmark";
51
52 public String getLabel(String actionId) {
53 switch (actionId) {
54 case ACTION_ID_CREATE_FOLDER:
55 return "Create Folder";
56 case ACTION_ID_BOOKMARK_FOLDER:
57 return "Bookmark Folder";
58 case ACTION_ID_SHARE_FOLDER:
59 return "Share Folder";
60 case ACTION_ID_DOWNLOAD_FOLDER:
61 return "Download as zip archive";
62 case ACTION_ID_RENAME:
63 return "Rename";
64 case ACTION_ID_DELETE:
65 return "Delete";
66 case ACTION_ID_UPLOAD_FILE:
67 return "Upload Files";
68 // case ACTION_ID_OPEN:
69 // return "Open";
70 case ACTION_ID_DELETE_BOOKMARK:
71 return "Delete bookmark";
72 case ACTION_ID_RENAME_BOOKMARK:
73 return "Rename bookmark";
74 default:
75 throw new IllegalArgumentException("Unknown action ID " + actionId);
76 }
77 }
78
79 public void openFile(Path toOpenPath) {
80 try {
81 String name = toOpenPath.getFileName().toString();
82 File tmpFile = File.createTempFile("tmp", name);
83 tmpFile.deleteOnExit();
84 try (OutputStream os = new FileOutputStream(tmpFile)) {
85 Files.copy(toOpenPath, os);
86 } catch (IOException e) {
87 throw new IllegalStateException("Cannot open copy " + name + " to tmpFile.", e);
88 }
89 String uri = Paths.get(tmpFile.getAbsolutePath()).toUri().toString();
90 Map<String, String> params = new HashMap<String, String>();
91 // params.put(OpenFile.PARAM_FILE_NAME, name);
92 // params.put(OpenFile.PARAM_FILE_URI, uri);
93 // FIXME open file without a command
94 // CommandUtils.callCommand(OpenFile.ID, params);
95 } catch (IOException e1) {
96 throw new IllegalStateException("Cannot create tmp copy of " + toOpenPath, e1);
97 }
98 }
99
100 public boolean deleteItems(Shell shell, IStructuredSelection selection) {
101 if (selection.isEmpty())
102 return false;
103
104 StringBuilder builder = new StringBuilder();
105 @SuppressWarnings("unchecked")
106 Iterator<Object> iterator = selection.iterator();
107 List<Path> paths = new ArrayList<>();
108
109 while (iterator.hasNext()) {
110 Path path = (Path) iterator.next();
111 builder.append(path.getFileName() + ", ");
112 paths.add(path);
113 }
114 String msg = "You are about to delete following elements: " + builder.substring(0, builder.length() - 2)
115 + ". Are you sure?";
116 if (openConfirm(msg)) {
117 for (Path path : paths) {
118 try {
119 // recursively delete directory and its content
120 Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
121 @Override
122 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
123 Files.delete(file);
124 return FileVisitResult.CONTINUE;
125 }
126
127 @Override
128 public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
129 Files.delete(dir);
130 return FileVisitResult.CONTINUE;
131 }
132 });
133 } catch (DirectoryNotEmptyException e) {
134 String errMsg = path.getFileName() + " cannot be deleted: directory is not empty.";
135 openError( errMsg);
136 throw new IllegalArgumentException("Cannot delete path " + path, e);
137 } catch (IOException e) {
138 String errMsg = e.toString();
139 openError(errMsg);
140 throw new IllegalArgumentException("Cannot delete path " + path, e);
141 }
142 }
143 return true;
144 }
145 return false;
146 }
147
148 public boolean renameItem(Shell shell, Path parentFolderPath, Path toRenamePath) {
149 String msg = "Enter a new name:";
150 String name = ask( msg, toRenamePath.getFileName().toString());
151 // TODO enhance check of name validity
152 if (EclipseUiUtils.notEmpty(name)) {
153 try {
154 Path child = parentFolderPath.resolve(name);
155 if (Files.exists(child)) {
156 String errMsg = "An object named " + name + " already exists at " + parentFolderPath.toString()
157 + ", please provide another name";
158 openError( errMsg);
159 throw new IllegalArgumentException(errMsg);
160 } else {
161 Files.move(toRenamePath, child);
162 return true;
163 }
164 } catch (IOException e) {
165 throw new IllegalStateException("Cannot rename " + name + " at " + parentFolderPath.toString(), e);
166 }
167 }
168 return false;
169 }
170
171 public boolean createFolder(Shell shell, Path currFolderPath) {
172 String msg = "Enter a name:";
173 String name = ask( msg);
174 // TODO enhance check of name validity
175 if (EclipseUiUtils.notEmpty(name)) {
176 name = name.trim();
177 try {
178 Path child = currFolderPath.resolve(name);
179 if (Files.exists(child)) {
180 String errMsg = "A folder named " + name + " already exists at " + currFolderPath.toString()
181 + ", cannot create";
182 openError(errMsg);
183 throw new IllegalArgumentException(errMsg);
184 } else {
185 Files.createDirectories(child);
186 return true;
187 }
188 } catch (IOException e) {
189 throw new IllegalStateException("Cannot create folder " + name + " at " + currFolderPath.toString(), e);
190 }
191 }
192 return false;
193 }
194
195 // public void bookmarkFolder(Path toBookmarkPath, Repository repository, DocumentsService documentsService) {
196 // String msg = "Provide a name:";
197 // String name = SingleQuestion.ask("Create bookmark", msg, toBookmarkPath.getFileName().toString());
198 // if (EclipseUiUtils.notEmpty(name))
199 // documentsService.createFolderBookmark(toBookmarkPath, name, repository);
200 // }
201
202 public boolean uploadFiles(Shell shell, Path currFolderPath) {
203 // shell = Display.getCurrent().getActiveShell();// ignore argument
204 try {
205 FileDialog dialog = new FileDialog(shell, SWT.MULTI);
206 dialog.setText("Choose one or more files to upload");
207
208 if (EclipseUiUtils.notEmpty(dialog.open())) {
209 String[] names = dialog.getFileNames();
210 // Workaround small differences between RAP and RCP
211 // 1. returned names are absolute path on RAP and
212 // relative in RCP
213 // 2. in RCP we must use getFilterPath that does not
214 // exists on RAP
215 Method filterMethod = null;
216 Path parPath = null;
217 try {
218 filterMethod = dialog.getClass().getDeclaredMethod("getFilterPath");
219 String filterPath = (String) filterMethod.invoke(dialog);
220 parPath = Paths.get(filterPath);
221 } catch (NoSuchMethodException nsme) { // RAP
222 }
223 if (names.length == 0)
224 return false;
225 else {
226 loop: for (String name : names) {
227 Path tmpPath = Paths.get(name);
228 if (parPath != null)
229 tmpPath = parPath.resolve(tmpPath);
230 if (Files.exists(tmpPath)) {
231 URI uri = tmpPath.toUri();
232 String uriStr = uri.toString();
233
234 if (Files.isDirectory(tmpPath)) {
235 openError(
236 "Upload of directories in the system is not yet implemented");
237 continue loop;
238 }
239 Path targetPath = currFolderPath.resolve(tmpPath.getFileName().toString());
240 try (InputStream in = new FileInputStream(tmpPath.toFile())) {
241 Files.copy(in, targetPath);
242 Files.delete(tmpPath);
243 }
244 if (log.isDebugEnabled())
245 log.debug("copied uploaded file " + uriStr + " to " + targetPath.toString());
246 } else {
247 String msg = "Cannot copy tmp file from " + tmpPath.toString();
248 if (parPath != null)
249 msg += "\nPlease remember that file upload fails when choosing files from the \"Recently Used\" bookmarks on some OS";
250 openError( msg);
251 continue loop;
252 }
253 }
254 return true;
255 }
256 }
257 } catch (Exception e) {
258 CmsFeedback.show("Cannot import files to " + currFolderPath,e);
259 }
260 return false;
261 }
262
263 // public boolean deleteBookmark(Shell shell, IStructuredSelection selection, Node bookmarkParent) {
264 // if (selection.isEmpty())
265 // return false;
266 //
267 // StringBuilder builder = new StringBuilder();
268 // @SuppressWarnings("unchecked")
269 // Iterator<Object> iterator = selection.iterator();
270 // List<Node> nodes = new ArrayList<>();
271 //
272 // while (iterator.hasNext()) {
273 // Node node = (Node) iterator.next();
274 // builder.append(Jcr.get(node, Property.JCR_TITLE) + ", ");
275 // nodes.add(node);
276 // }
277 // String msg = "You are about to delete following bookmark: " + builder.substring(0, builder.length() - 2)
278 // + ". Are you sure?";
279 // if (MessageDialog.openConfirm(shell, "Confirm deletion", msg)) {
280 // Session session = Jcr.session(bookmarkParent);
281 // try {
282 // if (session.hasPendingChanges())
283 // throw new DocumentsException("Cannot remove bookmarks, session is not clean");
284 // for (Node path : nodes)
285 // path.remove();
286 // bookmarkParent.getSession().save();
287 // return true;
288 // } catch (RepositoryException e) {
289 // JcrUtils.discardQuietly(session);
290 // throw new DocumentsException("Cannot delete bookmarks " + builder.toString(), e);
291 // }
292 // }
293 // return false;
294 // }
295
296 // public boolean renameBookmark(IStructuredSelection selection) {
297 // if (selection.isEmpty() || selection.size() > 1)
298 // return false;
299 // Node toRename = (Node) selection.getFirstElement();
300 // String msg = "Please provide a new name.";
301 // String name = SingleQuestion.ask("Rename bookmark", msg, ConnectJcrUtils.get(toRename, Property.JCR_TITLE));
302 // if (EclipseUiUtils.notEmpty(name)
303 // && ConnectJcrUtils.setJcrProperty(toRename, Property.JCR_TITLE, PropertyType.STRING, name)) {
304 // ConnectJcrUtils.saveIfNecessary(toRename);
305 // return true;
306 // }
307 // return false;
308 // }
309 }