Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 4d0b6b5e1365b8476d33650af787cc3009fdeab3 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

















                                                                                            

                                               
                                     


                                                      
                                        

                                                                         
                                                                           

                                                                          
                                                       
                                                            

                                                                     

                                                       
                                         

                                            
























                                                                               
                                           
 




                                               
 

                                    
                                                                  

                                                                                
 



                                                                                     
                        

                                            
                 



                                                                      

                                          
                                                                                          

                                                            









                                                                                     
                                                                                                        
           










                                                                                                                                
                                                        



                                                                                



                         







                                                                              

                 









                                                                 
 











                                                                      
 
                                                                                                      











                                                                                           



                                                                                  
 

                                                           
                                                                       

                                         


                         

                                         
                   

                          


                                                                         


                                                                                                   

                                                                                











                                                                                                           
                                                                              







                                                                                                        



                                                
















                                                                                      



                                                    






























                                                                                                                       

 







                                                                                                                   
 









                                                                                   
                                                    








                                                                                                            

         
/*****************************************************************************
 * Copyright (c) 2015 CEA LIST 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:
 *  Ansgar Radermacher (CEA LIST) ansgar.radermacher@cea.fr - Initial API and implementation
 *
 *****************************************************************************/
package org.eclipse.papyrusrt.umlrt.tooling.ui.widgets;

import java.util.ArrayList;

import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.papyrus.infra.properties.ui.modelelement.ModelElement;
import org.eclipse.papyrus.infra.properties.ui.widgets.ReferenceDialog;
import org.eclipse.papyrus.infra.widgets.providers.DelegatingLabelProvider;
import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
import org.eclipse.papyrus.uml.properties.modelelement.UMLModelElement;
import org.eclipse.papyrus.uml.tools.utils.PackageUtil;
import org.eclipse.papyrusrt.umlrt.core.utils.ProtocolUtils;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageKind;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageSet;
import org.eclipse.papyrusrt.umlrt.tooling.ui.Messages;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.uml2.uml.AnyReceiveEvent;
import org.eclipse.uml2.uml.CallEvent;
import org.eclipse.uml2.uml.Event;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.Port;
import org.eclipse.uml2.uml.Trigger;
import org.eclipse.uml2.uml.util.UMLUtil;

/**
 * Specific event selection dialog for UML/RT. It filters events in function of
 * selected port.
 */
public class EventSelectionDialog extends ReferenceDialog {

	/**
	 * Constructor.
	 *
	 * @param parent
	 * @param style
	 */
	public EventSelectionDialog(Composite parent, int style) {
		super(parent, style);
	}

	protected EList<Package> protocols;

	protected EList<Package> conjProtocols;

	protected Trigger trigger = null;

	protected boolean errorShown = false;

	@Override
	protected void doBinding() {
		editor.setLabelProvider(new EventLabelProvider());
		editor.setDirectCreation(input.getDirectCreation(propertyPath));
		editor.setMandatory(input.isMandatory(propertyPath));

		ModelElement triggerElement = input.getModelElement(propertyPath);
		EObject triggerEObj = ((UMLModelElement) triggerElement).getSource();
		if (triggerEObj instanceof Trigger) {
			trigger = (Trigger) triggerEObj;
		} else {
			// should not happen
			trigger = null;
		}

		updateProtocols();

		editor.setContentProvider(new EventContentProvider());

		if (valueEditor != null) {
			IObservableValue inputObservableValue = getInputObservableValue();
			if (inputObservableValue != null) {
				valueEditor.setStrategies();
				IValidator modelVal = getValidator();
				if (modelVal != null) {
					valueEditor.setModelValidator(modelVal);
				}
				valueEditor.setModelObservable(inputObservableValue);
			}
		}
	}

	/**
	 * Update the information about the used protocols, split into conjugated and "normal" protocols
	 */
	protected void updateProtocols() {
		protocols = new UniqueEList<Package>();
		conjProtocols = new UniqueEList<Package>();
		if (trigger != null) {
			for (Port port : trigger.getPorts()) {
				if (port.getType() != null) {
					Package protocol = port.getType().getNearestPackage();
					if (protocol != null) {
						// protocol can be null in case of unresolved proxies (even if type is not null)
						if (port.isConjugated()) {
							conjProtocols.add(protocol);
						} else {
							protocols.add(protocol);
						}
					}
				}
			}
		}
	}

	/**
	 * A delegating label provide that displays the icon of the associated
	 * operation instead of that of the call event itself.
	 */
	protected class EventLabelProvider extends DelegatingLabelProvider {

		public EventLabelProvider() {
			super(input.getLabelProvider(propertyPath));
		}

		/**
		 * no image in case of any receive event.
		 */
		@Override
		public Image getImage(Object element) {
			if (element instanceof AnyReceiveEvent) {
				return null;
			}
			return super.getImage(element);
		}

