org.eclipse.sirius.diagram.sequence.business.internal.VerticalPositionFunction.java Source code

Java tutorial

Introduction

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

Source

/*******************************************************************************
 * Copyright (c) 2010, 2011 THALES GLOBAL SERVICES.
 * 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;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.sirius.diagram.sequence.SequenceDDiagram;
import org.eclipse.sirius.diagram.sequence.business.internal.elements.ISequenceElementAccessor;
import org.eclipse.sirius.diagram.sequence.business.internal.ordering.EventEndHelper;
import org.eclipse.sirius.diagram.sequence.ordering.CompoundEventEnd;
import org.eclipse.sirius.diagram.sequence.ordering.EventEnd;
import org.eclipse.sirius.diagram.sequence.ordering.SingleEventEnd;
import org.eclipse.sirius.diagram.sequence.util.Range;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;

/**
 * A function which computes the vertical position (in absolute, normalized
 * coordinates) of an {@link EventEnd}.
 * 
 * @author pcdavid
 */
public class VerticalPositionFunction implements Function<EventEnd, Integer> {
    /**
     * The value returned by the function to indicate an invalid input from
     * which a position can not be determined.
     */
    public static final int INVALID_POSITION = Integer.MAX_VALUE;

    private final SequenceDDiagram diagram;

    /**
     * Constructor.
     * 
     * @param diagram
     *            the diagram on which the compute the position of the ends.
     */
    public VerticalPositionFunction(SequenceDDiagram diagram) {
        this.diagram = diagram;
    }

    /**
     * Returns the vertical position of the specified end as it appears on the
     * diagram associated to this function, or <code>INVALID_POSITION</code> if
     * the end is invalid or is not part of the diagram.
     * 
     * @param end
     *            the end for which to compute the position.
     * @return the vertical position of the end, or
     *         <code>INVALID_POSITION</code>.
     */
    public Integer apply(EventEnd end) {
        Integer result;
        SingleEventEnd see = null;
        EObject semanticEvent = null;
        if (end instanceof SingleEventEnd) {
            see = (SingleEventEnd) end;
        } else if (end instanceof CompoundEventEnd) {
            see = ((CompoundEventEnd) end).getEventEnds().iterator().next();
        }

        if (see != null) {
            semanticEvent = see.getSemanticEvent();
        }

        Iterable<View> eventViews = ISequenceElementAccessor.getViewsForSemanticElement(diagram, semanticEvent);

        if (Iterables.isEmpty(eventViews) && end instanceof CompoundEventEnd) {
            for (SingleEventEnd see2 : ((CompoundEventEnd) end).getEventEnds()) {
                if (see != null) {
                    semanticEvent = see2.getSemanticEvent();
                }
                eventViews = ISequenceElementAccessor.getViewsForSemanticElement(diagram, semanticEvent);
                if (!Iterables.isEmpty(eventViews)) {
                    break;
                }
            }
        }

        if (Iterables.isEmpty(eventViews)) {
            result = INVALID_POSITION;
        } else {
            result = INVALID_POSITION;
            Range range = Range.emptyRange();

            for (View potentialView : eventViews) {
                range = VerticalRangeFunction.INSTANCE.apply(potentialView);
                if (!range.isEmpty()) {
                    break;
                }
            }

            if (EventEndHelper.PUNCTUAL_COMPOUND_EVENT_END.apply(end)) {
                result = (int) range.middleValue();
            } else if (EventEndHelper.PUNCTUAL_COMPOUND_EVENT_END.apply(end)) {
                result = (int) range.middleValue();
            } else {
                result = (int) (see.isStart() ? range.getLowerBound() : range.getUpperBound());
            }
        }
        return result;
    }
}