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