		/**
		 * image of associated operation in case of call event
		 */
		@Override
		protected Image customGetImage(Object element) {
			if (element instanceof CallEvent) {
				CallEvent ce = (CallEvent) element;
				return getImage(ce.getOperation());
			}
			return null;
		}
	}

	protected class EventContentProvider implements IStaticContentProvider, ITreeContentProvider {

		@Override
		public Object[] getElements(Object inputElement) {
			return getElements();
		}

		@Override
		public void dispose() {
		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			updateProtocols();
			if (viewer instanceof TreeViewer) {
				final TreeViewer treeViewer = (TreeViewer) viewer;
				Display.getDefault().asyncExec(new Runnable() {

					@Override
					public void run() {
						treeViewer.expandAll();
					}
				});
			}
		}

		/**
		 * Top-level element list
		 * 
		 * @return
		 */
		@Override
		public Object[] getElements() {
			ArrayList<Event> events = new ArrayList<Event>();
			// take "any" event from first protocol, if there is one (arbitrary choice)
			if (protocols.size() > 0) {
				addAnyEvent(events, false, protocols.get(0));
			} else if (conjProtocols.size() > 0) {
				addAnyEvent(events, true, conjProtocols.get(0));
			}
			return events.toArray();
		}

		/**
		 * Get the specific protocol messages (grouped below the singleAnyReceiveElement as parent)
		 */
		@Override
		public Object[] getChildren(Object parent) {
			// get specific messages of protocols
			ArrayList<Event> events = new ArrayList<Event>();
			EList<Package> allProtocols = new UniqueEList<Package>();
			EList<Package> directProtocols = getDirectProtocols();
			for (Package protocol : directProtocols) {
				allProtocols.addAll(ProtocolUtils.getAllProtocols(protocol));
			}
			for (Package protocol : allProtocols) {
				// only add call events of protocols that are common among the protocols
				// referenced by a port
				if (ProtocolUtils.isCommonProtocol(directProtocols, protocol)) {
					addCallEvents(events, protocol);
				}
			}
			return events.toArray();
		}

		@Override
		public Object getParent(Object parent) {
			return null;
		}

		@Override
		public boolean hasChildren(Object event) {
			if (event instanceof AnyReceiveEvent) {
				return true;
			}
			return false;
		}
	}

	/**
	 * add the CallEvents of a protocol to the passed list of events. The function
	 * takes the conjugation status into account
	 * 
	 * @param events
	 *            The passed event lsit
	 * @param protocol
	 */
	protected void addCallEvents(ArrayList<Event> events, Package protocol) {
		// calculate conjugation status. If a protocol is in both lists, only
		// inout messages are added
		boolean normal = protocols.contains(protocol);
		boolean conjugated = conjProtocols.contains(protocol);
		for (PackageableElement pe : protocol.getPackagedElements()) {
			if (pe instanceof CallEvent) {
				CallEvent callEvent = (CallEvent) pe;
				Interface intf = callEvent.getOperation().getInterface();
				RTMessageSet rtMessageSet = UMLUtil.getStereotypeApplication(intf, RTMessageSet.class);
				RTMessageKind kind = rtMessageSet.getRtMsgKind();
				if (kind == RTMessageKind.IN_OUT
						|| (kind == RTMessageKind.IN && !conjugated)
						|| (kind == RTMessageKind.OUT && !normal)) {
					events.add(callEvent);
				}
			}
		}
	}

	/**
	 * @return protocols that are directly referenced by the ports.
	 */
	protected EList<Package> getDirectProtocols() {
		EList<Package> directProtocols = new UniqueEList<Package>();
		directProtocols.addAll(protocols);
		directProtocols.addAll(conjProtocols);
		return directProtocols;
	}



	protected static void addAnyEvent(ArrayList<Event> events, boolean conjugated, Package protocolContainer) {
		for (PackageableElement pe : protocolContainer.getPackagedElements()) {
			if (pe instanceof AnyReceiveEvent) {
				events.add((AnyReceiveEvent) pe);
			}
		}
	}

	/**
	 * Obtain the base protocol (UMLRTBaseCommProtocol) from the RTS library
	 *
	 * @return the base protocol
	 */
	public Package getBaseProtocol() {
		if (trigger != null) {
			Package root = PackageUtil.getRootPackage(trigger);
			Package baseProtocol = ProtocolUtils.getBaseProtocol(root);
			if (baseProtocol != null) {
				return baseProtocol;
			}
			if (!errorShown) {
				errorShown = true;
				MessageDialog.openWarning(Display.getCurrent().getActiveShell(),
						Messages.EventSelectionDialog_BaseProtocolNotFound_Title,
						Messages.EventSelectionDialog_BaseProtocolNotFound_Message);
			}
		}
		return null;
	}
}

Back to the top