1 package org
.argeo
.library
.ui
;
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
;
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
;
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
;
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
;
37 public class DocumentsUiService
{
38 private final static Log log
= LogFactory
.getLog(DocumentsUiService
.class);
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";
52 public String
getLabel(String 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
:
64 case ACTION_ID_DELETE
:
66 case ACTION_ID_UPLOAD_FILE
:
67 return "Upload Files";
68 // case ACTION_ID_OPEN:
70 case ACTION_ID_DELETE_BOOKMARK
:
71 return "Delete bookmark";
72 case ACTION_ID_RENAME_BOOKMARK
:
73 return "Rename bookmark";
75 throw new IllegalArgumentException("Unknown action ID " + actionId
);
79 public void openFile(Path toOpenPath
) {
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
);
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
);
100 public boolean deleteItems(Shell shell
, IStructuredSelection selection
) {
101 if (selection
.isEmpty())
104 StringBuilder builder
= new StringBuilder();
105 @SuppressWarnings("unchecked")
106 Iterator
<Object
> iterator
= selection
.iterator();
107 List
<Path
> paths
= new ArrayList
<>();
109 while (iterator
.hasNext()) {
110 Path path
= (Path
) iterator
.next();
111 builder
.append(path
.getFileName() + ", ");
114 String msg
= "You are about to delete following elements: " + builder
.substring(0, builder
.length() - 2)
116 if (openConfirm(msg
)) {
117 for (Path path
: paths
) {
119 // recursively delete directory and its content
120 Files
.walkFileTree(path
, new SimpleFileVisitor
<Path
>() {
122 public FileVisitResult
visitFile(Path file
, BasicFileAttributes attrs
) throws IOException
{
124 return FileVisitResult
.CONTINUE
;
128 public FileVisitResult
postVisitDirectory(Path dir
, IOException exc
) throws IOException
{
130 return FileVisitResult
.CONTINUE
;
133 } catch (DirectoryNotEmptyException e
) {
134 String errMsg
= path
.getFileName() + " cannot be deleted: directory is not empty.";
136 throw new IllegalArgumentException("Cannot delete path " + path
, e
);
137 } catch (IOException e
) {
138 String errMsg
= e
.toString();
140 throw new IllegalArgumentException("Cannot delete path " + path
, e
);
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
)) {
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";
159 throw new IllegalArgumentException(errMsg
);
161 Files
.move(toRenamePath
, child
);
164 } catch (IOException e
) {
165 throw new IllegalStateException("Cannot rename " + name
+ " at " + parentFolderPath
.toString(), e
);
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
)) {
178 Path child
= currFolderPath
.resolve(name
);
179 if (Files
.exists(child
)) {
180 String errMsg
= "A folder named " + name
+ " already exists at " + currFolderPath
.toString()
183 throw new IllegalArgumentException(errMsg
);
185 Files
.createDirectories(child
);
188 } catch (IOException e
) {
189 throw new IllegalStateException("Cannot create folder " + name
+ " at " + currFolderPath
.toString(), e
);
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);
202 public boolean uploadFiles(Shell shell
, Path currFolderPath
) {
203 // shell = Display.getCurrent().getActiveShell();// ignore argument
205 FileDialog dialog
= new FileDialog(shell
, SWT
.MULTI
);
206 dialog
.setText("Choose one or more files to upload");
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
213 // 2. in RCP we must use getFilterPath that does not
215 Method filterMethod
= null;
218 filterMethod
= dialog
.getClass().getDeclaredMethod("getFilterPath");
219 String filterPath
= (String
) filterMethod
.invoke(dialog
);
220 parPath
= Paths
.get(filterPath
);
221 } catch (NoSuchMethodException nsme
) { // RAP
223 if (names
.length
== 0)
226 loop
: for (String name
: names
) {
227 Path tmpPath
= Paths
.get(name
);
229 tmpPath
= parPath
.resolve(tmpPath
);
230 if (Files
.exists(tmpPath
)) {
231 URI uri
= tmpPath
.toUri();
232 String uriStr
= uri
.toString();
234 if (Files
.isDirectory(tmpPath
)) {
236 "Upload of directories in the system is not yet implemented");
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
);
244 if (log
.isDebugEnabled())
245 log
.debug("copied uploaded file " + uriStr
+ " to " + targetPath
.toString());
247 String msg
= "Cannot copy tmp file from " + tmpPath
.toString();
249 msg
+= "\nPlease remember that file upload fails when choosing files from the \"Recently Used\" bookmarks on some OS";
257 } catch (Exception e
) {
258 CmsFeedback
.show("Cannot import files to " + currFolderPath
,e
);
263 // public boolean deleteBookmark(Shell shell, IStructuredSelection selection, Node bookmarkParent) {
264 // if (selection.isEmpty())
267 // StringBuilder builder = new StringBuilder();
268 // @SuppressWarnings("unchecked")
269 // Iterator<Object> iterator = selection.iterator();
270 // List<Node> nodes = new ArrayList<>();
272 // while (iterator.hasNext()) {
273 // Node node = (Node) iterator.next();
274 // builder.append(Jcr.get(node, Property.JCR_TITLE) + ", ");
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);
282 // if (session.hasPendingChanges())
283 // throw new DocumentsException("Cannot remove bookmarks, session is not clean");
284 // for (Node path : nodes)
286 // bookmarkParent.getSession().save();
288 // } catch (RepositoryException e) {
289 // JcrUtils.discardQuietly(session);
290 // throw new DocumentsException("Cannot delete bookmarks " + builder.toString(), e);
296 // public boolean renameBookmark(IStructuredSelection selection) {
297 // if (selection.isEmpty() || selection.size() > 1)
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);