org.eclipse.sirius.diagram.sequence.business.internal.query.SequenceDiagramQuery.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.sirius.diagram.sequence.business.internal.query.SequenceDiagramQuery.java

Source

/*******************************************************************************
 * Copyright (c) 2010, 2015 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.diagram.sequence.business.internal.query;

import java.util.Collection;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.eclipse.sirius.diagram.sequence.Messages;
import org.eclipse.sirius.diagram.sequence.business.internal.RangeHelper;
import org.eclipse.sirius.diagram.sequence.business.internal.elements.AbstractFrame;
import org.eclipse.sirius.diagram.sequence.business.internal.elements.ISequenceEvent;
import org.eclipse.sirius.diagram.sequence.business.internal.elements.ISequenceNode;
import org.eclipse.sirius.diagram.sequence.business.internal.elements.Lifeline;
import org.eclipse.sirius.diagram.sequence.business.internal.elements.Message;
import org.eclipse.sirius.diagram.sequence.business.internal.elements.SequenceDiagram;
import org.eclipse.sirius.diagram.sequence.business.internal.layout.LayoutConstants;
import org.eclipse.sirius.diagram.sequence.util.Range;
import org.eclipse.sirius.diagram.ui.tools.api.graphical.edit.styles.IBorderItemOffsets;
import org.eclipse.sirius.ext.base.Option;

import com.google.common.base.Preconditions;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;

/**
 * Queries from a {@link SequenceDiagram}.
 * 
 * @author edugueperoux
 * 
 */
public class SequenceDiagramQuery {

    private SequenceDiagram sequenceDiagram;

    /**
     * Create the query.
     * 
     * @param sequenceDiagram
     *            the source of the query.
     */
    public SequenceDiagramQuery(SequenceDiagram sequenceDiagram) {
        this.sequenceDiagram = sequenceDiagram;
    }

    /**
     * Get all {@link ISequenceEvent} of the current {@link SequenceDiagram}
     * with range's lower bound strictly inferior to timePoint.
     * 
     * @param timePoint
     *            the timePoint from which get all lower {@link ISequenceEvent}
     * 
     * @return the set of {@link ISequenceEvent} lower timePoint, sorted by
     *         range from lower to upper
     */
    public Set<ISequenceEvent> getAllSequenceEventsLowerThan(int timePoint) {
        Preconditions.checkNotNull(sequenceDiagram, Messages.SequenceDiagramQuery_nullSequenceDiagram);
        Preconditions.checkArgument(timePoint > 0, Messages.SequenceDiagramQuery_invalidTimePoint);

        Set<ISequenceEvent> sequenceEventLowers = new TreeSet<ISequenceEvent>(new RangeComparator());
        for (ISequenceEvent sequenceEvent : getAllSequenceEvents()) {
            Range sequenceEventRange = sequenceEvent.getVerticalRange();
            if (sequenceEventRange.getLowerBound() < timePoint) {
                sequenceEventLowers.add(sequenceEvent);
            }
        }
        return sequenceEventLowers;
    }

    /**
     * Get all {@link ISequenceEvent} of the current {@link SequenceDiagram}
     * with range's including strictly timePoint.
     * 
     * @param timePoint
     *            the timePoint from which get all {@link ISequenceEvent}
     *            including it in their range
     * 
     * @return the set of {@link ISequenceEvent} having timePoint in their
     *         range, sorted by range from lower to upper
     */
    public Set<ISequenceEvent> getAllSequenceEventsOn(int timePoint) {
        Preconditions.checkNotNull(sequenceDiagram, Messages.SequenceDiagramQuery_nullSequenceDiagram);
        Preconditions.checkArgument(timePoint > 0, Messages.SequenceDiagramQuery_invalidTimePoint);

        Set<ISequenceEvent> sequenceEventOns = new TreeSet<ISequenceEvent>(new RangeComparator());
        for (ISequenceEvent sequenceEvent : getAllSequenceEvents()) {
            Range sequenceEventRange = sequenceEvent.getVerticalRange();
            if (sequenceEventRange.includes(timePoint)) {
                sequenceEventOns.add(sequenceEvent);
            }
        }
        return sequenceEventOns;
    }

