| /******************************************************************************* |
| * Copyright (c) 2010, 2017 THALES GLOBAL SERVICES and others. |
| * 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: |
| * Obeo - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.sirius.ui.debug; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Optional; |
| import java.util.Set; |
| |
| import org.eclipse.core.commands.operations.IOperationHistory; |
| import org.eclipse.core.commands.operations.IUndoContext; |
| import org.eclipse.core.commands.operations.IUndoableOperation; |
| import org.eclipse.core.commands.operations.OperationHistoryFactory; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.SubMonitor; |
| import org.eclipse.draw2d.Bendpoint; |
| import org.eclipse.draw2d.Connection; |
| import org.eclipse.draw2d.ConnectionAnchor; |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.emf.common.notify.Adapter; |
| import org.eclipse.emf.common.notify.Notifier; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EAttribute; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.InternalEObject; |
| import org.eclipse.emf.ecore.resource.ContentHandler; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.URIConverter; |
| import org.eclipse.emf.ecore.resource.URIHandler; |
| import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl; |
| import org.eclipse.emf.ecore.resource.impl.FileURIHandlerImpl; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; |
| import org.eclipse.emf.transaction.RecordingCommand; |
| import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| import org.eclipse.emf.transaction.util.TransactionUtil; |
| import org.eclipse.emf.workspace.IWorkspaceCommandStack; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeEditPart; |
| import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx; |
| import org.eclipse.gmf.runtime.gef.ui.figures.SlidableAnchor; |
| import org.eclipse.gmf.runtime.notation.Bounds; |
| import org.eclipse.gmf.runtime.notation.Edge; |
| import org.eclipse.gmf.runtime.notation.IdentityAnchor; |
| import org.eclipse.gmf.runtime.notation.LayoutConstraint; |
| import org.eclipse.gmf.runtime.notation.Location; |
| import org.eclipse.gmf.runtime.notation.Node; |
| import org.eclipse.gmf.runtime.notation.RelativeBendpoints; |
| import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint; |
| import org.eclipse.jface.dialogs.ProgressMonitorDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.sirius.business.api.session.Session; |
| import org.eclipse.sirius.business.api.session.SessionManager; |
| import org.eclipse.sirius.business.internal.movida.ViewpointSelection; |
| import org.eclipse.sirius.business.internal.movida.registry.ViewpointRegistry; |
| import org.eclipse.sirius.business.internal.movida.registry.ViewpointRegistryListener; |
| import org.eclipse.sirius.business.internal.session.danalysis.DAnalysisSessionImpl; |
| import org.eclipse.sirius.diagram.AbsoluteBoundsFilter; |
| import org.eclipse.sirius.diagram.DDiagramElement; |
| import org.eclipse.sirius.diagram.DEdge; |
| import org.eclipse.sirius.diagram.EdgeTarget; |
| import org.eclipse.sirius.diagram.sequence.SequenceDDiagram; |
| import org.eclipse.sirius.diagram.sequence.business.internal.VerticalPositionFunction; |
| import org.eclipse.sirius.diagram.sequence.business.internal.elements.ISequenceElement; |
| import org.eclipse.sirius.diagram.sequence.business.internal.elements.ISequenceElementAccessor; |
| import org.eclipse.sirius.diagram.sequence.business.internal.elements.ISequenceEvent; |
| import org.eclipse.sirius.diagram.sequence.business.internal.elements.Lifeline; |
| import org.eclipse.sirius.diagram.sequence.business.internal.operation.VerticalSpaceExpansion; |
| import org.eclipse.sirius.diagram.sequence.ordering.EventEnd; |
| import org.eclipse.sirius.diagram.sequence.ui.tool.api.SequenceDiagramLayout; |
| import org.eclipse.sirius.diagram.sequence.ui.tool.internal.edit.part.ISequenceEventEditPart; |
| import org.eclipse.sirius.diagram.sequence.ui.tool.internal.edit.part.InstanceRoleEditPart; |
| import org.eclipse.sirius.diagram.sequence.ui.tool.internal.edit.part.LifelineEditPart; |
| import org.eclipse.sirius.diagram.sequence.ui.tool.internal.edit.part.SequenceDiagramEditPart; |
| import org.eclipse.sirius.diagram.sequence.ui.tool.internal.edit.part.SequenceMessageEditPart; |
| import org.eclipse.sirius.diagram.sequence.util.Range; |
| import org.eclipse.sirius.diagram.ui.business.api.query.ViewQuery; |
| import org.eclipse.sirius.diagram.ui.business.internal.query.EdgeTargetQuery; |
| import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramContainerEditPart; |
| import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramElementContainerEditPart; |
| import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramNameEditPart; |
| import org.eclipse.sirius.diagram.ui.edit.api.part.IAbstractDiagramNodeEditPart; |
| import org.eclipse.sirius.diagram.ui.edit.api.part.IDiagramEdgeEditPart; |
| import org.eclipse.sirius.diagram.ui.edit.api.part.IDiagramElementEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.edit.parts.DDiagramEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.edit.parts.DEdgeBeginNameEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.edit.parts.DEdgeEndNameEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.edit.parts.DEdgeNameEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.refresh.GMFHelper; |
| import org.eclipse.sirius.diagram.ui.part.SiriusVisualIDRegistry; |
| import org.eclipse.sirius.diagram.ui.tools.internal.commands.ToggleFoldingStateCommand; |
| import org.eclipse.sirius.diagram.ui.tools.internal.edit.command.CommandFactory; |
| import org.eclipse.sirius.editor.tools.internal.presentation.ViewpoitnDependenciesSelectionDialog; |
| import org.eclipse.sirius.ext.base.Option; |
| import org.eclipse.sirius.ext.emf.AllContents; |
| import org.eclipse.sirius.tests.sample.component.Component; |
| import org.eclipse.sirius.tests.sample.component.util.PayloadMarkerAdapter; |
| import org.eclipse.sirius.tests.sample.component.util.PayloadMarkerAdapter.FeatureAccess; |
| import org.eclipse.sirius.ui.business.api.viewpoint.ViewpointSelectionDialog; |
| import org.eclipse.sirius.ui.debug.ResourceSetTopologyAnalyzer.Reference; |
| import org.eclipse.sirius.viewpoint.DRepresentationDescriptor; |
| import org.eclipse.sirius.viewpoint.DRepresentationElement; |
| import org.eclipse.sirius.viewpoint.DSemanticDecorator; |
| import org.eclipse.sirius.viewpoint.description.DescriptionPackage; |
| import org.eclipse.sirius.viewpoint.description.Viewpoint; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.widgets.FileDialog; |
| import org.eclipse.team.internal.core.streams.ProgressMonitorInputStream; |
| |
| import com.google.common.base.Functions; |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Maps; |
| import com.google.common.collect.Multimap; |
| import com.google.common.collect.Multiset; |
| import com.google.common.collect.Ordering; |
| |
| /** |
| * A simple view synchronized with the Eclipse selection, used to show arbitrary computed information from the currently |
| * selected edit part of a diagram and launch actions on them. This view is targeted to developers to help debugging, it |
| * should not be packaged in the final product and should not be available to end users. |
| * |
| * @author pcdavid |
| */ |
| @SuppressWarnings({ "restriction", "unused" }) |
| public class SiriusDebugView extends AbstractDebugView { |
| /** |
| * The global ID for the Eclipse View. |
| */ |
| public static final String ID = "org.eclipse.sirius.ui.debug.DebugView"; |
| |
| /** |
| * Memento used by the Store Positions/Show position changes actions. |
| */ |
| protected Map<EObject, Integer> storedPositions; |
| |
| protected ViewpointRegistry registry; |
| |
| /** |
| * Returns the text to show in the main text area for the specified object. |
| */ |
| @Override |
| protected String getTextFor(Object obj) { |
| if (obj instanceof IDiagramElementEditPart) { |
| return getTextFor((IDiagramElementEditPart) obj); |
| } else if (obj instanceof DDiagramEditPart) { |
| return getTextForDiagram((DDiagramEditPart) obj); |
| } else if (obj instanceof ConnectionEditPart) { |
| return getTextForConnection((ConnectionEditPart) obj); |
| } else if (getRepresentationDescriptor(obj) != null) { |
| return obj + "\n\n" + getTextForRepDescriptor(getRepresentationDescriptor(obj)); |
| } else { |
| return "Selection type not supported: " + obj; |
| } |
| } |
| |
| private DRepresentationDescriptor getRepresentationDescriptor(Object obj) { |
| DRepresentationDescriptor repDesc = null; |
| if (obj instanceof DRepresentationDescriptor) { |
| repDesc = (DRepresentationDescriptor) obj; |
| } else if (obj instanceof IAdaptable) { |
| EObject repDescObj = ((IAdaptable) obj).getAdapter(EObject.class); |
| if (repDescObj instanceof DRepresentationDescriptor) { |
| repDesc = (DRepresentationDescriptor) repDescObj; |
| } |
| } |
| return repDesc; |
| } |
| |
| private String getTextForRepDescriptor(DRepresentationDescriptor repDesc) { |
| StringBuilder sb = new StringBuilder(); |
| sb.append(repDesc + "\n"); |
| sb.append("isLoadedRepresentation : " + repDesc.isLoadedRepresentation()); |
| return sb.toString(); |
| } |
| |
| private String getTextForDiagram(DDiagramEditPart sdep) { |
| StringBuilder sb = new StringBuilder(); |
| sb.append(getCurrentEObject() + "\n"); |
| sb.append("Direct diagram children:\n"); |
| for (IGraphicalEditPart child : Iterables.filter(sdep.getChildren(), IGraphicalEditPart.class)) { |
| sb.append("- " + toString(child)); |
| sb.append("\n - sources: "); |
| for (IGraphicalEditPart sourceConn : Iterables.filter(child.getSourceConnections(), IGraphicalEditPart.class)) { |
| sb.append("\n ").append(toString(sourceConn)); |
| } |
| sb.append("\n - targets: "); |
| for (IGraphicalEditPart targetConn : Iterables.filter(child.getTargetConnections(), IGraphicalEditPart.class)) { |
| sb.append("\n ").append(toString(targetConn)); |
| } |
| sb.append("\n"); |
| } |
| return sb.toString(); |
| } |
| |
| private String toString(IGraphicalEditPart part) { |
| return String.valueOf(part).replace("org.eclipse.gmf.runtime.notation.impl.", "") + " #" + Long.toHexString(part.hashCode()); |
| } |
| |
| private String getTextFor(IDiagramElementEditPart part) { |
| StringBuilder sb = new StringBuilder(); |
| if (part instanceof ShapeEditPart) { |
| appendSequenceEventInfo(part, sb); |
| appendBoundsDetails(part, sb); |
| |
| if (part instanceof AbstractDiagramContainerEditPart && ((AbstractDiagramContainerEditPart) part).isRegionContainer()) { |
| IGraphicalEditPart compartment = null; |
| for (IGraphicalEditPart child : Iterables.filter(part.getChildren(), IGraphicalEditPart.class)) { |
| sb.append("Children bounds:\n"); |
| appendBoundsDetails(child, sb); |
| compartment = child; |
| } |
| |
| for (IGraphicalEditPart child2 : Iterables.filter(compartment.getChildren(), IGraphicalEditPart.class)) { |
| sb.append("Region bounds:\n"); |
| appendBoundsDetails(child2, sb); |
| } |
| } else if (part instanceof AbstractDiagramElementContainerEditPart && ((AbstractDiagramElementContainerEditPart) part).isRegion()) { |
| IGraphicalEditPart parent = (IGraphicalEditPart) part.getParent(); |
| sb.append("Compartment bounds:\n"); |
| appendBoundsDetails(parent, sb); |
| parent = (IGraphicalEditPart) parent.getParent(); |
| sb.append("Region Container bounds:\n"); |
| appendBoundsDetails(parent, sb); |
| } else if (part instanceof InstanceRoleEditPart) { |
| LifelineEditPart lep = Iterables.filter(part.getChildren(), LifelineEditPart.class).iterator().next(); |
| appendSequenceEventInfo(lep, sb); |
| } |
| } else if (part instanceof ConnectionEditPart) { |
| ConnectionEditPart conn = (ConnectionEditPart) part; |
| sb.append(getTextForConnection(conn)); |
| } else if (part instanceof AbstractDiagramNameEditPart) { |
| appendBoundsDetails(part, sb); |
| } else { |
| sb.append("unknown"); |
| } |
| return sb.toString(); |
| } |
| |
| private void appendBoundsDetails(IGraphicalEditPart part, StringBuilder sb) { |
| Node node = (Node) part.getNotationView(); |
| LayoutConstraint layoutConstraint = node.getLayoutConstraint(); |
| if (layoutConstraint instanceof Bounds) { |
| Bounds bounds = (Bounds) layoutConstraint; |
| sb.append("Bounds (GMF): Rectangle(" + bounds.getX() + ", " + bounds.getY() + ", " + bounds.getWidth() + ", " + bounds.getHeight() + ")\n"); |
| } else if (layoutConstraint instanceof Location) { |
| Location location = (Location) layoutConstraint; |
| sb.append("Location (GMF): Location(" + location.getX() + ", " + location.getY() + ")\n"); |
| } |
| |
| Rectangle absoluteBounds = GMFHelper.getAbsoluteBounds(node, true); |
| sb.append("Bounds (GMF absolute - insets): " + absoluteBounds + "\n"); |
| |
| absoluteBounds = GMFHelper.getAbsoluteBounds(node, false); |
| sb.append("Bounds (GMF absolute - no insets): " + absoluteBounds + "\n"); |
| |
| Option<ISequenceElement> elt = ISequenceElementAccessor.getISequenceElement(part.getNotationView()); |
| if (elt.some()) { |
| sb.append("Bounds (logical): " + elt.get().getProperLogicalBounds()).append("\n"); |
| } |
| Rectangle bounds = part.getFigure().getBounds().getCopy(); |
| sb.append("Bounds (Draw2D): " + bounds.toString() + " --> center: " + bounds.getCenter() + "\n"); |
| part.getFigure().translateToAbsolute(bounds); |
| sb.append("Bounds (Draw2D absolute): " + bounds.toString() + " --> center: " + bounds.getCenter() + "\n"); |
| sb.append("\n"); |
| } |
| |
| private String getTextForConnection(ConnectionEditPart conn) { |
| Edge edge = (Edge) conn.getNotationView(); |
| StringBuilder sb = new StringBuilder(); |
| |
| if (conn instanceof IDiagramElementEditPart) { |
| appendSequenceEventInfo((IDiagramElementEditPart) conn, sb); |
| } |
| |
| if (conn instanceof IDiagramEdgeEditPart) { |
| PolylineConnectionEx polyline = ((IDiagramEdgeEditPart) conn).getPolylineConnectionFigure(); |
| sb.append("Line width = " + polyline.getLineWidth() + " (float: " + polyline.getLineWidthFloat() + ")\n"); |
| } |
| |
| sb.append("GMF Notation (Edge):\n"); |
| |
| Point srcAnchorLoc = appendAnchorDetails(conn, (IdentityAnchor) edge.getSourceAnchor(), ((Connection) conn.getFigure()).getSourceAnchor(), " . sourceAnchor", sb); |
| Point tgtAnchorLoc = appendAnchorDetails(conn, (IdentityAnchor) edge.getTargetAnchor(), ((Connection) conn.getFigure()).getTargetAnchor(), " . targetAnchor", sb); |
| appendRelativeBenpointsDetails(edge, conn, sb); |
| |
| sb.append("\nDraw2D Connection:\n"); |
| Connection connFigure = conn.getConnectionFigure(); |
| |
| sb.append(" . routing constraint:\n"); |
| @SuppressWarnings("unchecked") |
| List<Bendpoint> bendpoints = (List<Bendpoint>) connFigure.getRoutingConstraint(); |
| if (bendpoints != null) { |
| for (int i = 0; i < bendpoints.size(); i++) { |
| Point location = bendpoints.get(i).getLocation(); |
| sb.append(" " + i + ":"); |
| sb.append(location); |
| sb.append("\n"); |
| } |
| } |
| |
| sb.append(" . sourceAnchor: "); |
| if (connFigure.getSourceAnchor() instanceof SlidableAnchor) { |
| sb.append(((SlidableAnchor) connFigure.getSourceAnchor()).getTerminal() + " ==> "); |
| } |
| sb.append(connFigure.getSourceAnchor().getReferencePoint()).append("\n"); |
| sb.append(" . targetAnchor: "); |
| if (connFigure.getTargetAnchor() instanceof SlidableAnchor) { |
| sb.append(((SlidableAnchor) connFigure.getTargetAnchor()).getTerminal() + " ==> "); |
| } |
| sb.append(connFigure.getTargetAnchor().getReferencePoint()).append("\n"); |
| |
| sb.append(" . points:\n"); |
| for (int i = 0; i < connFigure.getPoints().size(); i++) { |
| sb.append(" " + i + ": " + connFigure.getPoints().getPoint(i).toString()).append("\n"); |
| } |
| |
| appendGMFEdgeLabels(edge, sb); |
| return sb.toString(); |
| } |
| |
| private void appendGMFEdgeLabels(Edge edge, StringBuilder sb) { |
| sb.append("\nLabels of edge:\n"); |
| for (Object child : edge.getChildren()) { |
| if (child instanceof Node) { |
| Node node = (Node) child; |
| if (new ViewQuery(node).isForEdgeNameEditPart() && node.getLayoutConstraint() instanceof Location) { |
| Location location = (Location) (node).getLayoutConstraint(); |
| int type = SiriusVisualIDRegistry.getVisualID(node.getType()); |
| if (type == DEdgeBeginNameEditPart.VISUAL_ID) { |
| appendLabelLocation(sb, "Begin label", ((DEdge) node.getElement()).getBeginLabel(), location); |
| } else if (type == DEdgeNameEditPart.VISUAL_ID) { |
| appendLabelLocation(sb, "Center label", ((DEdge) node.getElement()).getName(), location); |
| } else if (type == DEdgeEndNameEditPart.VISUAL_ID) { |
| appendLabelLocation(sb, "End label", ((DEdge) node.getElement()).getEndLabel(), location); |
| } |
| } |
| } |
| } |
| } |
| |
| private void appendLabelLocation(StringBuilder sb, String labelKind, String labelName, Location location) { |
| sb.append("\n").append(labelKind).append(": ").append(labelName).append(", "); |
| sb.append(" (x: "); |
| sb.append(location.getX()); |
| sb.append(", y: "); |
| sb.append(location.getY()); |
| sb.append(')'); |
| } |
| |
| private void appendSequenceEventInfo(IDiagramElementEditPart part, StringBuilder sb) { |
| if (part instanceof ISequenceEventEditPart) { |
| ISequenceEvent iSequenceEvent = ((ISequenceEventEditPart) part).getISequenceEvent(); |
| Range range = iSequenceEvent.getVerticalRange(); |
| sb.append("Range: " + range.toString() + " (height = " + range.width() + ")\n"); |
| |
| Rectangle properLogicalBounds = iSequenceEvent.getProperLogicalBounds(); |
| sb.append("Absolute Bounds: " + properLogicalBounds + ")\n"); |
| |
| DDiagramElement dde = (DDiagramElement) iSequenceEvent.getNotationView().getElement(); |
| |
| if (!Lifeline.viewpointElementPredicate().apply(dde) && !Iterables.isEmpty(Iterables.filter(dde.getGraphicalFilters(), AbsoluteBoundsFilter.class))) { |
| AbsoluteBoundsFilter flag = Iterables.getOnlyElement(Iterables.filter(dde.getGraphicalFilters(), AbsoluteBoundsFilter.class)); |
| sb.append("Bounds flag: (" + flag.getX() + ", " + flag.getY() + ", " + flag.getWidth() + ", " + flag.getHeight() + ")\n\n"); |
| } |
| } |
| } |
| |
| private void appendRelativeBenpointsDetails(Edge edge, ConnectionEditPart conn, StringBuilder sb) { |
| sb.append(" . bendpoints ="); |
| StringBuilder fromSourceSB = new StringBuilder(); |
| List<Point> pointsFromSource = GMFHelper.getPointsFromSource(conn); |
| for (Point point : pointsFromSource) { |
| fromSourceSB.append(point); |
| fromSourceSB.append(" "); |
| } |
| StringBuilder fromTargetSB = new StringBuilder(); |
| List<Point> pointsFromTarget = GMFHelper.getPointsFromTarget(conn); |
| for (Point point : pointsFromTarget) { |
| fromTargetSB.append(point); |
| fromTargetSB.append(" "); |
| } |
| if (fromSourceSB.toString().equals(fromTargetSB.toString())) { |
| sb.append("\n . Computed points: "); |
| sb.append(fromSourceSB); |
| } else { |
| sb.append(" **** WARNING: points computed from source != points computed from target ****"); |
| sb.append("\n . Points computed from source: "); |
| sb.append(fromSourceSB); |
| sb.append("\n . Points computed from target: "); |
| sb.append(fromTargetSB); |
| } |
| appendRelativeBenpointsDetails(edge, sb); |
| } |
| |
| private void appendRelativeBenpointsDetails(Edge edge, StringBuilder sb) { |
| sb.append("\n . Source vectors: "); |
| RelativeBendpoints bp = (RelativeBendpoints) edge.getBendpoints(); |
| for (int i = 0; i < bp.getPoints().size(); i++) { |
| RelativeBendpoint rbp = (RelativeBendpoint) bp.getPoints().get(i); |
| sb.append("[" + rbp.getSourceX() + ", " + rbp.getSourceY() + "] "); |
| } |
| sb.append("\n . Target vectors: "); |
| for (int i = 0; i < bp.getPoints().size(); i++) { |
| RelativeBendpoint rbp = (RelativeBendpoint) bp.getPoints().get(i); |
| sb.append("[" + rbp.getTargetX() + ", " + rbp.getTargetY() + "] "); |
| } |
| } |
| |
| private Point appendAnchorDetails(ConnectionEditPart origin, IdentityAnchor anchor, ConnectionAnchor connectionAnchor, String name, StringBuilder sb) { |
| sb.append(name).append(" = "); |
| if (anchor != null) { |
| sb.append(anchor.getId()); |
| } else { |
| sb.append("null "); |
| } |
| Point location = connectionAnchor.getReferencePoint(); |
| origin.getFigure().translateToRelative(location); |
| sb.append(" => ").append(location).append("\n"); |
| return location; |
| } |
| |
| /** |
| * Creates the actions available to users. |
| */ |
| @Override |
| protected void createActionButtons() { |
| // addFoldingToggleAction(); |
| // addShowOrderingsAction(); |
| // addStorePositionsAction(); |
| // addShowPositionChangesAction(); |
| addShowFiguresHierarchyAction(); |
| addShowEditPartsHierarchyAction(); |
| // addRefreshBenpointsAction(); |
| // addResetBendpointsAction(); |
| // addExpandAction(); |
| // addRefreshCoverageAction(); |
| // addRefreshDiagramAction(); |
| // addStartMovidaRegistryAction(); |
| // addShowMovidaRegistryStatusAction(); |
| // addSelectReusedSiriussAction(); |
| // addShowCommandStackAction(); |
| // addSiriusSelectionAction(); |
| // addExtractExpressionsAction(); |
| // addLoadResourceWithProgressAction(); |
| addShowPayloadAccessLogAction(); |
| addClearPayloadAccessLogAction(); |
| addShowResourceSetTopologyAction(); |
| addShowAdaptersAction(); |
| addShowSessionStructureAction(); |
| // addShowCrossReferencerMap(); |
| } |
| |
| private void addShowSessionStructureAction() { |
| addAction("Show session structure", new Runnable() { |
| @Override |
| public void run() { |
| EObject current = getCurrentEObject(); |
| if (current != null) { |
| Session s = SessionManager.INSTANCE.getSession(current); |
| if (s instanceof DAnalysisSessionImpl) { |
| setText(getStructure(((DAnalysisSessionImpl) s))); |
| } else if (s == null && current instanceof DSemanticDecorator) { |
| s = SessionManager.INSTANCE.getSession(((DSemanticDecorator) current).getTarget()); |
| if (s instanceof DAnalysisSessionImpl) { |
| setText(getStructure(((DAnalysisSessionImpl) s))); |
| } |
| } |
| } |
| } |
| |
| private String getStructure(DAnalysisSessionImpl session) { |
| StringBuilder sb = new StringBuilder(); |
| sb.append("DAnalysisSessionEObject references:\n"); |
| for (EStructuralFeature esf : session.eClass().getEAllStructuralFeatures()) { |
| sb.append("* ").append(esf.getName()).append(":\n"); |
| appendValue(session, esf, sb); |
| } |
| sb.append("* ").append("srm resources:\n"); |
| int count = 0; |
| for (Resource res : session.getSrmResources()) { |
| count++; |
| sb.append(" ").append(count).append(". ").append(res.getURI()).append("\n"); |
| } |
| |
| return sb.toString(); |
| } |
| |
| private void appendValue(EObject obj, EStructuralFeature esf, StringBuilder sb) { |
| Object value = obj.eGet(esf); |
| if (esf.isMany()) { |
| EList<?> values = (EList<?>) value; |
| for (int i = 0; i < values.size(); i++) { |
| Object v = values.get(i); |
| sb.append(" ").append(i + 1).append(". ").append(v instanceof EObject ? toString((EObject) v) : String.valueOf(v)).append("\n"); |
| } |
| } else { |
| sb.append(" - ").append(value instanceof EObject ? toString((EObject) value) : String.valueOf(value)).append("\n"); |
| } |
| } |
| |
| private String toString(EObject obj) { |
| if (obj == null) { |
| return null; |
| } else if (obj.eIsProxy()) { |
| return ((InternalEObject) obj).eProxyURI().toString(); |
| } else { |
| return obj.getClass().getName() + "@" + Integer.toHexString(obj.hashCode()); |
| } |
| } |
| }); |
| } |
| |
| private void addShowPayloadAccessLogAction() { |
| addAction("Show Payload Access Log", new Runnable() { |
| @Override |
| public void run() { |
| int max = 50; |
| List<FeatureAccess> log = PayloadMarkerAdapter.INSTANCE.getAccessLog(); |
| int totalSize = log.size(); |
| int shown = Math.min(totalSize, max); |
| TabularReport tr = new TabularReport(/* "Timestamp", */"EObject", "Feature"); |
| |
| try { |
| PayloadMarkerAdapter.INSTANCE.setEnable(false); |
| for (int i = log.size() > max ? log.size() - max : 0; i < log.size(); i++) { |
| FeatureAccess featureAccess = log.get(i); |
| tr.addLine(Arrays.asList(/* |
| * String.format("%tT", featureAccess.timestamp), |
| */((Component) featureAccess.setting.getEObject()).getName(), featureAccess.setting.getEStructuralFeature().getName())); |
| } |
| } finally { |
| PayloadMarkerAdapter.INSTANCE.setEnable(true); |
| } |
| StringBuilder sb = new StringBuilder(); |
| sb.append("Showing " + shown + " of " + totalSize + " accesses.\n"); |
| Multiset<String> contexts = PayloadMarkerAdapter.INSTANCE.getUniqueContexts(); |
| sb.append("Unique contexts: " + contexts.elementSet().size()).append("\n\n"); |
| |
| int i = 0; |
| for (String stack : contexts.elementSet()) { |
| int count = contexts.count(stack); |
| sb.append("Context #" + i++ + " (" + count + " occurrences)").append("\n"); |
| sb.append(stack).append("\n"); |
| } |
| |
| sb.append("\n").append(tr.print()).append("\n"); |
| setText(sb.toString()); |
| } |
| }); |
| } |
| |
| private void addClearPayloadAccessLogAction() { |
| addAction("Clear Payload Access Log", new Runnable() { |
| @Override |
| public void run() { |
| PayloadMarkerAdapter.INSTANCE.clearAccessLog(); |
| } |
| }); |
| } |
| |
| private void addShowAdaptersAction() { |
| addAction("Show adapters", new Runnable() { |
| @Override |
| public void run() { |
| StringBuilder sb = new StringBuilder(); |
| EObject current = getCurrentEObject(); |
| if (current != null) { |
| sb.append("Selected element:\n"); |
| appendAdapters(sb, current); |
| if (current instanceof DSemanticDecorator) { |
| sb.append("\nDSemanticDecorator.target:\n"); |
| appendAdapters(sb, ((DSemanticDecorator) current).getTarget()); |
| } |
| if (current instanceof DRepresentationElement) { |
| sb.append("\nDRepresentationElement.semanticElements:\n"); |
| for (EObject o : ((DRepresentationElement) current).getSemanticElements()) { |
| if (o != null) { |
| appendAdapters(sb, o); |
| } |
| } |
| } |
| if (current.eResource() != null) { |
| Resource r = current.eResource(); |
| sb.append("\nAdapters on Resource " + r.getURI().toString()).append(":\n"); |
| appendAdapters2(sb, r); |
| if (r.getResourceSet() != null) { |
| ResourceSet rs = r.getResourceSet(); |
| sb.append("\nAdapters on ResourceSet:\n"); |
| appendAdapters2(sb, rs); |
| } |
| } |
| } |
| setText(sb.toString()); |
| } |
| |
| private void appendAdapters(StringBuilder sb, EObject current) { |
| sb.append("Adapters on ").append(current.eClass().getName()).append("\n"); |
| appendAdapters2(sb, current); |
| } |
| |
| private void appendAdapters2(StringBuilder sb, Notifier current) { |
| EList<Adapter> adapters = current.eAdapters(); |
| for (int i = 0; i < adapters.size(); i++) { |
| Adapter adapter = adapters.get(i); |
| sb.append(i + 1).append(". ").append(adapter.getClass().getName()).append("@").append(Integer.toHexString(adapter.hashCode())).append("\n"); |
| } |
| } |
| }); |
| } |
| |
| private void addShowCrossReferencerMap() { |
| addAction("Show Cross Referencer Map", new ShowCrossReferencerMap(this)); |
| } |
| |
| EObject getCurrentEObject() { |
| if (selection instanceof IGraphicalEditPart) { |
| return ((IGraphicalEditPart) selection).resolveSemanticElement(); |
| } else if (selection instanceof EObject) { |
| return (EObject) selection; |
| } else { |
| return null; |
| } |
| } |
| |
| private void addShowResourceSetTopologyAction() { |
| addAction("Show ResourceSet Topology", new Runnable() { |
| @Override |
| public void run() { |
| for (Session s : SessionManager.INSTANCE.getSessions()) { |
| ResourceSetTopologyAnalyzer rsta = new ResourceSetTopologyAnalyzer(s.getTransactionalEditingDomain().getResourceSet()); |
| Multimap<EStructuralFeature, Reference> result = rsta.analyze(); |
| StringBuilder sb = new StringBuilder(); |
| sb.append("Found " + result.keys().size() + " distinct kinds of cross-resource references:\n"); |
| for (EStructuralFeature esf : result.keys()) { |
| sb.append("- "); |
| appendFeatureName(sb, esf); |
| sb.append("\n"); |
| for (Reference ref : result.get(esf)) { |
| sb.append(" - ").append(renderResource(ref.sourceResource)).append(" => ").append(renderResource(ref.targetResource)).append(" [" + ref.count + "]").append("\n"); |
| } |
| } |
| setText(sb.toString()); |
| } |
| } |
| |
| private final void appendFeatureName(StringBuilder out, EStructuralFeature esf) { |
| out.append(esf.getEContainingClass().getEPackage().getName()).append("::").append(esf.getEContainingClass().getName()).append(".").append(esf.getName()); |
| } |
| |
| private final String renderResource(Resource res) { |
| if (res == null) { |
| return "(no resource)"; |
| } else if (res.getURI() == null) { |
| return "(resource with no URI)"; |
| } else { |
| return res.getURI().toString(); |
| } |
| } |
| }); |
| } |
| |
| private void addLoadResourceWithProgressAction() { |
| addAction("Load with progress", new Runnable() { |
| @Override |
| public void run() { |
| FileDialog dia = new FileDialog(getSite().getShell(), SWT.OPEN); |
| dia.setFilterExtensions(new String[] { "*.ecore" }); |
| final String path = dia.open(); |
| final Resource[] result = new Resource[1]; |
| if (path != null) { |
| try { |
| IRunnableWithProgress op = new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| ResourceSet rs = new ResourceSetImpl(); |
| final SubMonitor loadingMonitor = SubMonitor.convert(monitor, (int) new File(path).length()); |
| List<URIHandler> handlers = Lists.newArrayList(URIHandler.DEFAULT_HANDLERS); |
| handlers.set(1, new FileURIHandlerImpl() { |
| @Override |
| public InputStream createInputStream(URI uri, Map<?, ?> options) throws IOException { |
| String filePath = uri.toFileString(); |
| File file = new File(filePath); |
| InputStream inputStream = new ProgressMonitorInputStream(new FileInputStream(file), file.length(), 1, loadingMonitor) { |
| private long previousRead = 0; |
| |
| @Override |
| protected void updateMonitor(long bytesRead, long size, IProgressMonitor monitor) { |
| long progress = bytesRead - previousRead; |
| while (progress > Integer.MAX_VALUE) { |
| loadingMonitor.worked(Integer.MAX_VALUE); |
| progress -= Integer.MAX_VALUE; |
| } |
| loadingMonitor.worked((int) progress); |
| previousRead = bytesRead; |
| } |
| }; |
| Map<Object, Object> response = getResponse(options); |
| if (response != null) { |
| response.put(URIConverter.RESPONSE_TIME_STAMP_PROPERTY, file.lastModified()); |
| } |
| return inputStream; |
| } |
| |
| }); |
| rs.setURIConverter(new ExtensibleURIConverterImpl(handlers, ContentHandler.Registry.INSTANCE.contentHandlers())); |
| result[0] = rs.getResource(URI.createFileURI(path), true); |
| } |
| }; |
| new ProgressMonitorDialog(getSite().getShell()).run(true, false, op); |
| } catch (InvocationTargetException e) { |
| // handle exception |
| } catch (InterruptedException e) { |
| // handle cancelation |
| } |
| if (result[0] != null) { |
| setText("Loaded resource " + result[0] + " with " + Iterables.size(AllContents.of(result[0].getContents().get(0))) + " elements."); |
| } else { |
| setText("Failed loading resource at " + path); |
| } |
| } |
| } |
| }); |
| } |
| |
| private void addExtractExpressionsAction() { |
| addAction("Extract Expressions", new Runnable() { |
| @Override |
| public void run() { |
| FileDialog dia = new FileDialog(getSite().getShell(), SWT.OPEN | SWT.MULTI); |
| dia.setFilterExtensions(new String[] { "*.odesign" }); |
| String path = dia.open(); |
| List<String[]> lines = Lists.newArrayList(); |
| if (path != null) { |
| for (String file : dia.getFileNames()) { |
| ResourceSet rs = new ResourceSetImpl(); |
| Resource vsm = rs.getResource(URI.createFileURI(dia.getFilterPath() + "/" + file), true); |
| for (EObject obj : AllContents.of(vsm.getContents().get(0))) { |
| EClass klass = obj.eClass(); |
| for (EAttribute attr : klass.getEAllAttributes()) { |
| if (attr.getEType() == DescriptionPackage.Literals.INTERPRETED_EXPRESSION) { |
| String value = Optional.ofNullable((String) obj.eGet(attr)).orElse("").trim(); |
| if (value.length() > 100) { |
| value = value.substring(0, 97) + "..."; |
| } |
| lines.add(new String[] { value, attr.getEContainingClass().getName() + "." + attr.getName() }); |
| } |
| } |
| } |
| } |
| } |
| StringBuilder result = new StringBuilder(); |
| for (String[] line : lines) { |
| result.append(line[0] + "\n"); |
| } |
| result.append("Total: " + lines.size() + " expressions"); |
| setText(result.toString()); |
| // Collections.sort(lines, new Comparator<String[]>() { |
| // public int compare(String[] o1, String[] o2) { |
| // return o1[0].compareTo(o2[0]); |
| // } |
| // }); |
| // TabularReport report = new TabularReport("Expression", |
| // "Feature"); |
| // for (String[] line : lines) { |
| // report.addLine(line[0], line[1]); |
| // } |
| // setText(report.print()); |
| } |
| }); |
| } |
| |
| private ViewpointSelection currentSelection = null; |
| |
| private void addSiriusSelectionAction() { |
| addAction("Sirius Selection", new Runnable() { |
| @Override |
| public void run() { |
| ViewpointRegistry reg = (ViewpointRegistry) org.eclipse.sirius.business.api.componentization.ViewpointRegistry.getInstance(); |
| if (currentSelection == null) { |
| currentSelection = new ViewpointSelection(reg); |
| } |
| ViewpointSelectionDialog dlg = new ViewpointSelectionDialog(getSite().getShell(), reg, currentSelection, null); |
| if (dlg.open() == Window.OK) { |
| // Do nothing here. |
| } |
| } |
| }); |
| } |
| |
| private void addShowCommandStackAction() { |
| addAction("Show CommandStack", new Runnable() { |
| @Override |
| public void run() { |
| IUndoContext undoContext = getUndoContext(selection); |
| if (undoContext != null) { |
| TabularReport report = new TabularReport("IUndoableOperation's name"); |
| IUndoableOperation[] redoableOperations = OperationHistoryFactory.getOperationHistory().getRedoHistory(undoContext); |
| if (redoableOperations != null) { |
| for (int i = redoableOperations.length - 1; i >= 0; i--) { |
| IUndoableOperation redoableOperation = redoableOperations[i]; |
| report.addLine(redoableOperation.getLabel()); |
| } |
| } |
| report.addLine("---------"); |
| IUndoableOperation[] undoableOperations = OperationHistoryFactory.getOperationHistory().getUndoHistory(undoContext); |
| if (undoableOperations != null) { |
| for (int i = undoableOperations.length - 1; i >= 0; i--) { |
| IUndoableOperation undoableOperation = undoableOperations[i]; |
| report.addLine(undoableOperation.getLabel()); |
| } |
| } |
| setText(report.print()); |
| } |
| } |
| |
| private IUndoContext getUndoContext(Object selection) { |
| IUndoContext undoContext = IOperationHistory.GLOBAL_UNDO_CONTEXT; |
| EObject eObject = null; |
| if (selection instanceof EObject) { |
| eObject = (EObject) selection; |
| } else if (selection instanceof IAdaptable) { |
| IAdaptable adaptable = (IAdaptable) selection; |
| eObject = adaptable.getAdapter(EObject.class); |
| } |
| if (eObject != null) { |
| TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(eObject); |
| if (domain == null && eObject instanceof Session) { |
| Session session = (Session) eObject; |
| domain = session.getTransactionalEditingDomain(); |
| } |
| if (domain != null && domain.getCommandStack() instanceof IWorkspaceCommandStack) { |
| IWorkspaceCommandStack workspaceCommandStack = (IWorkspaceCommandStack) domain.getCommandStack(); |
| undoContext = workspaceCommandStack.getDefaultUndoContext(); |
| } |
| } |
| return undoContext; |
| } |
| }); |
| } |
| |
| private void addSelectReusedSiriussAction() { |
| addAction("Select reused", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof Viewpoint) { |
| final Option<Set<URI>> sel = new ViewpoitnDependenciesSelectionDialog((Viewpoint) selection).selectReusedViewpoints(getSite().getShell()); |
| if (sel.some()) { |
| ((Viewpoint) selection).getReuses().clear(); |
| Iterables.addAll(((Viewpoint) selection).getReuses(), sel.get()); |
| } |
| } |
| } |
| }); |
| } |
| |
| private void addShowMovidaRegistryStatusAction() { |
| addAction("Show Registry Status", new Runnable() { |
| @Override |
| public void run() { |
| if (registry != null) { |
| StringBuilder status = new StringBuilder(); |
| registry.dumpStatus(status); |
| setText(status.toString()); |
| } |
| } |
| }); |
| } |
| |
| private void addStartMovidaRegistryAction() { |
| addAction("Start Registry", new Runnable() { |
| @Override |
| public void run() { |
| if (registry != null) { |
| registry.stop(); |
| } |
| registry = new ViewpointRegistry(); |
| registry.addListener(new ViewpointRegistryListener() { |
| @Override |
| public void registryChanged(ViewpointRegistry registry, Set<URI> removed, Set<URI> added, Set<URI> changed) { |
| System.out.println(); |
| System.out.println("Added:"); |
| for (URI a : added) { |
| System.out.println(" - " + a); |
| } |
| System.out.println("Removed:"); |
| for (URI r : removed) { |
| System.out.println(" - " + r); |
| } |
| System.out.println("Changed:"); |
| for (URI c : changed) { |
| System.out.println(" - " + c); |
| } |
| } |
| }); |
| registry.start(); |
| } |
| }); |
| } |
| |
| private void addRefreshDiagramAction() { |
| addAction("Refresh diagram", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof DiagramEditPart) { |
| final DiagramEditPart diag = (DiagramEditPart) selection; |
| diag.refresh(); |
| for (IGraphicalEditPart child : Iterables.filter(diag.getChildren(), IGraphicalEditPart.class)) { |
| child.refresh(); |
| } |
| } |
| } |
| }); |
| } |
| |
| private void addRefreshCoverageAction() { |
| addAction("Refresh coverage", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof SequenceDiagramEditPart) { |
| final SequenceDiagramEditPart sdep = (SequenceDiagramEditPart) selection; |
| TransactionalEditingDomain ted = sdep.getEditingDomain(); |
| RefreshGraphicalCoverage refreshGraphicalCoverage = new RefreshGraphicalCoverage(ted, sdep); |
| sdep.getEditingDomain().getCommandStack().execute(refreshGraphicalCoverage); |
| } |
| } |
| }); |
| } |
| |
| private void addExpandAction() { |
| addAction("Expand", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof SequenceDiagramEditPart) { |
| final int start = Integer.parseInt(askStringFromUser("Expansion", "Start y", "0")); |
| final int size = Integer.parseInt(askStringFromUser("Expansion", "Size", "0")); |
| final SequenceDiagramEditPart sdep = (SequenceDiagramEditPart) selection; |
| TransactionalEditingDomain ted = sdep.getEditingDomain(); |
| RecordingCommand verticalSpaceExpansion = CommandFactory.createRecordingCommand(ted, |
| new VerticalSpaceExpansion(sdep.getSequenceDiagram(), new Range(start, start + size), 0, Collections.<ISequenceEvent> emptyList())); |
| sdep.getEditingDomain().getCommandStack().execute(verticalSpaceExpansion); |
| } |
| } |
| }); |
| } |
| |
| private void addRefreshBenpointsAction() { |
| addAction("Refresh bendpoints", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof SequenceMessageEditPart) { |
| final SequenceMessageEditPart smep = (SequenceMessageEditPart) selection; |
| TransactionalEditingDomain ted = smep.getEditingDomain(); |
| RefreshBendpoints refreshBendpoints = new RefreshBendpoints(ted, smep); |
| smep.getEditingDomain().getCommandStack().execute(refreshBendpoints); |
| } else if (selection instanceof SequenceDiagramEditPart) { |
| for (final SequenceMessageEditPart smep : Iterables.filter(((SequenceDiagramEditPart) selection).getChildren(), SequenceMessageEditPart.class)) { |
| TransactionalEditingDomain ted = smep.getEditingDomain(); |
| RefreshBendpoints refreshBendpoints = new RefreshBendpoints(ted, smep); |
| smep.getEditingDomain().getCommandStack().execute(refreshBendpoints); |
| } |
| } |
| } |
| }); |
| |
| } |
| |
| private void addResetBendpointsAction() { |
| addAction("Reset bendpoints", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof SequenceDiagramEditPart) { |
| final SequenceDiagramEditPart sdep = (SequenceDiagramEditPart) selection; |
| TransactionalEditingDomain ted = sdep.getEditingDomain(); |
| RecordingCommand verticalSpaceExpansion = CommandFactory.createRecordingCommand(ted, |
| new VerticalSpaceExpansion(sdep.getSequenceDiagram(), new Range(0, 0), 0, Lists.<ISequenceEvent> newArrayList())); |
| sdep.getEditingDomain().getCommandStack().execute(verticalSpaceExpansion); |
| } |
| } |
| }); |
| } |
| |
| /** |
| * Reads and remembers the vertical position of each element in a sequence diagram. Use in conjunction with "Show |
| * Position Changes". |
| */ |
| private void addStorePositionsAction() { |
| addAction("Store positions", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof SequenceDiagramEditPart) { |
| SequenceDiagramEditPart sdep = (SequenceDiagramEditPart) selection; |
| storedPositions = readVerticalPositions(sdep); |
| } |
| } |
| }); |
| } |
| |
| /** |
| * Prints a report of which elements changed position in a sequence diagram since the last call to "Store |
| * positions". Only the elements whose position is different are shown (i.e. an empty report means nothing changed). |
| */ |
| private void addShowPositionChangesAction() { |
| addAction("Show Position Changes", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof SequenceDiagramEditPart) { |
| SequenceDiagramEditPart sdep = (SequenceDiagramEditPart) selection; |
| if (storedPositions != null) { |
| Map<EObject, Integer> newPositions = readVerticalPositions(sdep); |
| List<EObject> elements = Lists.newArrayList(newPositions.keySet()); |
| Collections.sort(elements, Ordering.natural().onResultOf(Functions.forMap(newPositions))); |
| TabularReport report = new TabularReport("Semantic element", "Old Position", "New Position", "deltaY"); |
| AdapterFactoryLabelProvider lp = new AdapterFactoryLabelProvider(getAdapterFactory()); |
| for (EObject element : elements) { |
| Integer oldY = storedPositions.get(element); |
| Integer newY = newPositions.get(element); |
| if (oldY != null && !oldY.equals(newY)) { |
| report.addLine(lp.getText(element), String.valueOf(oldY), String.valueOf(newY), String.valueOf(newY - oldY)); |
| } else if (oldY == null) { |
| report.addLine(lp.getText(element), "-", String.valueOf(newY), "n/a"); |
| } else if (newY == VerticalPositionFunction.INVALID_POSITION) { |
| report.addLine(lp.getText(element), String.valueOf(oldY), "-", "n/a"); |
| } |
| } |
| setText(report.print()); |
| } |
| } |
| } |
| }); |
| } |
| |
| private Map<EObject, Integer> readVerticalPositions(SequenceDiagramEditPart sdep) { |
| SequenceDDiagram diag = (SequenceDDiagram) sdep.resolveSemanticElement(); |
| VerticalPositionFunction vpf = new VerticalPositionFunction(diag); |
| Map<EObject, Integer> positions = Maps.newHashMap(); |
| for (EventEnd end : diag.getGraphicalOrdering().getEventEnds()) { |
| positions.put(end.getSemanticEnd(), (int) vpf.apply(end)); |
| } |
| return positions; |
| } |
| |
| /** |
| * Prints a report of the graphical and semantic orderings on a sequence diagram. For elements which have a valid |
| * graphical position, it is also reported. |
| */ |
| private void addShowOrderingsAction() { |
| addAction("Orderings", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof SequenceDiagramEditPart) { |
| AdapterFactoryLabelProvider lp = new AdapterFactoryLabelProvider(getAdapterFactory()); |
| SequenceDiagramEditPart sdep = (SequenceDiagramEditPart) selection; |
| SequenceDDiagram diag = (SequenceDDiagram) sdep.resolveSemanticElement(); |
| VerticalPositionFunction vpf = new VerticalPositionFunction(diag); |
| Iterator<EventEnd> go = diag.getGraphicalOrdering().getEventEnds().iterator(); |
| Iterator<EventEnd> so = diag.getSemanticOrdering().getEventEnds().iterator(); |
| TabularReport report = new TabularReport("Semantic", "Graphical", "Sync?", "Y"); |
| while (so.hasNext() || go.hasNext()) { |
| List<String> line = Lists.newArrayList(); |
| |
| final EObject sosEnd; |
| if (so.hasNext()) { |
| EventEnd soEnd = so.next(); |
| sosEnd = soEnd.getSemanticEnd(); |
| line.add(lp.getText(sosEnd)); |
| } else { |
| sosEnd = null; |
| line.add("<none>"); |
| } |
| |
| final EObject gosEnd; |
| final int y; |
| if (go.hasNext()) { |
| EventEnd goEnd = go.next(); |
| gosEnd = goEnd.getSemanticEnd(); |
| line.add(lp.getText(gosEnd)); |
| y = vpf.apply(goEnd); |
| } else { |
| gosEnd = null; |
| line.add("<none>"); |
| y = -1; |
| } |
| |
| if (sosEnd == gosEnd) { |
| line.add("yes"); |
| } else { |
| line.add("NO"); |
| } |
| line.add(y != -1 ? String.valueOf(y) : "n/a"); |
| report.addLine(line); |
| } |
| setText(report.print()); |
| } |
| } |
| }); |
| } |
| |
| private void addFoldingToggleAction() { |
| addAction("Toggle folding", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof IAbstractDiagramNodeEditPart) { |
| IAbstractDiagramNodeEditPart part = (IAbstractDiagramNodeEditPart) selection; |
| EdgeTargetQuery query = new EdgeTargetQuery((EdgeTarget) part.resolveDiagramElement()); |
| boolean isFoldingPoint = query.isFoldingPoint(); |
| if (isFoldingPoint) { |
| part.getEditingDomain().getCommandStack().execute(new ToggleFoldingStateCommand(part.getEditingDomain(), part)); |
| } |
| } |
| } |
| }); |
| } |
| |
| /** |
| * Show details about each edit part |
| */ |
| private void addShowEditPartsHierarchyAction() { |
| addAction("Show Edit Parts", new ShowEditPartsHierarchy(this)); |
| } |
| |
| /** |
| * Show details about each figure in the Draw2D hierarchy starting from the current selection's figure. See |
| * {@link #figureDetails(IFigure)} for what information is actually shown for each figure. |
| */ |
| private void addShowFiguresHierarchyAction() { |
| addAction("Show figures", new Runnable() { |
| @Override |
| public void run() { |
| if (selection instanceof IAbstractDiagramNodeEditPart) { |
| IAbstractDiagramNodeEditPart part = (IAbstractDiagramNodeEditPart) selection; |
| StringBuilder sb = new StringBuilder(); |
| showFigures(part.getFigure(), 0, sb); |
| setText(sb.toString()); |
| } |
| } |
| }); |
| } |
| |
| private void showFigures(IFigure figure, int level, StringBuilder out) { |
| for (int i = 0; i < level; i++) { |
| out.append(" "); |
| } |
| out.append(figureDetails(figure)).append("\n"); |
| for (IFigure child : Iterables.filter(figure.getChildren(), IFigure.class)) { |
| showFigures(child, level + 1, out); |
| } |
| } |
| |
| private String figureDetails(IFigure figure) { |
| return "Opaque: " + figure.isOpaque() + " Color: " + figure.getBackgroundColor() + " Class: " + figure.getClass().getSimpleName() + " Bounds: " + figure.getBounds(); |
| } |
| |
| private static class RefreshGraphicalCoverage extends RecordingCommand { |
| |
| private SequenceDiagramEditPart sdep; |
| |
| public RefreshGraphicalCoverage(TransactionalEditingDomain domain, SequenceDiagramEditPart sdep) { |
| super(domain); |
| this.sdep = sdep; |
| } |
| |
| @Override |
| protected void doExecute() { |
| new SequenceDiagramLayout(sdep).refreshGraphicalCoverage(); |
| } |
| |
| } |
| |
| private static class RefreshBendpoints extends RecordingCommand { |
| |
| private SequenceMessageEditPart smep; |
| |
| public RefreshBendpoints(TransactionalEditingDomain domain, SequenceMessageEditPart smep) { |
| super(domain); |
| this.smep = smep; |
| } |
| |
| @Override |
| protected void doExecute() { |
| smep.refreshBendpoints(); |
| } |
| |
| } |
| } |