91aff0af43bed6a42f001ec165afbadc171bd2fa
[public/netxms.git] / webui / webapp / FileManager / src / org / netxms / ui / eclipse / filemanager / views / AgentFileManager.java
1 /**
2 * NetXMS - open source network management system
3 * Copyright (C) 2003-2016 Raden Solutions
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 package org.netxms.ui.eclipse.filemanager.views;
20
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.net.URLEncoder;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.zip.ZipEntry;
29 import java.util.zip.ZipOutputStream;
30 import org.eclipse.core.runtime.IProgressMonitor;
31 import org.eclipse.jface.action.Action;
32 import org.eclipse.jface.action.GroupMarker;
33 import org.eclipse.jface.action.IMenuListener;
34 import org.eclipse.jface.action.IMenuManager;
35 import org.eclipse.jface.action.IToolBarManager;
36 import org.eclipse.jface.action.MenuManager;
37 import org.eclipse.jface.action.Separator;
38 import org.eclipse.jface.commands.ActionHandler;
39 import org.eclipse.jface.dialogs.IDialogSettings;
40 import org.eclipse.jface.util.LocalSelectionTransfer;
41 import org.eclipse.jface.viewers.CellEditor;
42 import org.eclipse.jface.viewers.ColumnViewerEditor;
43 import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
44 import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
45 import org.eclipse.jface.viewers.ICellModifier;
46 import org.eclipse.jface.viewers.ISelectionChangedListener;
47 import org.eclipse.jface.viewers.IStructuredSelection;
48 import org.eclipse.jface.viewers.SelectionChangedEvent;
49 import org.eclipse.jface.viewers.TextCellEditor;
50 import org.eclipse.jface.viewers.TreeViewerEditor;
51 import org.eclipse.jface.viewers.ViewerDropAdapter;
52 import org.eclipse.jface.window.Window;
53 import org.eclipse.rap.rwt.RWT;
54 import org.eclipse.rap.rwt.client.service.JavaScriptExecutor;
55 import org.eclipse.swt.SWT;
56 import org.eclipse.swt.dnd.DND;
57 import org.eclipse.swt.dnd.DragSourceAdapter;
58 import org.eclipse.swt.dnd.DragSourceEvent;
59 import org.eclipse.swt.dnd.Transfer;
60 import org.eclipse.swt.dnd.TransferData;
61 import org.eclipse.swt.events.DisposeEvent;
62 import org.eclipse.swt.events.DisposeListener;
63 import org.eclipse.swt.events.ModifyEvent;
64 import org.eclipse.swt.events.ModifyListener;
65 import org.eclipse.swt.layout.FormAttachment;
66 import org.eclipse.swt.layout.FormData;
67 import org.eclipse.swt.layout.FormLayout;
68 import org.eclipse.swt.widgets.Composite;
69 import org.eclipse.swt.widgets.Item;
70 import org.eclipse.swt.widgets.Menu;
71 import org.eclipse.ui.IActionBars;
72 import org.eclipse.ui.IViewSite;
73 import org.eclipse.ui.IWorkbenchActionConstants;
74 import org.eclipse.ui.IWorkbenchWindow;
75 import org.eclipse.ui.PartInitException;
76 import org.eclipse.ui.PlatformUI;
77 import org.eclipse.ui.contexts.IContextService;
78 import org.eclipse.ui.handlers.IHandlerService;
79 import org.eclipse.ui.part.ViewPart;
80 import org.netxms.client.AgentFileData;
81 import org.netxms.client.NXCException;
82 import org.netxms.client.NXCSession;
83 import org.netxms.client.ProgressListener;
84 import org.netxms.client.objects.Node;
85 import org.netxms.client.server.AgentFile;
86 import org.netxms.ui.eclipse.actions.RefreshAction;
87 import org.netxms.ui.eclipse.console.DownloadServiceHandler;
88 import org.netxms.ui.eclipse.console.resources.SharedIcons;
89 import org.netxms.ui.eclipse.filemanager.Activator;
90 import org.netxms.ui.eclipse.filemanager.Messages;
91 import org.netxms.ui.eclipse.filemanager.dialogs.CreateFolderDialog;
92 import org.netxms.ui.eclipse.filemanager.dialogs.StartClientToServerFileUploadDialog;
93 import org.netxms.ui.eclipse.filemanager.views.helpers.AgentFileComparator;
94 import org.netxms.ui.eclipse.filemanager.views.helpers.AgentFileFilter;
95 import org.netxms.ui.eclipse.filemanager.views.helpers.AgentFileLabelProvider;
96 import org.netxms.ui.eclipse.filemanager.views.helpers.ViewAgentFilesProvider;
97 import org.netxms.ui.eclipse.jobs.ConsoleJob;
98 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
99 import org.netxms.ui.eclipse.tools.MessageDialogHelper;
100 import org.netxms.ui.eclipse.tools.WidgetHelper;
101 import org.netxms.ui.eclipse.widgets.FilterText;
102 import org.netxms.ui.eclipse.widgets.SortableTableViewer;
103 import org.netxms.ui.eclipse.widgets.SortableTreeViewer;
104
105 /**
106 * File manager for agent files
107 */
108 public class AgentFileManager extends ViewPart
109 {
110 public static final String ID = "org.netxms.ui.eclipse.filemanager.views.AgentFileManager"; //$NON-NLS-1$
111
112 private static final String TABLE_CONFIG_PREFIX = "AgentFileManager"; //$NON-NLS-1$
113
114 // Columns
115 public static final int COLUMN_NAME = 0;
116 public static final int COLUMN_TYPE = 1;
117 public static final int COLUMN_SIZE = 2;
118 public static final int COLUMN_MODIFYED = 3;
119 public static final int COLUMN_OWNER = 4;
120 public static final int COLUMN_GROUP = 5;
121 public static final int COLUMN_ACCESS_RIGHTS = 6;
122
123 private boolean initShowFilter = true;
124 private Composite content;
125 private AgentFileFilter filter;
126 private FilterText filterText;
127 private SortableTreeViewer viewer;
128 private NXCSession session;
129 private Action actionRefreshAll;
130 private Action actionUploadFile;
131 private Action actionDelete;
132 private Action actionRename;
133 private Action actionRefreshDirectory;
134 private Action actionShowFilter;
135 private Action actionDownloadFile;
136 private Action actionTailFile;
137 private Action actionShowFile;
138 private Action actionCreateDirectory;
139 private Action actionCalculateFolderSize;
140 private Action actionCopyFilePath;
141 private Action actionCopyFileName;
142 private long objectId = 0;
143
144 /*
145 * (non-Javadoc)
146 *
147 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
148 */
149 @Override
150 public void init(IViewSite site) throws PartInitException
151 {
152 super.init(site);
153
154 session = (NXCSession)ConsoleSharedData.getSession();
155 IDialogSettings settings = Activator.getDefault().getDialogSettings();
156 initShowFilter = safeCast(settings.get("AgentFileManager.showFilter"), settings.getBoolean("AgentFileManager.showFilter"), initShowFilter);
157 objectId = Long.parseLong(site.getSecondaryId());
158 setPartName(String.format(Messages.get().AgentFileManager_PartTitle, session.getObjectName(objectId)));
159 }
160
161 /**
162 * @param b
163 * @param defval
164 * @return
165 */
166 private static boolean safeCast(String s, boolean b, boolean defval)
167 {
168 return (s != null) ? b : defval;
169 }
170
171 /*
172 * (non-Javadoc)
173 *
174 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
175 */
176 @Override
177 public void createPartControl(Composite parent)
178 {
179 content = new Composite(parent, SWT.NONE);
180 content.setLayout(new FormLayout());
181
182 // Create filter area
183 filterText = new FilterText(content, SWT.NONE);
184 filterText.addModifyListener(new ModifyListener() {
185 @Override
186 public void modifyText(ModifyEvent e)
187 {
188 onFilterModify();
189 }
190 });
191
192 String os = ((Node)session.findObjectById(objectId)).getSystemDescription(); //$NON-NLS-1$
193
194 if (os.contains("Windows")) //if OS is windows don't show group and access rights columns //$NON-NLS-1$
195 {
196 final String[] columnNames = { Messages.get().AgentFileManager_ColName, Messages.get().AgentFileManager_ColType, Messages.get().AgentFileManager_ColSize, Messages.get().AgentFileManager_ColDate, Messages.get().AgentFileManager_ColOwner };
197 final int[] columnWidths = { 300, 120, 150, 150, 150 };
198 viewer = new SortableTreeViewer(content, columnNames, columnWidths, 0, SWT.UP, SortableTableViewer.DEFAULT_STYLE);
199 }
200 else
201 {
202 final String[] columnNames = { Messages.get().AgentFileManager_ColName, Messages.get().AgentFileManager_ColType, Messages.get().AgentFileManager_ColSize, Messages.get().AgentFileManager_ColDate, Messages.get().AgentFileManager_ColOwner, Messages.get().AgentFileManager_ColGroup, Messages.get().AgentFileManager_ColAccessRights };
203 final int[] columnWidths = { 300, 120, 150, 150, 150, 150, 200 };
204 viewer = new SortableTreeViewer(content, columnNames, columnWidths, 0, SWT.UP, SortableTableViewer.DEFAULT_STYLE);
205 }
206
207 WidgetHelper.restoreTreeViewerSettings(viewer, Activator.getDefault().getDialogSettings(), TABLE_CONFIG_PREFIX);
208 viewer.setContentProvider(new ViewAgentFilesProvider());
209 viewer.setLabelProvider(new AgentFileLabelProvider());
210 viewer.setComparator(new AgentFileComparator());
211 filter = new AgentFileFilter();
212 viewer.addFilter(filter);
213 viewer.addSelectionChangedListener(new ISelectionChangedListener() {
214 @Override
215 public void selectionChanged(SelectionChangedEvent event)
216 {
217 IStructuredSelection selection = (IStructuredSelection)event.getSelection();
218 if (selection != null)
219 {
220 actionDelete.setEnabled(selection.size() > 0);
221 actionCalculateFolderSize.setEnabled(selection.size() > 0);
222 }
223 }
224 });
225 viewer.getTree().addDisposeListener(new DisposeListener() {
226 @Override
227 public void widgetDisposed(DisposeEvent e)
228 {
229 WidgetHelper.saveTreeViewerSettings(viewer, Activator.getDefault().getDialogSettings(), TABLE_CONFIG_PREFIX);
230 }
231 });
232 enableDragSupport();
233 enableDropSupport();
234 enableInPlaceRename();
235
236 // Setup layout
237 FormData fd = new FormData();
238 fd.left = new FormAttachment(0, 0);
239 fd.top = new FormAttachment(filterText);
240 fd.right = new FormAttachment(100, 0);
241 fd.bottom = new FormAttachment(100, 0);
242 viewer.getTree().setLayoutData(fd);
243
244 fd = new FormData();
245 fd.left = new FormAttachment(0, 0);
246 fd.top = new FormAttachment(0, 0);
247 fd.right = new FormAttachment(100, 0);
248 filterText.setLayoutData(fd);
249
250 createActions();
251 contributeToActionBars();
252 createPopupMenu();
253 activateContext();
254
255 filterText.setCloseAction(actionShowFilter);
256
257 // Set initial focus to filter input line
258 if (initShowFilter)
259 filterText.setFocus();
260 else
261 enableFilter(false); // Will hide filter area correctly
262
263 refreshFileList();
264 }
265
266 /* (non-Javadoc)
267 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
268 */
269 @Override
270 public void dispose()
271 {
272 IDialogSettings settings = Activator.getDefault().getDialogSettings();
273 settings.put("AgentFileManager.showFilter", initShowFilter);
274 super.dispose();
275 }
276
277 /**
278 * Activate context
279 */
280 private void activateContext()
281 {
282 IContextService contextService = (IContextService)getSite().getService(IContextService.class);
283 if (contextService != null)
284 {
285 contextService.activateContext("org.netxms.ui.eclipse.filemanager.context.FileManager"); //$NON-NLS-1$
286 }
287 }
288
289 /**
290 * Enable drag support in object tree
291 */
292 public void enableDragSupport()
293 {
294 Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };
295 viewer.addDragSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, new DragSourceAdapter() {
296 @Override
297 public void dragStart(DragSourceEvent event)
298 {
299 LocalSelectionTransfer.getTransfer().setSelection(viewer.getSelection());
300 event.doit = true;
301 }
302
303 @Override
304 public void dragSetData(DragSourceEvent event)
305 {
306 event.data = LocalSelectionTransfer.getTransfer().getSelection();
307 }
308 });
309 }
310
311 /**
312 * Enable drop support in object tree
313 */
314 public void enableDropSupport()// SubtreeType infrastructure
315 {
316 final Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };
317 viewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, new ViewerDropAdapter(viewer) {
318
319 @Override
320 public boolean performDrop(Object data)
321 {
322 IStructuredSelection selection = (IStructuredSelection)data;
323 List<?> movableSelection = selection.toList();
324 for(int i = 0; i < movableSelection.size(); i++)
325 {
326 AgentFile movableObject = (AgentFile)movableSelection.get(i);
327
328 moveFile((AgentFile)getCurrentTarget(), movableObject);
329
330 }
331 return true;
332 }
333
334 @Override
335 public boolean validateDrop(Object target, int operation, TransferData transferType)
336 {
337 if ((target == null) || !LocalSelectionTransfer.getTransfer().isSupportedType(transferType))
338 return false;
339
340 IStructuredSelection selection = (IStructuredSelection)LocalSelectionTransfer.getTransfer().getSelection();
341 if (selection.isEmpty())
342 return false;
343
344 for(final Object object : selection.toList())
345 {
346 if (!(object instanceof AgentFile))
347 return false;
348 }
349 if (!(target instanceof AgentFile))
350 {
351 return false;
352 }
353 else
354 {
355 if (!((AgentFile)target).isDirectory())
356 {
357 return false;
358 }
359 }
360 return true;
361 }
362 });
363 }
364
365 /**
366 * Enable in-place renames
367 */
368 private void enableInPlaceRename()
369 {
370 TreeViewerEditor.create(viewer, new ColumnViewerEditorActivationStrategy(viewer) {
371 @Override
372 protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event)
373 {
374 return event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
375 }
376 }, ColumnViewerEditor.DEFAULT);
377 viewer.setCellEditors(new CellEditor[] { new TextCellEditor(viewer.getTree()) });
378 viewer.setColumnProperties(new String[] { "name" }); //$NON-NLS-1$
379 viewer.setCellModifier(new ICellModifier() {
380 @Override
381 public void modify(Object element, String property, Object value)
382 {
383 if (element instanceof Item)
384 element = ((Item)element).getData();
385
386 if (property.equals("name")) //$NON-NLS-1$
387 {
388 if (element instanceof AgentFile)
389 {
390 doRename((AgentFile)element, value.toString());
391 }
392 }
393 }
394
395 @Override
396 public Object getValue(Object element, String property)
397 {
398 if (property.equals("name")) //$NON-NLS-1$
399 {
400 if (element instanceof AgentFile)
401 {
402 return ((AgentFile)element).getName();
403 }
404 }
405 return null;
406 }
407
408 @Override
409 public boolean canModify(Object element, String property)
410 {
411 return property.equals("name"); //$NON-NLS-1$
412 }
413 });
414 }
415
416 /**
417 * Do actual rename
418 *
419 * @param AgentFile
420 * @param newName
421 */
422 private void doRename(final AgentFile agentFile, final String newName)
423 {
424 new ConsoleJob(Messages.get().ViewServerFile_DeletFileFromServerJob, this, Activator.PLUGIN_ID, Activator.PLUGIN_ID) {
425 @Override
426 protected String getErrorMessage()
427 {
428 return Messages.get().AgentFileManager_RenameError;
429 }
430
431 @Override
432 protected void runInternal(IProgressMonitor monitor) throws Exception
433 {
434 session.renameAgentFile(objectId, agentFile.getFullName(), agentFile.getParent().getFullName() + "/" + newName); //$NON-NLS-1$
435
436 runInUIThread(new Runnable() {
437 @Override
438 public void run()
439 {
440 agentFile.setName(newName);
441 viewer.refresh(agentFile, true);
442 }
443 });
444 }
445 }.start();
446 }
447
448 /**
449 * Create actions
450 */
451 private void createActions()
452 {
453 final IHandlerService handlerService = (IHandlerService)getSite().getService(IHandlerService.class);
454
455 actionRefreshDirectory = new Action(Messages.get().AgentFileManager_RefreshFolder, SharedIcons.REFRESH) {
456 @Override
457 public void run()
458 {
459 refreshFileOrDirectory();
460 }
461 };
462 actionRefreshDirectory.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.refreshFolder"); //$NON-NLS-1$
463 handlerService.activateHandler(actionRefreshDirectory.getActionDefinitionId(), new ActionHandler(actionRefreshDirectory));
464
465 actionRefreshAll = new RefreshAction(this) {
466 @Override
467 public void run()
468 {
469 refreshFileList();
470 }
471 };
472
473 actionUploadFile = new Action(Messages.get().AgentFileManager_UploadFile) {
474 @Override
475 public void run()
476 {
477 uploadFile();
478 }
479 };
480 actionUploadFile.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.uploadFile"); //$NON-NLS-1$
481 handlerService.activateHandler(actionUploadFile.getActionDefinitionId(), new ActionHandler(actionUploadFile));
482
483 actionDelete = new Action(Messages.get().AgentFileManager_Delete, SharedIcons.DELETE_OBJECT) {
484 @Override
485 public void run()
486 {
487 deleteFile();
488 }
489 };
490 actionDelete.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.delete"); //$NON-NLS-1$
491 handlerService.activateHandler(actionDelete.getActionDefinitionId(), new ActionHandler(actionDelete));
492
493 actionRename = new Action(Messages.get().AgentFileManager_Rename) {
494 @Override
495 public void run()
496 {
497 renameFile();
498 }
499 };
500 actionRename.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.rename"); //$NON-NLS-1$
501 handlerService.activateHandler(actionRename.getActionDefinitionId(), new ActionHandler(actionRename));
502
503 actionShowFilter = new Action(Messages.get().ViewServerFile_ShowFilterAction, Action.AS_CHECK_BOX) {
504 @Override
505 public void run()
506 {
507 enableFilter(!initShowFilter);
508 actionShowFilter.setChecked(initShowFilter);
509 }
510 };
511 actionShowFilter.setChecked(initShowFilter);
512 actionShowFilter.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.showFilter"); //$NON-NLS-1$
513 handlerService.activateHandler(actionShowFilter.getActionDefinitionId(), new ActionHandler(actionShowFilter));
514
515 actionDownloadFile = new Action(Messages.get().AgentFileManager_Download) {
516 @Override
517 public void run()
518 {
519 startDownload();
520 }
521 };
522 actionDownloadFile.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.download"); //$NON-NLS-1$
523 handlerService.activateHandler(actionDownloadFile.getActionDefinitionId(), new ActionHandler(actionDownloadFile));
524
525 actionTailFile = new Action(Messages.get().AgentFileManager_FollowChanges) {
526 @Override
527 public void run()
528 {
529 tailFile(true, 1024);
530 }
531 };
532
533 actionShowFile = new Action(Messages.get().AgentFileManager_Show) {
534 @Override
535 public void run()
536 {
537 tailFile(false, 0);
538 }
539 };
540
541 actionCreateDirectory = new Action(Messages.get().AgentFileManager_CreateFolder) {
542 @Override
543 public void run()
544 {
545 createFolder();
546 }
547 };
548 actionCreateDirectory.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.newFolder"); //$NON-NLS-1$
549 handlerService.activateHandler(actionCreateDirectory.getActionDefinitionId(), new ActionHandler(actionCreateDirectory));
550
551 actionCalculateFolderSize = new Action("Calculate folder &size") {
552 @Override
553 public void run()
554 {
555 calculateFolderSize();
556 }
557 };
558 actionCalculateFolderSize.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.calculateFolderSize"); //$NON-NLS-1$
559 handlerService.activateHandler(actionCalculateFolderSize.getActionDefinitionId(), new ActionHandler(actionCalculateFolderSize));
560
561 actionCopyFileName = new Action("Copy file &name") {
562 @Override
563 public void run()
564 {
565 copyFileName();
566 }
567 };
568 actionCopyFileName.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.copyFileName"); //$NON-NLS-1$
569 handlerService.activateHandler(actionCopyFileName.getActionDefinitionId(), new ActionHandler(actionCopyFileName));
570
571 actionCopyFilePath = new Action("Copy file &path") {
572 @Override
573 public void run()
574 {
575 copyFilePath();
576 }
577 };
578 actionCopyFilePath.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.copyFilePath"); //$NON-NLS-1$
579 handlerService.activateHandler(actionCopyFilePath.getActionDefinitionId(), new ActionHandler(actionCopyFilePath));
580 }
581
582 /**
583 * Contribute actions to action bar
584 */
585 private void contributeToActionBars()
586 {
587 IActionBars bars = getViewSite().getActionBars();
588 fillLocalPullDown(bars.getMenuManager());
589 fillLocalToolBar(bars.getToolBarManager());
590 }
591
592 /**
593 * Fill local pull-down menu
594 *
595 * @param manager Menu manager for pull-down menu
596 */
597 private void fillLocalPullDown(IMenuManager manager)
598 {
599 manager.add(actionShowFilter);
600 manager.add(new Separator());
601 manager.add(actionRefreshAll);
602 }
603
604 /**
605 * Fill local tool bar
606 *
607 * @param manager Menu manager for local tool bar
608 */
609 private void fillLocalToolBar(IToolBarManager manager)
610 {
611 manager.add(actionRefreshAll);
612 }
613
614 /**
615 * Create pop-up menu for user list
616 */
617 private void createPopupMenu()
618 {
619 // Create menu manager
620 MenuManager menuMgr = new MenuManager();
621 menuMgr.setRemoveAllWhenShown(true);
622 menuMgr.addMenuListener(new IMenuListener() {
623 public void menuAboutToShow(IMenuManager mgr)
624 {
625 fillContextMenu(mgr);
626 }
627 });
628
629 // Create menu
630 Menu menu = menuMgr.createContextMenu(viewer.getControl());
631 viewer.getControl().setMenu(menu);
632
633 // Register menu for extension.
634 getSite().registerContextMenu(menuMgr, viewer);
635 }
636
637 /**
638 * Fill context menu
639 *
640 * @param mgr Menu manager
641 */
642 protected void fillContextMenu(final IMenuManager mgr)
643 {
644 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
645 if (selection.isEmpty())
646 return;
647
648 if (selection.size() == 1)
649 {
650 if (((AgentFile)selection.getFirstElement()).isDirectory())
651 {
652 mgr.add(actionUploadFile);
653 }
654 else
655 {
656 mgr.add(actionTailFile);
657 mgr.add(actionShowFile);
658 }
659 }
660
661 mgr.add(actionDownloadFile);
662
663 if (isFolderOnlySelection(selection))
664 mgr.add(actionCalculateFolderSize);
665 mgr.add(new Separator());
666
667 if (selection.size() == 1)
668 {
669 if (((AgentFile)selection.getFirstElement()).isDirectory())
670 {
671 mgr.add(actionCreateDirectory);
672 }
673 mgr.add(actionRename);
674 }
675 mgr.add(actionDelete);
676 mgr.add(new Separator());
677 if (selection.size() == 1)
678 {
679 mgr.add(actionCopyFileName);
680 mgr.add(actionCopyFilePath);
681 }
682 mgr.add(new Separator());
683 mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
684 if ((selection.size() == 1) && ((AgentFile)selection.getFirstElement()).isDirectory())
685 {
686 mgr.add(new Separator());
687 mgr.add(actionRefreshDirectory);
688 }
689 }
690
691 /**
692 * Check if given selection contains only folders
693 *
694 * @param selection
695 * @return
696 */
697 private boolean isFolderOnlySelection(IStructuredSelection selection)
698 {
699 for(Object o : selection.toList())
700 if (!((AgentFile)o).isDirectory())
701 return false;
702 return true;
703 }
704
705 /**
706 * Refresh file list
707 */
708 private void refreshFileList()
709 {
710 new ConsoleJob(Messages.get().SelectServerFileDialog_JobTitle, null, Activator.PLUGIN_ID, null) {
711 @Override
712 protected void runInternal(IProgressMonitor monitor) throws Exception
713 {
714 final List<AgentFile> files = session.listAgentFiles(null, "/", objectId); //$NON-NLS-1$
715 runInUIThread(new Runnable() {
716 @Override
717 public void run()
718 {
719 viewer.setInput(files);
720 }
721 });
722 }
723
724 @Override
725 protected String getErrorMessage()
726 {
727 return Messages.get().SelectServerFileDialog_JobError;
728 }
729 }.start();
730 }
731
732 /**
733 * Refresh file list
734 */
735 private void refreshFileOrDirectory()
736 {
737 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
738 if (selection.isEmpty())
739 return;
740
741 final Object[] objects = selection.toArray();
742
743 new ConsoleJob(Messages.get().SelectServerFileDialog_JobTitle, null, Activator.PLUGIN_ID, null) {
744 @Override
745 protected void runInternal(IProgressMonitor monitor) throws Exception
746 {
747 for(int i = 0; i < objects.length; i++)
748 {
749 if (!((AgentFile)objects[i]).isDirectory())
750 objects[i] = ((AgentFile)objects[i]).getParent();
751
752 final AgentFile sf = ((AgentFile)objects[i]);
753 sf.setChildren(session.listAgentFiles(sf, sf.getFullName(), objectId));
754
755 runInUIThread(new Runnable() {
756 @Override
757 public void run()
758 {
759 viewer.refresh(sf);
760 }
761 });
762 }
763 }
764
765 @Override
766 protected String getErrorMessage()
767 {
768 return Messages.get().SelectServerFileDialog_JobError;
769 }
770 }.start();
771 }
772
773 /**
774 * Upload local file to agent
775 */
776 private void uploadFile()
777 {
778 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
779 if (selection.isEmpty())
780 return;
781
782 final Object[] objects = selection.toArray();
783 final AgentFile upladFolder = ((AgentFile)objects[0]).isDirectory() ? ((AgentFile)objects[0]) : ((AgentFile)objects[0])
784 .getParent();
785
786 final StartClientToServerFileUploadDialog dlg = new StartClientToServerFileUploadDialog(getSite().getShell());
787 if (dlg.open() == Window.OK)
788 {
789 final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
790 new ConsoleJob(Messages.get().AgentFileManager_UploadFileJobTitle, null, Activator.PLUGIN_ID, null) {
791 @Override
792 protected void runInternal(final IProgressMonitor monitor) throws Exception
793 {
794 List<File> fileList = dlg.getLocalFiles();
795 for(int i = 0; i < fileList.size(); i++)
796 {
797 final File localFile = fileList.get(i);
798 String remoteFile = fileList.get(i).getName();
799 if(fileList.size() == 1)
800 remoteFile = dlg.getRemoteFileName();
801
802 session.uploadLocalFileToAgent(objectId, localFile, upladFolder.getFullName()+"/"+remoteFile, new ProgressListener() { //$NON-NLS-1$
803 private long prevWorkDone = 0;
804
805 @Override
806 public void setTotalWorkAmount(long workTotal)
807 {
808 monitor.beginTask(Messages.get(getDisplay()).UploadFileToServer_TaskNamePrefix
809 + localFile.getAbsolutePath(),
810 (int)workTotal);
811 }
812
813 @Override
814 public void markProgress(long workDone)
815 {
816 monitor.worked((int)(workDone - prevWorkDone));
817 prevWorkDone = workDone;
818 }
819 });
820 monitor.done();
821 }
822
823 upladFolder.setChildren(session.listAgentFiles(upladFolder, upladFolder.getFullName(), objectId));
824 runInUIThread(new Runnable() {
825 @Override
826 public void run()
827 {
828
829 viewer.refresh(upladFolder, true);
830 }
831 });
832 }
833
834 @Override
835 protected String getErrorMessage()
836 {
837 return Messages.get().UploadFileToServer_JobError;
838 }
839 }.start();
840 }
841 }
842
843 /**
844 * Upload local folder to agent
845 */
846 /*
847 private void uploadFolder()
848 {
849 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
850 if (selection.isEmpty())
851 return;
852
853 final Object[] objects = selection.toArray();
854 final AgentFile upladFolder = ((AgentFile)objects[0]).isDirectory() ? ((AgentFile)objects[0]) : ((AgentFile)objects[0])
855 .getParent();
856
857 final StartClientToAgentFolderUploadDialog dlg = new StartClientToAgentFolderUploadDialog(getSite().getShell());
858 if (dlg.open() == Window.OK)
859 {
860 final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
861 new ConsoleJob(Messages.get().AgentFileManager_UploadFolderJobTitle, null, Activator.PLUGIN_ID, null) {
862 @Override
863 protected void runInternal(final IProgressMonitor monitor) throws Exception
864 {
865 File folder = dlg.getLocalFile();
866 session.createFolderOnAgent(objectId, upladFolder.getFullName()+"/"+dlg.getRemoteFileName()); //$NON-NLS-1$
867 uploadFilesInFolder(folder, upladFolder.getFullName()+"/"+dlg.getRemoteFileName(), monitor); //$NON-NLS-1$
868
869 upladFolder.setChildren(session.listAgentFiles(upladFolder, upladFolder.getFullName(), objectId));
870 runInUIThread(new Runnable() {
871 @Override
872 public void run()
873 {
874 viewer.refresh(upladFolder, true);
875 }
876 });
877 }
878
879 @Override
880 protected String getErrorMessage()
881 {
882 return Messages.get().UploadFileToServer_JobError;
883 }
884 }.start();
885 }
886 }
887 */
888
889 /**
890 * Recursively uploads files to agent and creates correct folders
891 *
892 * @param folder
893 * @param upladFolder
894 * @param monitor
895 * @throws NXCException
896 * @throws IOException
897 */
898 public void uploadFilesInFolder(final File folder, final String uploadFolder, final IProgressMonitor monitor) throws NXCException, IOException
899 {
900 for(final File fileEntry : folder.listFiles())
901 {
902 if (fileEntry.isDirectory())
903 {
904 session.createFolderOnAgent(objectId, uploadFolder + "/" + fileEntry.getName()); //$NON-NLS-1$
905 uploadFilesInFolder(fileEntry, uploadFolder + "/" + fileEntry.getName(), monitor); //$NON-NLS-1$
906 }
907 else
908 {
909 session.uploadLocalFileToAgent(objectId, fileEntry, uploadFolder + "/" + fileEntry.getName(), new ProgressListener() { //$NON-NLS-1$
910 private long prevWorkDone = 0;
911
912 @Override
913 public void setTotalWorkAmount(long workTotal)
914 {
915 monitor.beginTask(Messages.get().UploadFileToServer_TaskNamePrefix + fileEntry.getAbsolutePath(),
916 (int)workTotal);
917 }
918
919 @Override
920 public void markProgress(long workDone)
921 {
922 monitor.worked((int)(workDone - prevWorkDone));
923 prevWorkDone = workDone;
924 }
925 });
926 monitor.done();
927 }
928 }
929 }
930
931 /**
932 * Delete selected file
933 */
934 private void deleteFile()
935 {
936 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
937 if (selection.isEmpty())
938 return;
939
940 if (!MessageDialogHelper.openConfirm(getSite().getShell(), Messages.get().ViewServerFile_DeleteConfirmation,
941 Messages.get().ViewServerFile_DeletAck))
942 return;
943
944 final Object[] objects = selection.toArray();
945 new ConsoleJob(Messages.get().ViewServerFile_DeletFileFromServerJob, this, Activator.PLUGIN_ID, Activator.PLUGIN_ID) {
946 @Override
947 protected String getErrorMessage()
948 {
949 return Messages.get().ViewServerFile_ErrorDeleteFileJob;
950 }
951
952 @Override
953 protected void runInternal(IProgressMonitor monitor) throws Exception
954 {
955 for(int i = 0; i < objects.length; i++)
956 {
957 final AgentFile sf = (AgentFile)objects[i];
958 session.deleteAgentFile(objectId, sf.getFullName());
959
960 runInUIThread(new Runnable() {
961 @Override
962 public void run()
963 {
964 sf.getParent().removeChield(sf);
965 viewer.refresh(sf.getParent());
966 }
967 });
968 }
969 }
970 }.start();
971 }
972
973 /**
974 * Starts file tail
975 */
976 private void tailFile(final boolean followChanges, final int offset)
977 {
978 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
979 if (selection.isEmpty())
980 return;
981
982 final Object[] objects = selection.toArray();
983
984 if (((AgentFile)objects[0]).isDirectory())
985 return;
986
987 final AgentFile sf = ((AgentFile)objects[0]);
988
989 ConsoleJob job = new ConsoleJob(Messages.get().AgentFileManager_DownloadJobTitle, null, Activator.PLUGIN_ID, null) {
990 @Override
991 protected String getErrorMessage()
992 {
993 return String.format(Messages.get().AgentFileManager_DownloadJobError, sf.getFullName(), objectId);
994 }
995
996 @Override
997 protected void runInternal(final IProgressMonitor monitor) throws Exception
998 {
999 final AgentFileData file = session.downloadFileFromAgent(objectId, sf.getFullName(), offset, followChanges, new ProgressListener() {
1000 @Override
1001 public void setTotalWorkAmount(long workTotal)
1002 {
1003 monitor.beginTask("Download file " + sf.getFullName(), (int)workTotal);
1004 }
1005
1006 @Override
1007 public void markProgress(long workDone)
1008 {
1009 monitor.worked((int)workDone);
1010 }
1011 });
1012 runInUIThread(new Runnable() {
1013 @Override
1014 public void run()
1015 {
1016 try
1017 {
1018 String secondaryId = Long.toString(objectId) + "&" + URLEncoder.encode(sf.getName(), "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
1019 AgentFileViewer.createView(secondaryId, objectId, file, followChanges);
1020 }
1021 catch(Exception e)
1022 {
1023 final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
1024 MessageDialogHelper.openError(window.getShell(), Messages.get().AgentFileManager_Error,
1025 String.format(Messages.get().AgentFileManager_OpenViewError, e.getLocalizedMessage()));
1026 Activator.logError("Exception in AgentFileManager.tailFile", e);
1027 }
1028 }
1029 });
1030 }
1031 };
1032 job.start();
1033 }
1034
1035 /**
1036 * Download file from agent
1037 */
1038 private void startDownload()
1039 {
1040 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
1041 if (selection.size() != 1)
1042 return;
1043
1044 final AgentFile sf = (AgentFile)selection.getFirstElement();
1045 if (!sf.isDirectory())
1046 {
1047 downloadFile(sf.getFullName());
1048 }
1049 else
1050 {
1051 ConsoleJob job = new ConsoleJob("Download from agent", null, Activator.PLUGIN_ID, null) {
1052 @Override
1053 protected void runInternal(final IProgressMonitor monitor) throws Exception
1054 {
1055 //create zip from download folder wile download
1056 long dirSize = -1;
1057 try
1058 {
1059 dirSize = session.getAgentFileInfo(sf).getSize();
1060 }
1061 catch(Exception e)
1062 {
1063 }
1064 monitor.beginTask(String.format("Downloading directory %s", sf.getName()), (int)dirSize);
1065
1066 final File zipFile = File.createTempFile("download_", ".zip");
1067 FileOutputStream fos = new FileOutputStream(zipFile);
1068 ZipOutputStream zos = new ZipOutputStream(fos);
1069 downloadDir(sf, sf.getName(), zos, monitor);
1070 zos.close();
1071 fos.close();
1072
1073 DownloadServiceHandler.addDownload(zipFile.getName(), sf.getName() + ".zip", zipFile, "application/octet-stream");
1074 runInUIThread(new Runnable() {
1075 @Override
1076 public void run()
1077 {
1078 DownloadServiceHandler.startDownload(zipFile.getName());
1079 }
1080 });
1081
1082 monitor.done();
1083 }
1084
1085 @Override
1086 protected String getErrorMessage()
1087 {
1088 return Messages.get().AgentFileManager_DirectoryReadError;
1089 }
1090 };
1091 job.start();
1092 }
1093 }
1094
1095 /**
1096 * Recursively download directory from agent to local pc
1097 *
1098 * @param sf
1099 * @param localFileName
1100 * @throws IOException
1101 * @throws NXCException
1102 */
1103 private void downloadDir(final AgentFile sf, String localFileName, ZipOutputStream zos, final IProgressMonitor monitor) throws NXCException, IOException
1104 {
1105 List<AgentFile> files = sf.getChildren();
1106 if (files == null)
1107 {
1108 files = session.listAgentFiles(sf, sf.getFullName(), sf.getNodeId());
1109 sf.setChildren(files);
1110 }
1111 for(AgentFile f : files)
1112 {
1113 if (f.isDirectory())
1114 {
1115 downloadDir(f, localFileName + "/" + f.getName(), zos, monitor);
1116 }
1117 else
1118 {
1119 monitor.subTask(String.format("Compressing file %s", f.getFullName()));
1120 final AgentFileData file = session.downloadFileFromAgent(objectId, f.getFullName(), 0, false, new ProgressListener() {
1121 @Override
1122 public void setTotalWorkAmount(long workTotal)
1123 {
1124 }
1125 @Override
1126 public void markProgress(long workDone)
1127 {
1128 monitor.worked((int)workDone);
1129 }
1130 });
1131
1132 FileInputStream fis = new FileInputStream(file.getFile());
1133 ZipEntry zipEntry = new ZipEntry(localFileName + "/" + f.getName());
1134 zos.putNextEntry(zipEntry);
1135 byte[] bytes = new byte[1024];
1136 int length;
1137 while ((length = fis.read(bytes)) >= 0)
1138 {
1139 zos.write(bytes, 0, length);
1140 }
1141 zos.closeEntry();
1142 fis.close();
1143 }
1144 }
1145 }
1146
1147 /**
1148 * Downloads file
1149 * @throws NXCException
1150 * @throws IOException
1151 */
1152 private void downloadFile(final String remoteName)
1153 {
1154 ConsoleJob job = new ConsoleJob(Messages.get().SelectServerFileDialog_JobTitle, null, Activator.PLUGIN_ID, null) {
1155 @Override
1156 protected void runInternal(final IProgressMonitor monitor) throws Exception
1157 {
1158 final AgentFileData file = session.downloadFileFromAgent(objectId, remoteName, 0, false, new ProgressListener() {
1159 @Override
1160 public void setTotalWorkAmount(long workTotal)
1161 {
1162 monitor.beginTask("Downloading file " + remoteName, (int)workTotal);
1163 }
1164
1165 @Override
1166 public void markProgress(long workDone)
1167 {
1168 monitor.worked((int)workDone);
1169 }
1170 });
1171
1172 DownloadServiceHandler.addDownload(file.getFile().getName(), remoteName, file.getFile(), "application/octet-stream");
1173 runInUIThread(new Runnable() {
1174 @Override
1175 public void run()
1176 {
1177 DownloadServiceHandler.startDownload(file.getFile().getName());
1178 }
1179 });
1180 }
1181
1182 @Override
1183 protected String getErrorMessage()
1184 {
1185 return Messages.get().AgentFileManager_DirectoryReadError;
1186 }
1187 };
1188 job.setUser(false);
1189 job.start();
1190 }
1191
1192 /**
1193 * Rename selected file
1194 */
1195 private void renameFile()
1196 {
1197 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
1198 if (selection.size() != 1)
1199 return;
1200
1201 viewer.editElement(selection.getFirstElement(), 0);
1202 }
1203
1204 /**
1205 * Move selected file
1206 */
1207 private void moveFile(final AgentFile target, final AgentFile object)
1208 {
1209 new ConsoleJob(Messages.get().AgentFileManager_MoveFile, this, Activator.PLUGIN_ID, Activator.PLUGIN_ID) {
1210 @Override
1211 protected String getErrorMessage()
1212 {
1213 return Messages.get().AgentFileManager_MoveError;
1214 }
1215
1216 @Override
1217 protected void runInternal(IProgressMonitor monitor) throws Exception
1218 {
1219 session.renameAgentFile(objectId, object.getFullName(), target.getFullName() + "/" + object.getName()); //$NON-NLS-1$
1220
1221 runInUIThread(new Runnable() {
1222 @Override
1223 public void run()
1224 {
1225 object.getParent().removeChield(object);
1226 viewer.refresh(object.getParent(), true);
1227 object.setParent(target);
1228 target.addChield(object);
1229 viewer.refresh(object.getParent(), true);
1230 }
1231 });
1232 }
1233 }.start();
1234 }
1235
1236 /**
1237 * Create new folder
1238 */
1239 private void createFolder()
1240 {
1241 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
1242 if (selection.isEmpty())
1243 return;
1244
1245 final Object[] objects = selection.toArray();
1246 final AgentFile parentFolder = ((AgentFile)objects[0]).isDirectory() ? ((AgentFile)objects[0]) : ((AgentFile)objects[0])
1247 .getParent();
1248
1249 final CreateFolderDialog dlg = new CreateFolderDialog(getSite().getShell());
1250 if (dlg.open() != Window.OK)
1251 return;
1252
1253 final String newFolder = dlg.getNewName();
1254
1255 new ConsoleJob(Messages.get().AgentFileManager_CreatingFolder, this, Activator.PLUGIN_ID, Activator.PLUGIN_ID) {
1256 @Override
1257 protected String getErrorMessage()
1258 {
1259 return Messages.get().AgentFileManager_FolderCreationError;
1260 }
1261
1262 @Override
1263 protected void runInternal(IProgressMonitor monitor) throws Exception
1264 {
1265 session.createFolderOnAgent(objectId, parentFolder.getFullName() + "/" + newFolder); //$NON-NLS-1$
1266 parentFolder.setChildren(session.listAgentFiles(parentFolder, parentFolder.getFullName(), objectId));
1267
1268 runInUIThread(new Runnable() {
1269 @Override
1270 public void run()
1271 {
1272 viewer.refresh(parentFolder, true);
1273 }
1274 });
1275 }
1276 }.start();
1277 }
1278
1279 /**
1280 * Show file size
1281 */
1282 private void calculateFolderSize()
1283 {
1284 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
1285 if (selection.isEmpty())
1286 return;
1287
1288 final List<AgentFile> files = new ArrayList<AgentFile>(selection.size());
1289 for(Object o : selection.toList())
1290 files.add((AgentFile)o);
1291
1292 new ConsoleJob("Calculate folder size", this, Activator.PLUGIN_ID, null) {
1293 @Override
1294 protected void runInternal(IProgressMonitor monitor) throws Exception
1295 {
1296 for(AgentFile f : files)
1297 {
1298 f.setFileInfo(session.getAgentFileInfo(f));
1299 }
1300 runInUIThread(new Runnable() {
1301 @Override
1302 public void run()
1303 {
1304 viewer.update(files.toArray(), null);
1305 }
1306 });
1307 }
1308
1309 @Override
1310 protected String getErrorMessage()
1311 {
1312 return "Cannot calculate folder size";
1313 }
1314 }.start();
1315 }
1316
1317 /**
1318 * Copy name of file to clipboard
1319 */
1320 private void copyFileName()
1321 {
1322 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
1323 if (selection.size() != 1)
1324 return;
1325
1326 WidgetHelper.copyToClipboard(((AgentFile)selection.getFirstElement()).getName());
1327 }
1328
1329 /**
1330 * Copy full path to file to clipboard
1331 */
1332 private void copyFilePath()
1333 {
1334 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
1335 if (selection.size() != 1)
1336 return;
1337
1338 String filePath = ((AgentFile)selection.getFirstElement()).getFullName();
1339 JavaScriptExecutor executor = RWT.getClient().getService(JavaScriptExecutor.class);
1340 if( executor != null )
1341 {
1342 StringBuilder js = new StringBuilder();
1343 js.append("copyTextToClipboard(\'" + filePath.substring(1, filePath.length()) + "\');"); // Substring is made to remove first "/"
1344 executor.execute(js.toString());
1345 }
1346 }
1347
1348 /*
1349 * (non-Javadoc)
1350 *
1351 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
1352 */
1353 @Override
1354 public void setFocus()
1355 {
1356 viewer.getControl().setFocus();
1357 }
1358
1359 /**
1360 * Enable or disable filter
1361 *
1362 * @param enable New filter state
1363 */
1364 private void enableFilter(boolean enable)
1365 {
1366 initShowFilter = enable;
1367 filterText.setVisible(initShowFilter);
1368 FormData fd = (FormData)viewer.getTree().getLayoutData();
1369 fd.top = enable ? new FormAttachment(filterText) : new FormAttachment(0, 0);
1370 content.layout();
1371 if (enable)
1372 {
1373 filterText.setFocus();
1374 }
1375 else
1376 {
1377 filterText.setText(""); //$NON-NLS-1$
1378 onFilterModify();
1379 }
1380 }
1381
1382 /**
1383 * Handler for filter modification
1384 */
1385 private void onFilterModify()
1386 {
1387 final String text = filterText.getText();
1388 filter.setFilterString(text);
1389 viewer.refresh(false);
1390 }
1391 }