/* * Copyright 2015 the original author or authors. * @https://github.com/scouter-project/scouter * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package scouter.client.views; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.TreeColumnLayout; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.ViewPart; import scouter.client.Images; import scouter.client.net.TcpProxy; import scouter.client.server.ServerManager; import scouter.client.sorter.TreeLabelSorter; import scouter.client.util.ConsoleProxy; import scouter.client.util.ExUtil; import scouter.client.util.ImageUtil; import scouter.client.util.ScouterUtil; import scouter.lang.pack.MapPack; import scouter.lang.value.ListValue; import scouter.net.RequestCmd; import scouter.util.DateUtil; public class ServerFileManagementView extends ViewPart { public static final String ID = ServerFileManagementView.class.getName(); public TreeViewer viewer; public Tree tree; Composite labelComp; Label totalLabel; private int serverId; Map<String, DirObject> dirMap = new TreeMap<String, DirObject>(); public void init(IViewSite site) throws PartInitException { super.init(site); String secId = site.getSecondaryId(); if (secId != null) { serverId = Integer.parseInt(secId); } } public void createPartControl(Composite parent) { this.setPartName("DataManagement[" + ServerManager.getInstance().getServer(serverId).getName() + "]"); parent.setLayout(new GridLayout(1, true)); labelComp = new Composite(parent, SWT.NONE); labelComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); labelComp.setLayout(new RowLayout()); totalLabel = new Label(parent, SWT.NONE); totalLabel.setText(" "); Composite treeComp = new Composite(parent, SWT.BORDER); treeComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); tree = new Tree(treeComp, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI); tree.setHeaderVisible(true); viewer = new TreeViewer(tree); tree.setLinesVisible(true); final TreeColumn nameColumn = new TreeColumn(tree, SWT.LEFT); nameColumn.setAlignment(SWT.LEFT); nameColumn.setText("Name"); nameColumn.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { TreeLabelSorter sorter = (TreeLabelSorter) viewer.getComparator(); sorter.setColumn(nameColumn); } }); final TreeColumn sizeColumn = new TreeColumn(tree, SWT.RIGHT); sizeColumn.setAlignment(SWT.RIGHT); sizeColumn.setText("Size"); sizeColumn.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { TreeLabelSorter sorter = (TreeLabelSorter) viewer.getComparator(); sorter.setColumn(sizeColumn); } }); final TreeColumn timeColumn = new TreeColumn(tree, SWT.CENTER); timeColumn.setAlignment(SWT.CENTER); timeColumn.setText("Last Modified"); timeColumn.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { TreeLabelSorter sorter = (TreeLabelSorter) viewer.getComparator(); sorter.setColumn(timeColumn); } }); TreeColumnLayout layout = new TreeColumnLayout(); treeComp.setLayout(layout); layout.setColumnData(nameColumn, new ColumnWeightData(30)); layout.setColumnData(sizeColumn, new ColumnWeightData(20)); layout.setColumnData(timeColumn, new ColumnWeightData(20)); viewer.setContentProvider(new DirContentProvider()); viewer.setLabelProvider(new LockLabelProvider()); viewer.setComparator(new TreeLabelSorter(viewer).setCustomCompare(new TreeLabelSorter.ICustomCompare() { public int doCompare(TreeColumn col, int index, Object o1, Object o2) { if (o1 instanceof DirObject && o2 instanceof DirObject) { DirObject dirObj1 = (DirObject) o1; DirObject dirObj2 = (DirObject) o2; switch (index) { case 0: return dirObj1.name.compareTo(dirObj2.name); case 1: long gap = dirObj1.size - dirObj2.size; if (gap > 0) { return 1; } else if (gap < 0) { return -1; } else { return 0; } case 2: gap = dirObj1.lastModified - dirObj2.lastModified; if (gap > 0) { return 1; } else if (gap < 0) { return -1; } else { return 0; } } } return 0; } })); viewer.setInput(dirMap); IToolBarManager man = getViewSite().getActionBars().getToolBarManager(); man.add(new Action("Collapse All", ImageUtil .getImageDescriptor(Images.collapse)) { public void run() { viewer.collapseAll(); } }); man.add(new Separator()); man.add(new Action("Reload", ImageUtil .getImageDescriptor(Images.refresh)) { public void run() { load(); } }); load(); createContextMenu(viewer, new IMenuListener() { public void menuAboutToShow(IMenuManager manager){ fillTreeViewerContextMenu(manager); } }); } private void load() { ExUtil.asyncRun(new Runnable() { public void run() { TcpProxy tcpProxy = TcpProxy.getTcpProxy(serverId); try { MapPack pack = (MapPack) tcpProxy.getSingle( RequestCmd.SERVER_DB_LIST, null); if (pack == null) { return; } final long totalSize = pack.getLong("total"); final long freeSize = pack.getLong("free"); ListValue nameLv = pack.getList("name"); ListValue sizeLv = pack.getList("size"); ListValue lastModifiedLv = pack.getList("lastModified"); dirMap.clear(); Map<String, DirObject> tempMap = new HashMap<String, DirObject>(); for (int i = 0; i < nameLv.size(); i++) { DirObject dirObj = new DirObject(); dirObj.name = nameLv.getString(i); dirObj.size = sizeLv.getLong(i); dirObj.lastModified = lastModifiedLv.getLong(i); tempMap.put(dirObj.name, dirObj); } Iterator<String> itr = tempMap.keySet().iterator(); while (itr.hasNext()) { String name = itr.next(); DirObject dirObj = tempMap.get(name); int lastIndex = name.lastIndexOf("/"); if (lastIndex < 0) { lastIndex = name.lastIndexOf("\\"); } if (lastIndex > 1) { String parentName = name.substring(0, lastIndex); DirObject parentObj = tempMap.get(parentName); parentObj.addChild(dirObj); dirObj.parent = parentObj; } else { dirMap.put(name, dirObj); } } ExUtil.exec(labelComp, new Runnable() { public void run() { StringBuffer sb = new StringBuffer(); sb.append("Size : "); sb.append(ScouterUtil.humanReadableByteCount( totalSize, true)); if (freeSize > 0) { sb.append(" / Available : "); sb.append(ScouterUtil.humanReadableByteCount( freeSize, true)); } totalLabel.setText(sb.toString()); totalLabel.update(); labelComp.layout(true, true); } }); ExUtil.exec(viewer.getTree(), new Runnable() { public void run() { viewer.refresh(); } }); } catch (Throwable th) { th.printStackTrace(); } finally { TcpProxy.putTcpProxy(tcpProxy); } } }); } public void setFocus() { } private void createContextMenu(Viewer viewer, IMenuListener listener) { MenuManager contextMenu = new MenuManager(); contextMenu.setRemoveAllWhenShown(true); contextMenu.addMenuListener(listener); Menu menu = contextMenu.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); getSite().registerContextMenu(contextMenu, viewer); } private void fillTreeViewerContextMenu(IMenuManager mgr){ ISelection selection = viewer.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection sel = (IStructuredSelection)selection; Object[] elements = sel.toArray(); if (elements == null || elements.length < 1) { return; } Action action = new DeleteAction(elements); for (Object obj : elements) { try { DirObject dirObj = (DirObject) obj; if (dirObj.name.contains("00000000")) { action.setEnabled(false); break; } } catch (Exception e) { } } mgr.add(action); } } public class DeleteAction extends Action { Object[] elements; public DeleteAction(Object[] elements) { super("&Delete"); this.elements = elements; } public void run() { int length = elements.length; if (MessageDialog.openConfirm(getViewSite().getShell(), "Permanently Delete", length + " directories are deleted permanently with subdirectories. Continue?")) { new DeleteJob("Delete Files", elements).schedule(); } } } public class DeleteJob extends Job { Object[] elements; public DeleteJob(String name, Object[] elements) { super(name); this.elements = elements; } protected IStatus run(IProgressMonitor monitor) { TcpProxy tcp = TcpProxy.getTcpProxy(serverId); try { monitor.beginTask("Delete Server Files.....", IProgressMonitor.UNKNOWN); MapPack param = new MapPack(); ListValue fileLv = param.newList("file"); for (int i = 0; i < elements.length; i++) { if (elements[i] instanceof DirObject) { DirObject obj = (DirObject) elements[i]; fileLv.add(obj.name); } } MapPack m = (MapPack) tcp.getSingle(RequestCmd.SERVER_DB_DELETE, param); monitor.done(); int size = m.getInt("size"); ConsoleProxy.infoSafe(size + " directories is deleted."); load(); } catch (Exception e) { e.printStackTrace(); } finally { TcpProxy.putTcpProxy(tcp); } return Status.OK_STATUS; } } class DirObject { String name; long size; long lastModified; DirObject parent; List<DirObject> childList; public void addChild(DirObject child) { if (childList == null) { childList = new ArrayList<DirObject>(); } childList.add(child); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + getOuterType().hashCode(); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; DirObject other = (DirObject) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } private ServerFileManagementView getOuterType() { return ServerFileManagementView.this; } } class DirContentProvider implements ITreeContentProvider { public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } @SuppressWarnings("rawtypes") public Object[] getElements(Object inputElement) { if (inputElement instanceof Map) { return ((Map) inputElement).values().toArray(); } return new Object[0]; } public Object[] getChildren(Object parentElement) { if (parentElement instanceof DirObject) { if (((DirObject) parentElement).childList != null) { return ((DirObject) parentElement).childList.toArray(); } } return null; } public Object getParent(Object element) { if (element instanceof DirObject) { return ((DirObject) element).parent; } return null; } public boolean hasChildren(Object element) { if (element instanceof DirObject) { return ((DirObject) element).childList != null; } return false; } } class LockLabelProvider implements ITableLabelProvider { public void addListener(ILabelProviderListener listener) { } public void dispose() { } public boolean isLabelProperty(Object element, String property) { return false; } public void removeListener(ILabelProviderListener listener) { } public Image getColumnImage(Object element, int columnIndex) { if (columnIndex == 0 && element instanceof DirObject) { return Images.folder; } return null; } public String getColumnText(Object element, int columnIndex) { if (element instanceof DirObject) { DirObject obj = (DirObject) element; switch (columnIndex) { case 0: int lastIndex = obj.name.lastIndexOf("/"); if (lastIndex < 0) { lastIndex = obj.name.lastIndexOf("\\"); } if (lastIndex > -1) { return obj.name.substring(lastIndex + 1); } else { return obj.name; } case 1: return ScouterUtil.humanReadableByteCount(obj.size, true); case 2: return DateUtil.format(obj.lastModified, "yyyy-MM-dd HH:mm:ss"); } } return null; } } }