    /**
     * Get all {@link ISequenceEvent} of the current {@link SequenceDiagram}
     * with range's lowerbound strictly upper to timePoint.
     * 
     * @param timePoint
     *            the timePoint from which get all upper {@link ISequenceEvent}
     * 
     * @return the set of {@link ISequenceEvent} upper timePoint, sorted by
     *         range from lower to upper
     */
    public Set<ISequenceEvent> getAllSequenceEventsUpperThan(int timePoint) {
        Preconditions.checkNotNull(sequenceDiagram, Messages.SequenceDiagramQuery_nullSequenceDiagram);
        Preconditions.checkArgument(timePoint > 0, Messages.SequenceDiagramQuery_invalidTimePoint);

        Set<ISequenceEvent> sequenceEventUppers = new TreeSet<ISequenceEvent>(new RangeComparator());
        for (ISequenceEvent sequenceEvent : getAllSequenceEvents()) {
            Range sequenceEventRange = sequenceEvent.getVerticalRange();
            if (sequenceEventRange.getLowerBound() > timePoint) {
                sequenceEventUppers.add(sequenceEvent);
            }
        }
        return sequenceEventUppers;
    }

    /**
     * Get all {@link ISequenceEvent} of the current {@link SequenceDiagram}.
     * 
     * @return the set of {@link ISequenceEvent} of the current
     *         {@link SequenceDiagram}, sorted by range from lower to upper
     */
    public Set<ISequenceEvent> getAllSequenceEvents() {
        Preconditions.checkNotNull(sequenceDiagram, Messages.SequenceDiagramQuery_nullSequenceDiagram);

        Set<ISequenceEvent> allSequenceEvents = new TreeSet<ISequenceEvent>(new RangeComparator());
        allSequenceEvents.addAll(sequenceDiagram.getAllLifelines());
        allSequenceEvents.addAll(sequenceDiagram.getAllAbstractNodeEvents());
        allSequenceEvents.addAll(sequenceDiagram.getAllMessages());
        allSequenceEvents.addAll(sequenceDiagram.getAllInteractionUses());
        allSequenceEvents.addAll(sequenceDiagram.getAllCombinedFragments());
        allSequenceEvents.addAll(sequenceDiagram.getAllOperands());
        allSequenceEvents.addAll(sequenceDiagram.getAllStates());
        return allSequenceEvents;
    }

    /**
     * Get all {@link ISequenceEvent} of the current {@link SequenceDiagram} of
     * the specified {@link Lifeline}.
     * 
     * @param lifeline
     *            the specified {@link Lifeline}
     * 
     * @return the set of {@link ISequenceEvent} of the current
     *         {@link SequenceDiagram} of the specified {@link Lifeline}, sorted
     *         by range from lower to upper
     */
    public Set<ISequenceEvent> getAllSequenceEventsOnLifeline(Lifeline lifeline) {
        Set<ISequenceEvent> allSequenceEventsOnLifeline = new TreeSet<ISequenceEvent>(new RangeComparator());
        for (ISequenceEvent sequenceEvent : Iterables.filter(getAllSequenceEvents(),
                Predicates.not(Predicates.instanceOf(Lifeline.class)))) {
            Option<Lifeline> lifelineOfSequenceEventOption = sequenceEvent.getLifeline();
            if (lifelineOfSequenceEventOption.some() && lifelineOfSequenceEventOption.get().equals(lifeline)) {
                allSequenceEventsOnLifeline.add(sequenceEvent);
            } else if (!lifelineOfSequenceEventOption.some()) {
                if (sequenceEvent instanceof Message) {
                    Message message = (Message) sequenceEvent;
                    Option<Lifeline> sourceLifelineOption = message.getSourceLifeline();
                    Option<Lifeline> targetLifelineOption = message.getTargetLifeline();
                    if (sourceLifelineOption.some() && sourceLifelineOption.get().equals(lifeline)) {
                        allSequenceEventsOnLifeline.add(message);
                    } else if (targetLifelineOption.some() && targetLifelineOption.get().equals(lifeline)) {
                        allSequenceEventsOnLifeline.add(message);
                    }
                } else if (sequenceEvent instanceof AbstractFrame) {
                    AbstractFrame abstractFrame = (AbstractFrame) sequenceEvent;
                    Collection<Lifeline> coveredLifelines = abstractFrame.computeCoveredLifelines();
                    if (coveredLifelines.contains(lifeline)) {
                        allSequenceEventsOnLifeline.add(abstractFrame);
                    }
                }
            }
        }
        return allSequenceEventsOnLifeline;
    }

