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