1 package org
.argeo
.documents
.ui
;
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
;
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
.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
;
38 public class DocumentsUiService
{
39 private final static Log log
= LogFactory
.getLog(DocumentsUiService
.class);
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";
53 public String
getLabel(String 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
:
65 case ACTION_ID_DELETE
:
67 case ACTION_ID_UPLOAD_FILE
:
68 return "Upload Files";
69 // case ACTION_ID_OPEN:
71 case ACTION_ID_DELETE_BOOKMARK
:
72 return "Delete bookmark";
73 case ACTION_ID_RENAME_BOOKMARK
:
74 return "Rename bookmark";
76 throw new IllegalArgumentException("Unknown action ID " + actionId
);
80 public void openFile(Path toOpenPath
) {
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
);
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
);
101 public boolean deleteItems(Shell shell
, IStructuredSelection selection
) {
102 if (selection
.isEmpty())
105 StringBuilder builder
= new StringBuilder();
106 @SuppressWarnings("unchecked")
107 Iterator
<Object
> iterator
= selection
.iterator();
108 List
<Path
> paths
= new ArrayList
<>();
110 while (iterator
.hasNext()) {
111 Path path
= (Path
) iterator
.next();
112 builder
.append(path
.getFileName() + ", ");
115 String msg
= "You are about to delete following elements: " + builder
.substring(0, builder
.length() - 2)
117 if (openConfirm(msg
)) {
118 for (Path path
: paths
) {
120 // recursively delete directory and its content
121 Files
.walkFileTree(path
, new SimpleFileVisitor
<Path
>() {
123 public FileVisitResult
visitFile(Path file
, BasicFileAttributes attrs
) throws IOException
{
125 return FileVisitResult
.CONTINUE
;
129 public FileVisitResult
postVisitDirectory(Path dir
, IOException exc
) throws IOException
{
131 return FileVisitResult
.CONTINUE
;
134 } catch (DirectoryNotEmptyException e
) {
135 String errMsg
= path
.getFileName() + " cannot be deleted: directory is not empty.";
137 throw new IllegalArgumentException("Cannot delete path " + path
, e
);
138 } catch (IOException e
) {
139 String errMsg
= e
.toString();
141 throw new IllegalArgumentException("Cannot delete path " + path
, e
);
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
)) {
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";
160 throw new IllegalArgumentException(errMsg
);
162 Files
.move(toRenamePath
, child
);
165 } catch (IOException e
) {
166 throw new IllegalStateException("Cannot rename " + name
+ " at " + parentFolderPath
.toString(), e
);
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
)) {
179 Path child
= currFolderPath
.resolve(name
);
180 if (Files
.exists(child
)) {
181 String errMsg
= "A folder named " + name
+ " already exists at " + currFolderPath
.toString()
184 throw new IllegalArgumentException(errMsg
);
186 Files
.createDirectories(child
);
189 } catch (IOException e
) {
190 throw new IllegalStateException("Cannot create folder " + name
+ " at " + currFolderPath
.toString(), e
);
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);
203 public boolean uploadFiles(Shell shell
, Path currFolderPath
) {
204 // shell = Display.getCurrent().getActiveShell();// ignore argument
206 FileDialog dialog
= new FileDialog(shell
, SWT
.MULTI
);
207 dialog
.setText("Choose one or more files to upload");
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
214 // 2. in RCP we must use getFilterPath that does not
216 Method filterMethod
= null;
219 filterMethod
= dialog
.getClass().getDeclaredMethod("getFilterPath");
220 String filterPath
= (String
) filterMethod
.invoke(dialog
);
221 parPath
= Paths
.get(filterPath
);
222 } catch (NoSuchMethodException nsme
) { // RAP
224 if (names
.length
== 0)
227 loop
: for (String name
: names
) {
228 Path tmpPath
= Paths
.get(name
);
230 tmpPath
= parPath
.resolve(tmpPath
);
231 if (Files
.exists(tmpPath
)) {
232 URI uri
= tmpPath
.toUri();
233 String uriStr
= uri
.toString();
235 if (Files
.isDirectory(tmpPath
)) {
237 "Upload of directories in the system is not yet implemented");
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
);
245 if (log
.isDebugEnabled())
246 log
.debug("copied uploaded file " + uriStr
+ " to " + targetPath
.toString());
248 String msg
= "Cannot copy tmp file from " + tmpPath
.toString();
250 msg
+= "\nPlease remember that file upload fails when choosing files from the \"Recently Used\" bookmarks on some OS";
258 } catch (Exception e
) {
259 CmsFeedback
.show("Cannot import files to " + currFolderPath
,e
);
264 // public boolean deleteBookmark(Shell shell, IStructuredSelection selection, Node bookmarkParent) {
265 // if (selection.isEmpty())
268 // StringBuilder builder = new StringBuilder();
269 // @SuppressWarnings("unchecked")
270 // Iterator<Object> iterator = selection.iterator();
271 // List<Node> nodes = new ArrayList<>();
273 // while (iterator.hasNext()) {
274 // Node node = (Node) iterator.next();
275 // builder.append(Jcr.get(node, Property.JCR_TITLE) + ", ");
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);
283 // if (session.hasPendingChanges())
284 // throw new DocumentsException("Cannot remove bookmarks, session is not clean");
285 // for (Node path : nodes)
287 // bookmarkParent.getSession().save();
289 // } catch (RepositoryException e) {
290 // JcrUtils.discardQuietly(session);
291 // throw new DocumentsException("Cannot delete bookmarks " + builder.toString(), e);
297 // public boolean renameBookmark(IStructuredSelection selection) {
298 // if (selection.isEmpty() || selection.size() > 1)
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);