    /**
     * Get all events having at least one bound on the given {@link Lifeline} in
     * the given range.
     * 
     * @param lifeline
     *            the lifeline to check.
     * @param inclusionRange
     *            the range to look in.
     * @return events on the given lifeline and range.
     */
    public SortedSet<ISequenceEvent> getAllSequenceEventsOnLifelineOnRange(Lifeline lifeline,
            Range inclusionRange) {
        SortedSet<ISequenceEvent> allSequenceEventsOnLifelineStrictlyIncludedBetween = new TreeSet<ISequenceEvent>(
                new RangeComparator());
        for (ISequenceEvent sequenceEvent : getAllSequenceEventsOnLifeline(lifeline)) {
            Range sequenceEventRange = sequenceEvent.getVerticalRange();
            if (inclusionRange.includesAtLeastOneBound(sequenceEventRange)) {
                allSequenceEventsOnLifelineStrictlyIncludedBetween.add(sequenceEvent);
            }
        }
        return allSequenceEventsOnLifelineStrictlyIncludedBetween;
    }

    /**
     * Get all {@link ISequenceNode} of the current {@link SequenceDiagram} with
     * range's lowerbound strictly lower to timePoint.
     * 
     * @param timePoint
     *            the timePoint from which get all lower {@link ISequenceNode}
     * 
     * @return the set of {@link ISequenceNode} lower timePoint, sorted by range
     *         from lower to upper
     */
    public Set<ISequenceNode> getAllSequenceNodesLowerThan(int timePoint) {
        Preconditions.checkNotNull(sequenceDiagram, Messages.SequenceDiagramQuery_nullSequenceDiagram);
        Preconditions.checkArgument(timePoint > 0, Messages.SequenceDiagramQuery_invalidTimePoint);

        Set<ISequenceNode> sequenceNodeLowers = new TreeSet<ISequenceNode>(new RangeComparator());
        for (ISequenceNode sequenceNode : getAllSequenceNodes()) {
            Range sequenceNodeRange = RangeHelper.verticalRange(sequenceNode.getBounds());
            if (sequenceNodeRange.getLowerBound() < timePoint) {
                sequenceNodeLowers.add(sequenceNode);
            }
        }
        return sequenceNodeLowers;
    }

    /**
     * Get all {@link ISequenceNode} of the current {@link SequenceDiagram} with
     * range's including strictly timePoint.
     * 
     * @param timePoint
     *            the timePoint from which get all {@link ISequenceNode}
     *            including it in their range
     * 
     * @return the set of {@link ISequenceNode} having timePoint in their range,
     *         sorted by range from lower to upper
     */
    public Set<ISequenceNode> getAllSequenceNodesOn(int timePoint) {
        Preconditions.checkNotNull(sequenceDiagram, Messages.SequenceDiagramQuery_nullSequenceDiagram);
        Preconditions.checkArgument(timePoint > 0, Messages.SequenceDiagramQuery_invalidTimePoint);

        Set<ISequenceNode> sequenceNodeUnders = new TreeSet<ISequenceNode>(new RangeComparator());
        for (ISequenceNode sequenceNode : getAllSequenceNodes()) {
            Range sequenceEventRange = RangeHelper.verticalRange(sequenceNode.getBounds());
            if (sequenceEventRange.includes(timePoint)) {
                sequenceNodeUnders.add(sequenceNode);
            }
        }
        return sequenceNodeUnders;
    }

