1 package org
.argeo
.app
.ui
.library
;
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
.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
;
36 public class DocumentsUiService
{
37 private final static CmsLog log
= CmsLog
.getLog(DocumentsUiService
.class);
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";
51 public String
getLabel(String 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
:
63 case ACTION_ID_DELETE
:
65 case ACTION_ID_UPLOAD_FILE
:
66 return "Upload Files";
67 // case ACTION_ID_OPEN:
69 case ACTION_ID_DELETE_BOOKMARK
:
70 return "Delete bookmark";
71 case ACTION_ID_RENAME_BOOKMARK
:
72 return "Rename bookmark";
74 throw new IllegalArgumentException("Unknown action ID " + actionId
);
78 public void openFile(Path toOpenPath
) {
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
);
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
);
99 public boolean deleteItems(Shell shell
, IStructuredSelection selection
) {
100 if (selection
.isEmpty())
103 StringBuilder builder
= new StringBuilder();
104 @SuppressWarnings("unchecked")
105 Iterator
<Object
> iterator
= selection
.iterator();
106 List
<Path
> paths
= new ArrayList
<>();
108 while (iterator
.hasNext()) {
109 Path path
= (Path
) iterator
.next();
110 builder
.append(path
.getFileName() + ", ");
113 String msg
= "You are about to delete following elements: " + builder
.substring(0, builder
.length() - 2)
115 if (openConfirm(msg
)) {
116 for (Path path
: paths
) {
118 // recursively delete directory and its content
119 Files
.walkFileTree(path
, new SimpleFileVisitor
<Path
>() {
121 public FileVisitResult
visitFile(Path file
, BasicFileAttributes attrs
) throws IOException
{
123 return FileVisitResult
.CONTINUE
;
127 public FileVisitResult
postVisitDirectory(Path dir
, IOException exc
) throws IOException
{
129 return FileVisitResult
.CONTINUE
;
132 } catch (DirectoryNotEmptyException e
) {
133 String errMsg
= path
.getFileName() + " cannot be deleted: directory is not empty.";
135 throw new IllegalArgumentException("Cannot delete path " + path
, e
);
136 } catch (IOException e
) {
137 String errMsg
= e
.toString();
139 throw new IllegalArgumentException("Cannot delete path " + path
, e
);
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
)) {
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";
158 throw new IllegalArgumentException(errMsg
);
160 Files
.move(toRenamePath
, child
);
163 } catch (IOException e
) {
164 throw new IllegalStateException("Cannot rename " + name
+ " at " + parentFolderPath
.toString(), e
);
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
)) {
177 Path child
= currFolderPath
.resolve(name
);
178 if (Files
.exists(child
)) {
179 String errMsg
= "A folder named " + name
+ " already exists at " + currFolderPath
.toString()
182 throw new IllegalArgumentException(errMsg
);
184 Files
.createDirectories(child
);
187 } catch (IOException e
) {
188 throw new IllegalStateException("Cannot create folder " + name
+ " at " + currFolderPath
.toString(), e
);
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);
201 public boolean uploadFiles(Shell shell
, Path currFolderPath
) {
202 // shell = Display.getCurrent().getActiveShell();// ignore argument
204 FileDialog dialog
= new FileDialog(shell
, SWT
.MULTI
);
205 dialog
.setText("Choose one or more files to upload");
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
212 // 2. in RCP we must use getFilterPath that does not
214 Method filterMethod
= null;
217 filterMethod
= dialog
.getClass().getDeclaredMethod("getFilterPath");
218 String filterPath
= (String
) filterMethod
.invoke(dialog
);
219 parPath
= Paths
.get(filterPath
);
220 } catch (NoSuchMethodException nsme
) { // RAP
222 if (names
.length
== 0)
225 loop
: for (String name
: names
) {
226 Path tmpPath
= Paths
.get(name
);
228 tmpPath
= parPath
.resolve(tmpPath
);
229 if (Files
.exists(tmpPath
)) {
230 URI uri
= tmpPath
.toUri();
231 String uriStr
= uri
.toString();
233 if (Files
.isDirectory(tmpPath
)) {
235 "Upload of directories in the system is not yet implemented");
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
);
243 if (log
.isDebugEnabled())
244 log
.debug("copied uploaded file " + uriStr
+ " to " + targetPath
.toString());
246 String msg
= "Cannot copy tmp file from " + tmpPath
.toString();
248 msg
+= "\nPlease remember that file upload fails when choosing files from the \"Recently Used\" bookmarks on some OS";
256 } catch (Exception e
) {
257 CmsFeedback
.error("Cannot import files to " + currFolderPath
,e
);
262 // public boolean deleteBookmark(Shell shell, IStructuredSelection selection, Node bookmarkParent) {
263 // if (selection.isEmpty())
266 // StringBuilder builder = new StringBuilder();
267 // @SuppressWarnings("unchecked")
268 // Iterator<Object> iterator = selection.iterator();
269 // List<Node> nodes = new ArrayList<>();
271 // while (iterator.hasNext()) {
272 // Node node = (Node) iterator.next();
273 // builder.append(Jcr.get(node, Property.JCR_TITLE) + ", ");
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);
281 // if (session.hasPendingChanges())
282 // throw new DocumentsException("Cannot remove bookmarks, session is not clean");
283 // for (Node path : nodes)
285 // bookmarkParent.getSession().save();
287 // } catch (RepositoryException e) {
288 // JcrUtils.discardQuietly(session);
289 // throw new DocumentsException("Cannot delete bookmarks " + builder.toString(), e);
295 // public boolean renameBookmark(IStructuredSelection selection) {
296 // if (selection.isEmpty() || selection.size() > 1)
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);