2e86c2c6b926b6cd61af7530454ab2ec59ed6eb9
[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-2015 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.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.net.URLEncoder;
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.core.runtime.Platform;
32 import org.eclipse.jface.action.Action;
33 import org.eclipse.jface.action.GroupMarker;
34 import org.eclipse.jface.action.IMenuListener;
35 import org.eclipse.jface.action.IMenuManager;
36 import org.eclipse.jface.action.IToolBarManager;
37 import org.eclipse.jface.action.MenuManager;
38 import org.eclipse.jface.action.Separator;
39 import org.eclipse.jface.commands.ActionHandler;
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.IWorkbenchPage;
75 import org.eclipse.ui.IWorkbenchWindow;
76 import org.eclipse.ui.PartInitException;
77 import org.eclipse.ui.PlatformUI;
78 import org.eclipse.ui.contexts.IContextService;
79 import org.eclipse.ui.handlers.IHandlerService;
80 import org.eclipse.ui.part.ViewPart;
81 import org.netxms.client.AgentFile;
82 import org.netxms.client.NXCException;
83 import org.netxms.client.NXCSession;
84 import org.netxms.client.ProgressListener;
85 import org.netxms.client.server.ServerFile;
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.ServerFileLabelProvider;
96 import org.netxms.ui.eclipse.filemanager.views.helpers.ViewAgentFilesProvider;
97 import org.netxms.ui.eclipse.jobs.ConsoleJob;
98 import org.netxms.ui.eclipse.objecttools.views.FileViewer;
99 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
100 import org.netxms.ui.eclipse.tools.MessageDialogHelper;
101 import org.netxms.ui.eclipse.tools.WidgetHelper;
102 import org.netxms.ui.eclipse.widgets.FilterText;
103 import org.netxms.ui.eclipse.widgets.SortableTableViewer;
104 import org.netxms.ui.eclipse.widgets.SortableTreeViewer;
105
106 /**
107 * Editor for server files
108 */
109 public class AgentFileManager extends ViewPart
110 {
111 public static final String ID = "org.netxms.ui.eclipse.filemanager.views.AgentFileManager"; //$NON-NLS-1$
112
113 private static final String TABLE_CONFIG_PREFIX = "AgentFileManager"; //$NON-NLS-1$
114
115 // Columns
116 public static final int COLUMN_NAME = 0;
117 public static final int COLUMN_TYPE = 1;
118 public static final int COLUMN_SIZE = 2;
119 public static final int COLUMN_MODIFYED = 3;
120
121 private boolean filterEnabled = false;
122 private Composite content;
123 private ServerFile[] files;
124 private AgentFileFilter filter;
125 private FilterText filterText;
126 private SortableTreeViewer viewer;
127 private NXCSession session;
128 private Action actionRefreshAll;
129 private Action actionUploadFile;
130 private Action actionDelete;
131 private Action actionRename;
132 private Action actionRefreshDirectory;
133 private Action actionShowFilter;
134 private Action actionDownloadFile;
135 private Action actionTailFile;
136 private Action actionShowFile;
137 private Action actionCreateDirectory;
138 private long objectId = 0;
139 private String workspaceDir;
140
141 /*
142 * (non-Javadoc)
143 *
144 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
145 */
146 @Override
147 public void init(IViewSite site) throws PartInitException
148 {
149 super.init(site);
150
151 session = (NXCSession)ConsoleSharedData.getSession();
152 objectId = Long.parseLong(site.getSecondaryId());
153 setPartName(String.format(Messages.get().AgentFileManager_PartTitle, session.getObjectName(objectId)));
154 workspaceDir = Platform.getInstanceLocation().getURL().getPath();
155 }
156
157 /*
158 * (non-Javadoc)
159 *
160 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
161 */
162 @Override
163 public void createPartControl(Composite parent)
164 {
165 content = new Composite(parent, SWT.NONE);
166 content.setLayout(new FormLayout());
167
168 // Create filter area
169 filterText = new FilterText(content, SWT.NONE);
170 filterText.addModifyListener(new ModifyListener() {
171 @Override
172 public void modifyText(ModifyEvent e)
173 {
174 onFilterModify();
175 }
176 });
177 filterText.setCloseAction(new Action() {
178 @Override
179 public void run()
180 {
181 enableFilter(false);
182 }
183 });
184
185 final String[] columnNames = { Messages.get().AgentFileManager_ColName, Messages.get().AgentFileManager_ColType, Messages.get().AgentFileManager_ColSize, Messages.get().AgentFileManager_ColDate };
186 final int[] columnWidths = { 300, 120, 150, 150 };
187 viewer = new SortableTreeViewer(content, columnNames, columnWidths, 0, SWT.UP, SortableTableViewer.DEFAULT_STYLE);
188 WidgetHelper.restoreTreeViewerSettings(viewer, Activator.getDefault().getDialogSettings(), TABLE_CONFIG_PREFIX);
189 viewer.setContentProvider(new ViewAgentFilesProvider());
190 viewer.setLabelProvider(new ServerFileLabelProvider());
191 viewer.setComparator(new AgentFileComparator());
192 filter = new AgentFileFilter();
193 viewer.addFilter(filter);
194 viewer.addSelectionChangedListener(new ISelectionChangedListener() {
195 @Override
196 public void selectionChanged(SelectionChangedEvent event)
197 {
198 IStructuredSelection selection = (IStructuredSelection)event.getSelection();
199 if (selection != null)
200 {
201 actionDelete.setEnabled(selection.size() > 0);
202 }
203 }
204 });
205 viewer.getTree().addDisposeListener(new DisposeListener() {
206 @Override
207 public void widgetDisposed(DisposeEvent e)
208 {
209 WidgetHelper.saveTreeViewerSettings(viewer, Activator.getDefault().getDialogSettings(), TABLE_CONFIG_PREFIX);
210 }
211 });
212 enableDragSupport();
213 enableDropSupport();
214 enableInPlaceRename();
215
216 // Setup layout
217 FormData fd = new FormData();
218 fd.left = new FormAttachment(0, 0);
219 fd.top = new FormAttachment(filterText);
220 fd.right = new FormAttachment(100, 0);
221 fd.bottom = new FormAttachment(100, 0);
222 viewer.getTree().setLayoutData(fd);
223
224 fd = new FormData();
225 fd.left = new FormAttachment(0, 0);
226 fd.top = new FormAttachment(0, 0);
227 fd.right = new FormAttachment(100, 0);
228 filterText.setLayoutData(fd);
229
230 createActions();
231 contributeToActionBars();
232 createPopupMenu();
233 activateContext();
234
235 filterText.setCloseAction(actionShowFilter);
236
237 // Set initial focus to filter input line
238 if (filterEnabled)
239 filterText.setFocus();
240 else
241 enableFilter(false); // Will hide filter area correctly
242
243 refreshFileList();
244 }
245
246 /**
247 * Activate context
248 */
249 private void activateContext()
250 {
251 IContextService contextService = (IContextService)getSite().getService(IContextService.class);
252 if (contextService != null)
253 {
254 contextService.activateContext("org.netxms.ui.eclipse.filemanager.context.AgentFileManager"); //$NON-NLS-1$
255 }
256 }
257
258 /**
259 * Enable drag support in object tree
260 */
261 public void enableDragSupport()
262 {
263 Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };
264 viewer.addDragSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, new DragSourceAdapter() {
265 @Override
266 public void dragStart(DragSourceEvent event)
267 {
268 LocalSelectionTransfer.getTransfer().setSelection(viewer.getSelection());
269 event.doit = true;
270 }
271
272 @Override
273 public void dragSetData(DragSourceEvent event)
274 {
275 event.data = LocalSelectionTransfer.getTransfer().getSelection();
276 }
277 });
278 }
279
280 /**
281 * Enable drop support in object tree
282 */
283 public void enableDropSupport()// SubtreeType infrastructure
284 {
285 final Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };
286 viewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, new ViewerDropAdapter(viewer) {
287
288 @Override
289 public boolean performDrop(Object data)
290 {
291 IStructuredSelection selection = (IStructuredSelection)data;
292 List<?> movableSelection = selection.toList();
293 for(int i = 0; i < movableSelection.size(); i++)
294 {
295 ServerFile movableObject = (ServerFile)movableSelection.get(i);
296
297 moveFile((ServerFile)getCurrentTarget(), movableObject);
298
299 }
300 return true;
301 }
302
303 @Override
304 public boolean validateDrop(Object target, int operation, TransferData transferType)
305 {
306 if ((target == null) || !LocalSelectionTransfer.getTransfer().isSupportedType(transferType))
307 return false;
308
309 IStructuredSelection selection = (IStructuredSelection)LocalSelectionTransfer.getTransfer().getSelection();
310 if (selection.isEmpty())
311 return false;
312
313 for(final Object object : selection.toList())
314 {
315 if (!(object instanceof ServerFile))
316 return false;
317 }
318 if (!(target instanceof ServerFile))
319 {
320 return false;
321 }
322 else
323 {
324 if (!((ServerFile)target).isDirectory())
325 {
326 return false;
327 }
328 }
329 return true;
330 }
331 });
332 }
333
334 /**
335 * Enable in-place renames
336 */
337 private void enableInPlaceRename()
338 {
339 TreeViewerEditor.create(viewer, new ColumnViewerEditorActivationStrategy(viewer) {
340 @Override
341 protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event)
342 {
343 return event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
344 }
345 }, ColumnViewerEditor.DEFAULT);
346 viewer.setCellEditors(new CellEditor[] { new TextCellEditor(viewer.getTree()) });
347 viewer.setColumnProperties(new String[] { "name" }); //$NON-NLS-1$
348 viewer.setCellModifier(new ICellModifier() {
349 @Override
350 public void modify(Object element, String property, Object value)
351 {
352 if (element instanceof Item)
353 element = ((Item)element).getData();
354
355 if (property.equals("name")) //$NON-NLS-1$
356 {
357 if (element instanceof ServerFile)
358 {
359 doRename((ServerFile)element, value.toString());
360 }
361 }
362 }
363
364 @Override
365 public Object getValue(Object element, String property)
366 {
367 if (property.equals("name")) //$NON-NLS-1$
368 {
369 if (element instanceof ServerFile)
370 {
371 return ((ServerFile)element).getName();
372 }
373 }
374 return null;
375 }
376
377 @Override
378 public boolean canModify(Object element, String property)
379 {
380 return property.equals("name"); //$NON-NLS-1$
381 }
382 });
383 }
384
385 /**
386 * Do actual rename
387 *
388 * @param serverFile
389 * @param newName
390 */
391 private void doRename(final ServerFile serverFile, final String newName)
392 {
393 new ConsoleJob(Messages.get().ViewServerFile_DeletFileFromServerJob, this, Activator.PLUGIN_ID, Activator.PLUGIN_ID) {
394 @Override
395 protected String getErrorMessage()
396 {
397 return Messages.get().AgentFileManager_RenameError;
398 }
399
400 @Override
401 protected void runInternal(IProgressMonitor monitor) throws Exception
402 {
403 session.renameAgentFile(objectId, serverFile.getFullName(), serverFile.getParent().getFullName() + "/" + newName); //$NON-NLS-1$
404
405 runInUIThread(new Runnable() {
406 @Override
407 public void run()
408 {
409 serverFile.setName(newName);
410 viewer.refresh(serverFile, true);
411 }
412 });
413 }
414 }.start();
415 }
416
417 /**
418 * Create actions
419 */
420 private void createActions()
421 {
422 final IHandlerService handlerService = (IHandlerService)getSite().getService(IHandlerService.class);
423
424 actionRefreshDirectory = new Action(Messages.get().AgentFileManager_RefreshFolder, SharedIcons.REFRESH) {
425 @Override
426 public void run()
427 {
428 refreshFileOrDirectory();
429 }
430 };
431 actionRefreshDirectory.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.refreshFolder"); //$NON-NLS-1$
432 handlerService.activateHandler(actionRefreshDirectory.getActionDefinitionId(), new ActionHandler(actionRefreshDirectory));
433
434 actionRefreshAll = new RefreshAction(this) {
435 @Override
436 public void run()
437 {
438 refreshFileList();
439 }
440 };
441
442 actionUploadFile = new Action(Messages.get().AgentFileManager_UploadFile) {
443 @Override
444 public void run()
445 {
446 uploadFile();
447 }
448 };
449 actionUploadFile.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.uploadFile"); //$NON-NLS-1$
450 handlerService.activateHandler(actionUploadFile.getActionDefinitionId(), new ActionHandler(actionUploadFile));
451
452 actionDelete = new Action(Messages.get().AgentFileManager_Delete, SharedIcons.DELETE_OBJECT) {
453 @Override
454 public void run()
455 {
456 deleteFile();
457 }
458 };
459 actionDelete.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.delete"); //$NON-NLS-1$
460 handlerService.activateHandler(actionDelete.getActionDefinitionId(), new ActionHandler(actionDelete));
461
462 actionRename = new Action(Messages.get().AgentFileManager_Rename) {
463 @Override
464 public void run()
465 {
466 renameFile();
467 }
468 };
469 actionRename.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.rename"); //$NON-NLS-1$
470 handlerService.activateHandler(actionRename.getActionDefinitionId(), new ActionHandler(actionRename));
471
472 actionShowFilter = new Action(Messages.get().ViewServerFile_ShowFilterAction, Action.AS_CHECK_BOX) {
473 @Override
474 public void run()
475 {
476 enableFilter(!filterEnabled);
477 actionShowFilter.setChecked(filterEnabled);
478 }
479 };
480 actionShowFilter.setChecked(filterEnabled);
481 actionShowFilter.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.showFilter"); //$NON-NLS-1$
482 handlerService.activateHandler(actionShowFilter.getActionDefinitionId(), new ActionHandler(actionShowFilter));
483
484 actionDownloadFile = new Action(Messages.get().AgentFileManager_Download) {
485 @Override
486 public void run()
487 {
488 startDownload();
489 }
490 };
491 actionDownloadFile.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.download"); //$NON-NLS-1$
492 handlerService.activateHandler(actionDownloadFile.getActionDefinitionId(), new ActionHandler(actionDownloadFile));
493
494 actionTailFile = new Action("Tail") {
495 @Override
496 public void run()
497 {
498 tailFile(true, 500);
499 }
500 };
501
502 actionShowFile = new Action(Messages.get().AgentFileManager_Show) {
503 @Override
504 public void run()
505 {
506 tailFile(false, 0);
507 }
508 };
509
510 actionCreateDirectory = new Action(Messages.get().AgentFileManager_CreateFolder) {
511 @Override
512 public void run()
513 {
514 createFolder();
515 }
516 };
517 actionCreateDirectory.setActionDefinitionId("org.netxms.ui.eclipse.filemanager.commands.newFolder"); //$NON-NLS-1$
518 handlerService.activateHandler(actionCreateDirectory.getActionDefinitionId(), new ActionHandler(actionCreateDirectory));
519 }
520
521 /**
522 * Contribute actions to action bar
523 */
524 private void contributeToActionBars()
525 {
526 IActionBars bars = getViewSite().getActionBars();
527 fillLocalPullDown(bars.getMenuManager());
528 fillLocalToolBar(bars.getToolBarManager());
529 }
530
531 /**
532 * Fill local pull-down menu
533 *
534 * @param manager Menu manager for pull-down menu
535 */
536 private void fillLocalPullDown(IMenuManager manager)
537 {
538 manager.add(actionShowFilter);
539 manager.add(new Separator());
540 manager.add(actionRefreshAll);
541 }
542
543 /**
544 * Fill local tool bar
545 *
546 * @param manager Menu manager for local tool bar
547 */
548 private void fillLocalToolBar(IToolBarManager manager)
549 {
550 manager.add(actionRefreshAll);
551 }
552
553 /**
554 * Create pop-up menu for user list
555 */
556 private void createPopupMenu()
557 {
558 // Create menu manager
559 MenuManager menuMgr = new MenuManager();
560 menuMgr.setRemoveAllWhenShown(true);
561 menuMgr.addMenuListener(new IMenuListener() {
562 public void menuAboutToShow(IMenuManager mgr)
563 {
564 fillContextMenu(mgr);
565 }
566 });
567
568 // Create menu
569 Menu menu = menuMgr.createContextMenu(viewer.getControl());
570 viewer.getControl().setMenu(menu);
571
572 // Register menu for extension.
573 getSite().registerContextMenu(menuMgr, viewer);
574 }
575
576 /**
577 * Fill context menu
578 *
579 * @param mgr Menu manager
580 */
581 protected void fillContextMenu(final IMenuManager mgr)
582 {
583 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
584 if (selection.isEmpty())
585 return;
586
587 if (selection.size() == 1)
588 {
589 if (((ServerFile)selection.getFirstElement()).isDirectory())
590 {
591 mgr.add(actionUploadFile);
592 }
593 else
594 {
595 mgr.add(actionTailFile);
596 mgr.add(actionShowFile);
597 }
598 mgr.add(actionDownloadFile);
599 mgr.add(new Separator());
600 }
601
602 if (selection.size() == 1)
603 {
604 if (((ServerFile)selection.getFirstElement()).isDirectory())
605 {
606 mgr.add(actionCreateDirectory);
607 }
608 mgr.add(actionRename);
609 }
610 mgr.add(actionDelete);
611 mgr.add(new Separator());
612 mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
613 if ((selection.size() == 1) && ((ServerFile)selection.getFirstElement()).isDirectory())
614 {
615 mgr.add(new Separator());
616 mgr.add(actionRefreshDirectory);
617 }
618 }
619
620 /**
621 * Refresh file list
622 */
623 private void refreshFileList()
624 {
625 new ConsoleJob(Messages.get().SelectServerFileDialog_JobTitle, null, Activator.PLUGIN_ID, null) {
626 @Override
627 protected void runInternal(IProgressMonitor monitor) throws Exception
628 {
629 files = session.listAgentFiles(null, "/", objectId); //$NON-NLS-1$
630 runInUIThread(new Runnable() {
631 @Override
632 public void run()
633 {
634 viewer.setInput(files);
635 }
636 });
637 }
638
639 @Override
640 protected String getErrorMessage()
641 {
642 return Messages.get().SelectServerFileDialog_JobError;
643 }
644 }.start();
645 }
646
647 /**
648 * Refresh file list
649 */
650 private void refreshFileOrDirectory()
651 {
652 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
653 if (selection.isEmpty())
654 return;
655
656 final Object[] objects = selection.toArray();
657
658 new ConsoleJob(Messages.get().SelectServerFileDialog_JobTitle, null, Activator.PLUGIN_ID, null) {
659 @Override
660 protected void runInternal(IProgressMonitor monitor) throws Exception
661 {
662 for(int i = 0; i < objects.length; i++)
663 {
664 if (!((ServerFile)objects[i]).isDirectory())
665 objects[i] = ((ServerFile)objects[i]).getParent();
666
667 final ServerFile sf = ((ServerFile)objects[i]);
668 sf.setChildren(session.listAgentFiles(sf, sf.getFullName(), objectId));
669
670 runInUIThread(new Runnable() {
671 @Override
672 public void run()
673 {
674 viewer.refresh(sf);
675 }
676 });
677 }
678 }
679
680 @Override
681 protected String getErrorMessage()
682 {
683 return Messages.get().SelectServerFileDialog_JobError;
684 }
685 }.start();
686 }
687
688 /**
689 * Upload local file to agent
690 */
691 private void uploadFile()
692 {
693 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
694 if (selection.isEmpty())
695 return;
696
697 final Object[] objects = selection.toArray();
698 final ServerFile upladFolder = ((ServerFile)objects[0]).isDirectory() ? ((ServerFile)objects[0]) : ((ServerFile)objects[0])
699 .getParent();
700
701 final StartClientToServerFileUploadDialog dlg = new StartClientToServerFileUploadDialog(getSite().getShell());
702 if (dlg.open() == Window.OK)
703 {
704 final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
705 new ConsoleJob(Messages.get().AgentFileManager_UploadFileJobTitle, null, Activator.PLUGIN_ID, null) {
706 @Override
707 protected void runInternal(final IProgressMonitor monitor) throws Exception
708 {
709 List<File> fileList = dlg.getLocalFiles();
710 for(int i = 0; i < fileList.size(); i++)
711 {
712 final File localFile = fileList.get(i);
713 String remoteFile = fileList.get(i).getName();
714 if(fileList.size() == 1)
715 remoteFile = dlg.getRemoteFileName();
716
717 session.uploadLocalFileToAgent(localFile, upladFolder.getFullName()+"/"+remoteFile, objectId, new ProgressListener() { //$NON-NLS-1$
718 private long prevWorkDone = 0;
719
720 @Override
721 public void setTotalWorkAmount(long workTotal)
722 {
723 monitor.beginTask(Messages.get(getDisplay()).UploadFileToServer_TaskNamePrefix
724 + localFile.getAbsolutePath(),
725 (int)workTotal);
726 }
727
728 @Override
729 public void markProgress(long workDone)
730 {
731 monitor.worked((int)(workDone - prevWorkDone));
732 prevWorkDone = workDone;
733 }
734 });
735 monitor.done();
736 }
737
738 upladFolder.setChildren(session.listAgentFiles(upladFolder, upladFolder.getFullName(), objectId));
739 runInUIThread(new Runnable() {
740 @Override
741 public void run()
742 {
743
744 viewer.refresh(upladFolder, true);
745 }
746 });
747 }
748
749 @Override
750 protected String getErrorMessage()
751 {
752 return Messages.get().UploadFileToServer_JobError;
753 }
754 }.start();
755 }
756 }
757
758 /**
759 * Upload local folder to agent
760 */
761 /*
762 private void uploadFolder()
763 {
764 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
765 if (selection.isEmpty())
766 return;
767
768 final Object[] objects = selection.toArray();
769 final ServerFile upladFolder = ((ServerFile)objects[0]).isDirectory() ? ((ServerFile)objects[0]) : ((ServerFile)objects[0])
770 .getParent();
771
772 final StartClientToAgentFolderUploadDialog dlg = new StartClientToAgentFolderUploadDialog(getSite().getShell());
773 if (dlg.open() == Window.OK)
774 {
775 final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
776 new ConsoleJob(Messages.get().AgentFileManager_UploadFolderJobTitle, null, Activator.PLUGIN_ID, null) {
777 @Override
778 protected void runInternal(final IProgressMonitor monitor) throws Exception
779 {
780 File folder = dlg.getLocalFile();
781 session.createFolderOnAgent(upladFolder.getFullName()+"/"+dlg.getRemoteFileName(), objectId); //$NON-NLS-1$
782 listFilesForFolder(folder, upladFolder.getFullName()+"/"+dlg.getRemoteFileName(), monitor); //$NON-NLS-1$
783
784 upladFolder.setChildren(session.listAgentFiles(upladFolder, upladFolder.getFullName(), objectId));
785 runInUIThread(new Runnable() {
786 @Override
787 public void run()
788 {
789 viewer.refresh(upladFolder, true);
790 }
791 });
792 }
793
794 @Override
795 protected String getErrorMessage()
796 {
797 return Messages.get().UploadFileToServer_JobError;
798 }
799 }.start();
800 }
801 }
802 */
803
804 /**
805 * Recursively uploads files to agent and creates correct folders
806 *
807 * @param folder
808 * @param upladFolder
809 * @param monitor
810 * @throws NXCException
811 * @throws IOException
812 */
813 public void listFilesForFolder(final File folder, final String upladFolder, final IProgressMonitor monitor) throws NXCException, IOException
814 {
815 for (final File fileEntry : folder.listFiles())
816 {
817 if (fileEntry.isDirectory())
818 {
819 session.createFolderOnAgent(upladFolder+"/"+fileEntry.getName(), objectId); //$NON-NLS-1$
820 listFilesForFolder(fileEntry, upladFolder+"/"+fileEntry.getName(), monitor); //$NON-NLS-1$
821 }
822 else
823 {
824 session.uploadLocalFileToAgent(fileEntry, upladFolder+"/"+fileEntry.getName(), objectId, new ProgressListener() { //$NON-NLS-1$
825 private long prevWorkDone = 0;
826
827 @Override
828 public void setTotalWorkAmount(long workTotal)
829 {
830 monitor.beginTask(Messages.get().UploadFileToServer_TaskNamePrefix + fileEntry.getAbsolutePath(),
831 (int)workTotal);
832 }
833
834 @Override
835 public void markProgress(long workDone)
836 {
837 monitor.worked((int)(workDone - prevWorkDone));
838 prevWorkDone = workDone;
839 }
840 });
841 monitor.done();
842 }
843 }
844 }
845
846 /**
847 * Delete selected file
848 */
849 private void deleteFile()
850 {
851 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
852 if (selection.isEmpty())
853 return;
854
855 if (!MessageDialogHelper.openConfirm(getSite().getShell(), Messages.get().ViewServerFile_DeleteConfirmation,
856 Messages.get().ViewServerFile_DeletAck))
857 return;
858
859 final Object[] objects = selection.toArray();
860 new ConsoleJob(Messages.get().ViewServerFile_DeletFileFromServerJob, this, Activator.PLUGIN_ID, Activator.PLUGIN_ID) {
861 @Override
862 protected String getErrorMessage()
863 {
864 return Messages.get().ViewServerFile_ErrorDeleteFileJob;
865 }
866
867 @Override
868 protected void runInternal(IProgressMonitor monitor) throws Exception
869 {
870 for(int i = 0; i < objects.length; i++)
871 {
872 final ServerFile sf = (ServerFile)objects[i];
873 session.deleteAgentFile(objectId, sf.getFullName());
874
875 runInUIThread(new Runnable() {
876 @Override
877 public void run()
878 {
879 sf.getParent().removeChield(sf);
880 viewer.refresh(sf.getParent());
881 }
882 });
883 }
884 }
885 }.start();
886 }
887
888 /**
889 * Starts file tail view&messages
890 */
891 private void tailFile(final boolean tail, final int offset)
892 {
893 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
894 if (selection.isEmpty())
895 return;
896
897 final Object[] objects = selection.toArray();
898
899 if (((ServerFile)objects[0]).isDirectory())
900 return;
901
902 final ServerFile sf = ((ServerFile)objects[0]);
903
904 ConsoleJob job = new ConsoleJob(Messages.get().AgentFileManager_DownloadJobTitle, null, Activator.PLUGIN_ID, null) {
905 @Override
906 protected String getErrorMessage()
907 {
908 return String.format(Messages.get().AgentFileManager_DownloadJobError, sf.getFullName(), objectId);
909 }
910
911 @Override
912 protected void runInternal(IProgressMonitor monitor) throws Exception
913 {
914 final AgentFile file = session.downloadFileFromAgent(objectId, sf.getFullName(), offset, tail);
915 runInUIThread(new Runnable() {
916 @Override
917 public void run()
918 {
919 final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
920 try
921 {
922 String secondaryId = Long.toString(objectId) + "&" + URLEncoder.encode(sf.getName(), "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
923 FileViewer view = (FileViewer)window.getActivePage().showView(FileViewer.ID, secondaryId,
924 IWorkbenchPage.VIEW_ACTIVATE);
925 view.showFile(file.getFile(), tail, file.getId(), offset);
926 }
927 catch(Exception e)
928 {
929 MessageDialogHelper.openError(window.getShell(), Messages.get().AgentFileManager_Error,
930 String.format(Messages.get().AgentFileManager_OpenViewError, e.getLocalizedMessage()));
931 }
932 }
933 });
934 }
935 };
936 job.start();
937 }
938
939 /**
940 * Download file from agent
941 */
942 private void startDownload()
943 {
944 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
945 if (selection.size() != 1)
946 return;
947
948 final ServerFile sf = (ServerFile)selection.getFirstElement();
949
950 if (!sf.isDirectory())
951 downloadFile(sf.getFullName());
952
953 if (sf.isDirectory())
954 {
955 ConsoleJob job = new ConsoleJob(Messages.get().SelectServerFileDialog_JobTitle, null, Activator.PLUGIN_ID, null) {
956 @Override
957 protected void runInternal(IProgressMonitor monitor) throws Exception
958 {
959 //create zip from download folder wile download
960 FileOutputStream fos = new FileOutputStream(workspaceDir+File.separator+sf.getName()+".zip");
961 ZipOutputStream zos = new ZipOutputStream(fos);
962 downloadDir(sf, sf.getName(), zos);
963
964 zos.close();
965 fos.close();
966
967 //javascript for client to download this zip
968 final File zipArchive = new File(workspaceDir+File.separator+sf.getName()+".zip");
969 DownloadServiceHandler.addDownload(zipArchive.getName(), zipArchive.getName(), zipArchive, "application/octet-stream");
970 runInUIThread(new Runnable() {
971 @Override
972 public void run()
973 {
974 JavaScriptExecutor executor = RWT.getClient().getService(JavaScriptExecutor.class);
975 if( executor != null )
976 {
977 StringBuilder js = new StringBuilder();
978 js.append("var hiddenIFrameID = 'hiddenDownloader',");
979 js.append(" iframe = document.getElementById(hiddenIFrameID);");
980 js.append("if (iframe === null) {");
981 js.append(" iframe = document.createElement('iframe');");
982 js.append(" iframe.id = hiddenIFrameID;");
983 js.append(" iframe.style.display = 'none';");
984 js.append(" document.body.appendChild(iframe);");
985 js.append("}");
986 js.append("iframe.src = '");
987 js.append(DownloadServiceHandler.createDownloadUrl(zipArchive.getName()));
988 js.append("';");
989 executor.execute(js.toString());
990 }
991 }
992 });
993 }
994
995 @Override
996 protected String getErrorMessage()
997 {
998 return Messages.get().AgentFileManager_DirectoryReadError;
999 }
1000 };
1001 job.setUser(false);
1002 job.start();
1003 }
1004 }
1005
1006 public static void addToZipFile(String fileName, ZipOutputStream zos) throws FileNotFoundException, IOException
1007 {
1008 File file = new File(fileName);
1009 FileInputStream fis = new FileInputStream(file);
1010 ZipEntry zipEntry = new ZipEntry(fileName+File.separator);
1011 zos.putNextEntry(zipEntry);
1012
1013 byte[] bytes = new byte[1024];
1014 int length;
1015 while ((length = fis.read(bytes)) >= 0)
1016 {
1017 zos.write(bytes, 0, length);
1018 }
1019
1020 zos.closeEntry();
1021 fis.close();
1022 }
1023
1024 /**
1025 * Recursively download directory from agent to local pc
1026 *
1027 * @param sf
1028 * @param localFileName
1029 * @throws IOException
1030 * @throws NXCException
1031 */
1032 private void downloadDir(final ServerFile sf, String localFileName, ZipOutputStream zos) throws NXCException, IOException
1033 {
1034 //create directory inside of zip
1035 zos.putNextEntry(new ZipEntry(localFileName+File.separator));
1036 zos.closeEntry();
1037 ServerFile[] files = sf.getChildren();
1038 if(files == null)
1039 {
1040 files = session.listAgentFiles(sf, sf.getFullName(), sf.getNodeId());
1041 }
1042 for(int i = 0; i < files.length; i++)
1043 {
1044 if(files[i].isDirectory())
1045 {
1046 downloadDir(files[i], localFileName + "/" + sf.getName(), zos); //$NON-NLS-1$
1047 }
1048 else
1049 {
1050 final AgentFile file = session.downloadFileFromAgent(objectId, files[i].getFullName(), 0, false);
1051
1052 FileInputStream fis = new FileInputStream(file.getFile());
1053 ZipEntry zipEntry = new ZipEntry(localFileName+"/"+files[i].getName());
1054 zos.putNextEntry(zipEntry);
1055
1056 byte[] bytes = new byte[1024];
1057 int length;
1058 while ((length = fis.read(bytes)) >= 0)
1059 {
1060 zos.write(bytes, 0, length);
1061 }
1062
1063 zos.closeEntry();
1064 fis.close();
1065 }
1066 }
1067 }
1068
1069 /**
1070 * Downloads file
1071 */
1072 private void downloadFile(final String remoteName)
1073 {
1074 ConsoleJob job = new ConsoleJob(Messages.get().AgentFileManager_DownloadFileFromAgent, null, Activator.PLUGIN_ID, null) {
1075 @Override
1076 protected void runInternal(IProgressMonitor monitor) throws Exception
1077 {
1078 final AgentFile file = session.downloadFileFromAgent(objectId, remoteName, 0, false);
1079 DownloadServiceHandler.addDownload(file.getFile().getName(), remoteName, file.getFile(), "application/octet-stream");
1080 runInUIThread(new Runnable() {
1081 @Override
1082 public void run()
1083 {
1084 JavaScriptExecutor executor = RWT.getClient().getService(JavaScriptExecutor.class);
1085 if( executor != null )
1086 {
1087 StringBuilder js = new StringBuilder();
1088 js.append("var hiddenIFrameID = 'hiddenDownloader',");
1089 js.append(" iframe = document.getElementById(hiddenIFrameID);");
1090 js.append("if (iframe === null) {");
1091 js.append(" iframe = document.createElement('iframe');");
1092 js.append(" iframe.id = hiddenIFrameID;");
1093 js.append(" iframe.style.display = 'none';");
1094 js.append(" document.body.appendChild(iframe);");
1095 js.append("}");
1096 js.append("iframe.src = '");
1097 js.append(DownloadServiceHandler.createDownloadUrl(file.getFile().getName()));
1098 js.append("';");
1099 executor.execute(js.toString());
1100 }
1101 }
1102 });
1103 }
1104
1105 @Override
1106 protected String getErrorMessage()
1107 {
1108 return String.format(Messages.get().AgentFileManager_FileDownloadError, remoteName, session.getObjectName(objectId), objectId);
1109 }
1110 };
1111 job.start();
1112 }
1113
1114 /**
1115 * Rename selected file
1116 */
1117 private void renameFile()
1118 {
1119 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
1120 if (selection.size() != 1)
1121 return;
1122
1123 viewer.editElement(selection.getFirstElement(), 0);
1124 }
1125
1126 /**
1127 * Move selected file
1128 */
1129 private void moveFile(final ServerFile target, final ServerFile object)
1130 {
1131 new ConsoleJob(Messages.get().AgentFileManager_MoveFile, this, Activator.PLUGIN_ID, Activator.PLUGIN_ID) {
1132 @Override
1133 protected String getErrorMessage()
1134 {
1135 return Messages.get().AgentFileManager_MoveError;
1136 }
1137
1138 @Override
1139 protected void runInternal(IProgressMonitor monitor) throws Exception
1140 {
1141 session.renameAgentFile(objectId, object.getFullName(), target.getFullName() + "/" + object.getName()); //$NON-NLS-1$
1142
1143 runInUIThread(new Runnable() {
1144 @Override
1145 public void run()
1146 {
1147 object.getParent().removeChield(object);
1148 viewer.refresh(object.getParent(), true);
1149 object.setParent(target);
1150 target.addChield(object);
1151 viewer.refresh(object.getParent(), true);
1152 }
1153 });
1154 }
1155 }.start();
1156 }
1157
1158 /**
1159 * Create new folder
1160 */
1161 private void createFolder()
1162 {
1163 IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
1164 if (selection.isEmpty())
1165 return;
1166
1167 final Object[] objects = selection.toArray();
1168 final ServerFile parentFolder = ((ServerFile)objects[0]).isDirectory() ? ((ServerFile)objects[0]) : ((ServerFile)objects[0])
1169 .getParent();
1170
1171 final CreateFolderDialog dlg = new CreateFolderDialog(getSite().getShell());
1172 if (dlg.open() != Window.OK)
1173 return;
1174
1175 final String newFolder = dlg.getNewName();
1176
1177 new ConsoleJob(Messages.get().AgentFileManager_CreatingFolder, this, Activator.PLUGIN_ID, Activator.PLUGIN_ID) {
1178 @Override
1179 protected String getErrorMessage()
1180 {
1181 return Messages.get().AgentFileManager_FolderCreationError;
1182 }
1183
1184 @Override
1185 protected void runInternal(IProgressMonitor monitor) throws Exception
1186 {
1187 session.createFolderOnAgent(parentFolder.getFullName() + "/" + newFolder, objectId); //$NON-NLS-1$
1188 parentFolder.setChildren(session.listAgentFiles(parentFolder, parentFolder.getFullName(), objectId));
1189
1190 runInUIThread(new Runnable() {
1191 @Override
1192 public void run()
1193 {
1194 viewer.refresh(parentFolder, true);
1195 }
1196 });
1197 }
1198 }.start();
1199 }
1200
1201 /*
1202 * (non-Javadoc)
1203 *
1204 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
1205 */
1206 @Override
1207 public void setFocus()
1208 {
1209 viewer.getControl().setFocus();
1210 }
1211
1212 /**
1213 * Enable or disable filter
1214 *
1215 * @param enable New filter state
1216 */
1217 private void enableFilter(boolean enable)
1218 {
1219 filterEnabled = enable;
1220 filterText.setVisible(filterEnabled);
1221 FormData fd = (FormData)viewer.getTree().getLayoutData();
1222 fd.top = enable ? new FormAttachment(filterText) : new FormAttachment(0, 0);
1223 content.layout();
1224 if (enable)
1225 {
1226 filterText.setFocus();
1227 }
1228 else
1229 {
1230 filterText.setText(""); //$NON-NLS-1$
1231 onFilterModify();
1232 }
1233 }
1234
1235 /**
1236 * Handler for filter modification
1237 */
1238 private void onFilterModify()
1239 {
1240 final String text = filterText.getText();
1241 filter.setFilterString(text);
1242 viewer.refresh(false);
1243 }
1244 }