/******************************************************************************* * Copyright (c) 2015, 2016 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.boot.dash.views; import static org.springsource.ide.eclipse.commons.ui.UiUtil.openUrl; import java.util.List; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.TableColumn; import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; import org.springframework.ide.eclipse.boot.dash.model.BootDashModel.ElementStateListener; import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; import org.springframework.ide.eclipse.boot.dash.model.requestmappings.RequestMapping; import org.springframework.ide.eclipse.boot.dash.util.Utils; import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; import org.springsource.ide.eclipse.commons.livexp.core.UIValueListener; import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; import org.springsource.ide.eclipse.commons.livexp.ui.Disposable; import org.springsource.ide.eclipse.commons.livexp.ui.IPageWithSections; import org.springsource.ide.eclipse.commons.livexp.ui.PageSection; import org.springsource.ide.eclipse.commons.livexp.ui.Stylers; import org.springsource.ide.eclipse.commons.livexp.ui.util.ReflowUtil; /** * @author Kris De Volder */ public class RequestMappingsSection extends PageSection implements Disposable { private static final Object[] NO_ELEMENTS = new Object[0]; private LiveExpression<BootDashElement> input; private Composite page; private TableViewer tv; private BootDashViewModel model; private ElementStateListener modelListener; private RequestMappingLabelProvider labelProvider; private Stylers stylers; private ViewerSorter sorter = new ViewerSorter() { @Override public int compare(Viewer viewer, Object e1, Object e2) { if (e1 instanceof RequestMapping && e2 instanceof RequestMapping) { RequestMapping rm1 = (RequestMapping) e1; RequestMapping rm2 = (RequestMapping) e2; int cat1 = getCategory(rm1); int cat2 = getCategory(rm2); if (cat1!=cat2) { return cat1-cat2; } else { return rm1.getPath().compareTo(rm2.getPath()); } } return 0; } private int getCategory(RequestMapping rm) { if (rm.isUserDefined()) { return 0; } else { return 1; } } }; public RequestMappingsSection(IPageWithSections owner, BootDashViewModel model, LiveExpression<BootDashElement> selection) { super(owner); this.model = model; this.input = selection; } @Override public LiveExpression<ValidationResult> getValidator() { return OK_VALIDATOR; } @Override public void createContents(final Composite page) { this.page = page; this.tv = new TableViewer(page, SWT.BORDER|SWT.FULL_SELECTION|SWT.V_SCROLL); tv.setContentProvider(new ContentProvider()); tv.setSorter(sorter); // tv.setLabelProvider(labelProvider = new RequestMappingLabelProvider(tv.getTable().getFont(), input)); tv.setInput(model); tv.getTable().setHeaderVisible(true); stylers = new Stylers(tv.getTable().getFont()); for (RequestMappingsColumn colType : RequestMappingsColumn.values()) { TableViewerColumn col = new TableViewerColumn(tv, colType.getAlignment()); col.setLabelProvider(new RequestMappingLabelProvider(stylers, input, colType)); TableColumn colWidget = col.getColumn(); colWidget.setText(colType.getLabel()); colWidget.setWidth(colType.getDefaultWidth()); } GridDataFactory.fillDefaults().grab(true, true).applyTo(tv.getTable()); this.input.addListener(new UIValueListener<BootDashElement>() { public void uiGotValue(LiveExpression<BootDashElement> exp, BootDashElement value) { if (!tv.getControl().isDisposed()) { tv.setInput(value); } } }); tv.getTable().addControlListener(new ControlListener() { public void controlResized(ControlEvent e) { ReflowUtil.reflow(owner, tv.getControl()); } @Override public void controlMoved(ControlEvent e) { } }); tv.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { IStructuredSelection sel = (IStructuredSelection) event.getSelection(); Object clicked = sel.getFirstElement(); if(clicked instanceof RequestMapping){ RequestMapping rm = (RequestMapping) clicked; BootDashElement el = input.getValue(); String url = Utils.createUrl(el.getLiveHost(), el.getLivePort(), rm.getPath()); if (url!=null) { openUrl(url); } // MessageDialog.openInformation(page.getShell(), "clickety click!", // "Double-click on : "+ clicked); } } }); model.addElementStateListener(modelListener = new ElementStateListener() { public void stateChanged(BootDashElement e) { if (e.equals(input.getValue())) { if (!tv.getControl().isDisposed()) { tv.getControl().getDisplay().asyncExec(new Runnable() { public void run() { if (!tv.getControl().isDisposed()) { tv.refresh(); page.layout(new Control[] {tv.getControl()}); } } }); } } } }); } public class ContentProvider implements IStructuredContentProvider { @Override public void dispose() { } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { tv.refresh(); tv.getControl().getDisplay().asyncExec(new Runnable() { public void run() { if (!page.isDisposed()) { page.layout(new Control[] {tv.getControl()}); } } }); } @Override public Object[] getElements(Object inputElement) { if (inputElement instanceof BootDashElement) { BootDashElement el = (BootDashElement) inputElement; List<RequestMapping> elements = el.getLiveRequestMappings(); if (elements!=null) { return elements.toArray(); } else { //null means we couldn't determine the request mappings. return new Object[] { "'"+el.getName()+"' must be running...", "and the actuator 'mappings' ...", "endpoint must be enabled ...", "to obtain request mappings.", }; } } return NO_ELEMENTS; } } @Override public void dispose() { if (modelListener!=null) { model.removeElementStateListener(modelListener); modelListener = null; } if (labelProvider!=null) { labelProvider.dispose(); labelProvider = null; } if (stylers!=null) { stylers.dispose(); stylers = null; } } }