    /**
     * Get all {@link ISequenceNode} of the current {@link SequenceDiagram} with
     * range's lowerbound strictly upper to timePoint.
     * 
     * @param timePoint
     *            the timePoint from which get all upper {@link ISequenceNode}
     * 
     * @return the set of {@link ISequenceNode} upper timePoint, sorted by range
     *         from lower to upper
     */
    public Set<ISequenceNode> getAllSequenceNodesUpperThan(int timePoint) {
        Preconditions.checkNotNull(sequenceDiagram, Messages.SequenceDiagramQuery_nullSequenceDiagram);
        Preconditions.checkArgument(timePoint > 0, Messages.SequenceDiagramQuery_invalidTimePoint);

        Set<ISequenceNode> sequenceNodeUnders = new TreeSet<ISequenceNode>(new RangeComparator());
        for (ISequenceNode sequenceNode : getAllSequenceNodes()) {
            Range sequenceNodeRange = RangeHelper.verticalRange(sequenceNode.getBounds());
            if (sequenceNodeRange.getLowerBound() > timePoint) {
                sequenceNodeUnders.add(sequenceNode);
            }
        }
        return sequenceNodeUnders;
    }

    /**
     * Get all {@link ISequenceNode} of the current {@link SequenceDiagram}.
     * 
     * @return the set of {@link ISequenceNode} of the current
     *         {@link SequenceDiagram}, sorted by range from lower to upper
     */
    public Set<ISequenceNode> getAllSequenceNodes() {
        Preconditions.checkNotNull(sequenceDiagram, Messages.SequenceDiagramQuery_nullSequenceDiagram);

        Set<ISequenceNode> allSequenceNodes = new TreeSet<ISequenceNode>(new RangeComparator());
        allSequenceNodes.addAll(sequenceDiagram.getAllInstanceRoles());
        allSequenceNodes.addAll(sequenceDiagram.getAllLifelines());
        allSequenceNodes.addAll(sequenceDiagram.getAllAbstractNodeEvents());
        allSequenceNodes.addAll(sequenceDiagram.getAllInteractionUses());
        allSequenceNodes.addAll(sequenceDiagram.getAllCombinedFragments());
        allSequenceNodes.addAll(sequenceDiagram.getAllOperands());
        allSequenceNodes.addAll(sequenceDiagram.getAllEndOfLifes());
        return allSequenceNodes;
    }

    /**
     * Get the initial time from which event ends can graphically start. This
     * initial time corresponds to y coordinate of the bottom of the biggest
     * InstanceRole not connected to a Create message +
     * {@link LayoutConstants#TIME_START_OFFSET}.
     * 
     * @return the initial time if the current {@link SequenceDiagram} contains
     *         {@link Lifeline}, 0 else
     */
    public int getInitialTime() {
        Preconditions.checkNotNull(sequenceDiagram, Messages.SequenceDiagramQuery_nullSequenceDiagram);
        int initialTime = 0;
        for (Lifeline lifeline : sequenceDiagram.getAllLifelines()) {
            int initialTimeCandidate = lifeline.getVerticalRange().getLowerBound();
            if (initialTimeCandidate > initialTime && !lifeline.getInstanceRole().isExplicitlyCreated()) {
                initialTime = initialTimeCandidate;
            }
        }
        return initialTime + LayoutConstants.TIME_START_OFFSET + IBorderItemOffsets.DEFAULT_OFFSET.height;
    }

    /**
     * Get the final time until which event ends can graphically end. This final
     * time corresponds to y coordinate of the bottom of {@link Lifeline} -
     * {@link LayoutConstants#TIME_STOP_OFFSET}.
     * 
     * @return the final time if the current {@link SequenceDiagram} contains
     *         {@link Lifeline}, 0 else
     */
    public int getFinalTime() {
        Preconditions.checkNotNull(sequenceDiagram, Messages.SequenceDiagramQuery_nullSequenceDiagram);
        int finalTime = 0;
        if (!sequenceDiagram.getAllLifelines().isEmpty()) {
            Lifeline lifeline = sequenceDiagram.getAllLifelines().iterator().next();
            finalTime = lifeline.getVerticalRange().getUpperBound() - LayoutConstants.TIME_STOP_OFFSET;
        }
        return finalTime;
    }

}