TDLan2ScopeProvider.java 6.08 KB
Newer Older
package org.etsi.mts.tdl.scoping;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.Scopes;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.etsi.mts.tdl.Assignment;
import org.etsi.mts.tdl.Behaviour;
import org.etsi.mts.tdl.Block;
import org.etsi.mts.tdl.ComponentInstance;
import org.etsi.mts.tdl.Connection;
import org.etsi.mts.tdl.DataElementMapping;
import org.etsi.mts.tdl.DataInstanceUse;
import org.etsi.mts.tdl.Element;
import org.etsi.mts.tdl.GateInstance;
import org.etsi.mts.tdl.GateReference;
import org.etsi.mts.tdl.MemberAssignment;
import org.etsi.mts.tdl.Parameter;
import org.etsi.mts.tdl.ParameterBinding;
import org.etsi.mts.tdl.ParameterMapping;
import org.etsi.mts.tdl.StructuredDataInstance;
import org.etsi.mts.tdl.StructuredDataType;
import org.etsi.mts.tdl.Target;
import org.etsi.mts.tdl.TestConfiguration;
import org.etsi.mts.tdl.TestDescription;
import org.etsi.mts.tdl.Variable;

import com.google.common.base.Function;
import com.google.inject.Inject;

/**
 * This class contains custom scoping description.
 * 
 * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping on
 * how and when to use it
 * 
 */
public class TDLan2ScopeProvider extends AbstractDeclarativeScopeProvider {
	@Inject
	private IQualifiedNameConverter qualifiedNameConverter;

	@Override
	public IScope getScope(EObject context, EReference reference) {

		if (reference.getEType().getInstanceClass() == GateInstance.class) {
			if (context instanceof GateReference) {
				GateReference gate = (GateReference) context;
				IScope scope = Scopes.scopeFor(gate.getComponent().getType().getGateInstance());
				return scope;
			}
		} else if (reference.getEType().getInstanceClass() == ComponentInstance.class) {
			if (context instanceof Behaviour || context instanceof Block) {
				TestDescription testDescription = getTestDescription((Element) context);
				if (testDescription!=null) {
					TestConfiguration configuration = testDescription.getTestConfiguration();
					IScope scope = Scopes.scopeFor(configuration.getComponentInstance());
					return scope;
				}
			} else if (context instanceof GateReference) {
				TestConfiguration configuration = getTestConfiguration((Element) context);
				EList<ComponentInstance> components = configuration.getComponentInstance();
				IScope scope = Scopes.scopeFor(components);
				return scope;
			} 
		} else if (reference.getEType().getInstanceClass() == GateReference.class) {
			//TODO: safety checks in case invalid configuration is specified
			//TODO: only suggest connected gates as targets?

			if (context instanceof Behaviour || context instanceof Target || context instanceof Block) {
				TestConfiguration configuration = getTestDescription((Element) context).getTestConfiguration();
				EList<EObject> elements = new BasicEList<>();
				for (Connection c : configuration.getConnection()) {
					elements.addAll(c.getEndPoint());
				}

				IScope scope = Scopes.scopeFor(elements, new Function<EObject, QualifiedName>() {
			        @Override 
			        public QualifiedName apply(EObject o) {
			        	GateReference r = (GateReference) o;
			        	String n = r.getComponent().getName()+"."+r.getGate().getName();
			            QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(n);
			            return qualifiedName;
			        }

			    }, IScope.NULLSCOPE); 

				return scope;
			}
		} else if (Parameter.class.isAssignableFrom(reference.getEType().getInstanceClass())) {
			if (context instanceof MemberAssignment) {
				if (context.eContainer() instanceof StructuredDataInstance) {
					IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance)context.eContainer()).getDataType()).getMember());
					return scope;
				}
			} else if (context instanceof ParameterMapping) {
				if (context.eContainer() instanceof DataElementMapping) {
					if (((DataElementMapping)context.eContainer()).getMappableDataElement() instanceof StructuredDataType) {
						IScope scope = Scopes.scopeFor(((StructuredDataType)((DataElementMapping)context.eContainer()).getMappableDataElement()).getMember());
						return scope;
					}
				}				
			} else if (context instanceof ParameterBinding) {
				if (context.eContainer() instanceof DataInstanceUse) {
					if (((DataInstanceUse)context.eContainer()).getDataInstance() instanceof StructuredDataInstance) {
						IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance)((DataInstanceUse)context.eContainer()).getDataInstance()).getDataType()).getMember());
						return scope;
					}
				}
			}
		} else if (reference.getEType().getInstanceClass() == Variable.class) {
			if (context instanceof Assignment) {
				if (((Assignment)context).getComponentInstance()!=null) {
					IScope scope = Scopes.scopeFor(((Assignment)context).getComponentInstance().getType().getVariable());
					return scope;
				}
			}
		} else {
		}

		if (context instanceof Block) {
			TestDescription testDescription = getTestDescription((Element) context);
			if (testDescription!=null) {
				TestConfiguration configuration = testDescription.getTestConfiguration();
				IScope scope = Scopes.scopeFor(configuration.getComponentInstance());
				return scope;
			}
		}		
		return super.getScope(context, reference);
	}

	private TestConfiguration getTestConfiguration(Element self) {
		if (self.eContainer()!=null) {
			if (!(self.eContainer() instanceof TestConfiguration)) {
				return getTestConfiguration((Element) self.eContainer());
			} else {
				return (TestConfiguration)self.eContainer();
			}
		} 
		return null;
	}

	
	private TestDescription getTestDescription(Element self) {
		if (self.eContainer()!=null) {
			if (!(self.eContainer() instanceof TestDescription)) {
				return getTestDescription((Element) self.eContainer());
			} else {
				return (TestDescription)self.eContainer();
			}
		} 
		return null;
	}

}