Loading plugins/org.etsi.mts.tdl.graphical.labels.data/src/org/etsi/mts/tdl/graphical/labels/DataRuntimeModule.java +24 −0 Original line number Original line Diff line number Diff line Loading @@ -3,10 +3,18 @@ */ */ package org.etsi.mts.tdl.graphical.labels; package org.etsi.mts.tdl.graphical.labels; import org.eclipse.xtext.linking.ILinkingService; import org.eclipse.xtext.naming.IQualifiedNameProvider; import org.eclipse.xtext.parser.IParser; import org.eclipse.xtext.parser.IParser; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.scoping.IGlobalScopeProvider; import org.eclipse.xtext.serializer.sequencer.IContextFinder; import org.eclipse.xtext.serializer.sequencer.IContextFinder; import org.eclipse.xtext.serializer.tokens.ICrossReferenceSerializer; import org.eclipse.xtext.serializer.tokens.ICrossReferenceSerializer; import org.etsi.mts.tdl.graphical.labels.linking.ContextAwareLinkingService; import org.etsi.mts.tdl.graphical.labels.naming.QNameProvider; import org.etsi.mts.tdl.graphical.labels.parser.RuleBasedDataParser; import org.etsi.mts.tdl.graphical.labels.parser.RuleBasedDataParser; import org.etsi.mts.tdl.graphical.labels.resource.AdaptiveLinkingResource; import org.etsi.mts.tdl.graphical.labels.scoping.ConfigurableScopeProvider; import org.etsi.mts.tdl.graphical.labels.serializer.DataCrossReferenceSerializer; import org.etsi.mts.tdl.graphical.labels.serializer.DataCrossReferenceSerializer; /** /** Loading @@ -25,4 +33,20 @@ public class DataRuntimeModule extends AbstractDataRuntimeModule { public Class<? extends IParser> bindIParser() { public Class<? extends IParser> bindIParser() { return RuleBasedDataParser.class; return RuleBasedDataParser.class; } } public Class<? extends XtextResource> bindXtextResource() { return AdaptiveLinkingResource.class; } public Class<? extends ILinkingService> bindILinkingService() { return ContextAwareLinkingService.class; } public Class<? extends IQualifiedNameProvider> bindIQualifiedNameProvider() { return QNameProvider.class; } public Class<? extends IGlobalScopeProvider> bindIGlobalScopeProvider() { return ConfigurableScopeProvider.class; } } } plugins/org.etsi.mts.tdl.graphical.labels.data/src/org/etsi/mts/tdl/graphical/labels/linking/ContextAwareLinkingService.java 0 → 100644 +134 −0 Original line number Original line Diff line number Diff line package org.etsi.mts.tdl.graphical.labels.linking; import java.util.Collections; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.linking.impl.DefaultLinkingService; import org.eclipse.xtext.linking.impl.IllegalNodeException; import org.eclipse.xtext.naming.IQualifiedNameConverter; import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.scoping.IScope; import org.etsi.mts.tdl.DataUse; import org.etsi.mts.tdl.tdlPackage; import com.google.inject.Inject; public class ContextAwareLinkingService extends DefaultLinkingService { private Map<EClass, AlternativeContext> alternativeContexts; @Inject private IQualifiedNameConverter qualifiedNameConverter; @Override public List<EObject> getLinkedObjects(EObject context, EReference ref, INode node) throws IllegalNodeException { final EClass requiredType = ref.getEReferenceType(); if (requiredType == null) return Collections.<EObject> emptyList(); final String crossRefString = getCrossRefNodeAsString(node); if (crossRefString != null && !crossRefString.equals("")) { QualifiedName qualifiedLinkName = qualifiedNameConverter.toQualifiedName(crossRefString); IScope scope = getScope(context, ref); Iterable<IEObjectDescription> eObjectDescriptions = scope.getElements(qualifiedLinkName); if (context instanceof DataUse && !eObjectDescriptions.iterator().hasNext()) { AlternativeContext alternative = getAlternativeContext(context); if (alternative != null) { //Keeps track of current object in the resource EObject current = context; for (int i = 0; i < alternative.classes.length; i++) { EObject alternativeContext = EcoreUtil.create(alternative.classes[i]); //Add new object to resource EcoreUtil.replace(current, alternativeContext); current = alternativeContext; IScope alternativeScope = getScope(alternativeContext, alternative.references[i]); Iterable<IEObjectDescription> altEObjectDescriptions = alternativeScope.getElements(qualifiedLinkName); if (altEObjectDescriptions.iterator().hasNext()) { alternative.copy(context, alternativeContext); context = alternativeContext; ref = alternative.references[i]; scope = alternativeScope; eObjectDescriptions = altEObjectDescriptions; break; } } if (context != current) //No alternative match, restore original EcoreUtil.replace(current, context); } } Iterator<IEObjectDescription> iter = eObjectDescriptions.iterator(); if (iter.hasNext()) { IEObjectDescription eObjectDescription = iter.next(); EObject linkedObject = eObjectDescription.getEObjectOrProxy(); if (!iter.hasNext() || !ref.isMany()) { // If we replaced the context object above then we need to // set this association here or it will be lost context.eSet(ref, linkedObject); return Collections.singletonList(linkedObject); } } } return Collections.emptyList(); } public AlternativeContext getAlternativeContext(EObject contextObject) { if (alternativeContexts == null) { alternativeContexts = new Hashtable<EClass, AlternativeContext>(); AlternativeContext dataUseContexts = new AlternativeContext() { @Override void copy(EObject from, EObject to) { ((DataUse)to).getReduction().addAll(((DataUse)from).getReduction()); ((DataUse)to).getArgument().addAll(((DataUse)from).getArgument()); } }; dataUseContexts.classes = new EClass[]{ tdlPackage.eINSTANCE.getDataInstanceUse(), tdlPackage.eINSTANCE.getFunctionCall(), tdlPackage.eINSTANCE.getPredefinedFunctionCall(), tdlPackage.eINSTANCE.getVariableUse(), tdlPackage.eINSTANCE.getFormalParameterUse() }; dataUseContexts.references = new EReference[]{ tdlPackage.eINSTANCE.getDataInstanceUse_DataInstance(), tdlPackage.eINSTANCE.getFunctionCall_Function(), tdlPackage.eINSTANCE.getPredefinedFunctionCall_Function(), tdlPackage.eINSTANCE.getVariableUse_Variable(), tdlPackage.eINSTANCE.getFormalParameterUse_Parameter() }; alternativeContexts.put(tdlPackage.eINSTANCE.getDataUse(), dataUseContexts); } for (EClass alternativeClass: alternativeContexts.keySet()) if (alternativeClass.isInstance(contextObject)) return alternativeContexts.get(alternativeClass); return null; } } abstract class AlternativeContext { EClass[] classes; EReference[] references; abstract void copy(EObject from, EObject to); } No newline at end of file plugins/org.etsi.mts.tdl.graphical.labels.data/src/org/etsi/mts/tdl/graphical/labels/naming/QNameProvider.java 0 → 100644 +19 −0 Original line number Original line Diff line number Diff line package org.etsi.mts.tdl.graphical.labels.naming; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider; import org.eclipse.xtext.naming.QualifiedName; import org.etsi.mts.tdl.Element; import org.etsi.mts.tdl.NamedElement; public class QNameProvider extends DefaultDeclarativeQualifiedNameProvider { @Override public QualifiedName getFullyQualifiedName(EObject obj) { if (obj instanceof NamedElement) { String name = ((Element) obj).getName(); if (name != null) return QualifiedName.create(((Element) obj).getName()); } return super.getFullyQualifiedName(obj); } } plugins/org.etsi.mts.tdl.graphical.labels.data/src/org/etsi/mts/tdl/graphical/labels/resource/AdaptiveLinkingResource.java 0 → 100644 +28 −0 Original line number Original line Diff line number Diff line package org.etsi.mts.tdl.graphical.labels.resource; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.xtext.linking.lazy.LazyLinkingResource; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.util.Triple; public class AdaptiveLinkingResource extends LazyLinkingResource { @Override protected EObject getEObject(String uriFragment, Triple<EObject, EReference, INode> triple) throws AssertionError { List<EObject> linkedObjects = getLinkingService().getLinkedObjects( triple.getFirst(), triple.getSecond(), triple.getThird()); if (!linkedObjects.isEmpty()) { EObject newObject = linkedObjects.get(0); if (!triple.getSecond().getEType().isInstance(newObject)) { //Was replaced return null; } } return super.getEObject(uriFragment, triple); } } plugins/org.etsi.mts.tdl.graphical.labels.data/src/org/etsi/mts/tdl/graphical/labels/scoping/ConfigurableScopeProvider.java 0 → 100644 +81 −0 Original line number Original line Diff line number Diff line package org.etsi.mts.tdl.graphical.labels.scoping; import java.util.Hashtable; import java.util.LinkedHashSet; import java.util.Map; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.resource.IResourceDescription; import org.eclipse.xtext.resource.IResourceDescriptions; import org.eclipse.xtext.resource.IResourceServiceProvider; import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider; import org.eclipse.xtext.scoping.impl.SelectableBasedScope; import org.etsi.mts.tdl.ElementImport; import org.etsi.mts.tdl.Package; import org.etsi.mts.tdl.tdlPackage; import com.google.common.base.Predicate; import com.google.inject.Inject; public class ConfigurableScopeProvider extends ImportUriGlobalScopeProvider { @Inject private IResourceServiceProvider resourceServiceProvider; private Map<URI, LinkedHashSet<URI>> importedUris = new Hashtable<URI, LinkedHashSet<URI>>(); @Override protected LinkedHashSet<URI> getImportedUris(Resource resource) { URI uri = resource.getURI(); ResourceSet rs = new ResourceSetImpl(); Resource realResource = rs.getResource(uri, true); LinkedHashSet<URI> imports = new LinkedHashSet<URI>(); importedUris.put(uri, imports); imports.add(uri); //Add resource URIs of imported packages for (EObject e: realResource.getContents()) { if (tdlPackage.eINSTANCE.getPackage().isInstance(e)) { Package p = (Package) e; addImports(p, imports); } } return imports; } private void addImports(Package p, LinkedHashSet<URI> imports) { for (ElementImport pi: p.getImport()) { Package ip = pi.getImportedPackage(); URI iUri = EcoreUtil.getURI(ip).trimFragment(); imports.add(iUri); addImports(ip, imports); } } @Override protected IScope createLazyResourceScope(IScope parent, URI uri, IResourceDescriptions descriptions, EClass type, Predicate<IEObjectDescription> filter, boolean ignoreCase) { ResourceSet rs = new ResourceSetImpl(); Resource resource = rs.getResource(uri, true); IResourceDescription description = resourceServiceProvider.getResourceDescriptionManager().getResourceDescription(resource); IScope scope = SelectableBasedScope.createScope(parent, description, filter, type, ignoreCase); return scope; } } Loading
plugins/org.etsi.mts.tdl.graphical.labels.data/src/org/etsi/mts/tdl/graphical/labels/DataRuntimeModule.java +24 −0 Original line number Original line Diff line number Diff line Loading @@ -3,10 +3,18 @@ */ */ package org.etsi.mts.tdl.graphical.labels; package org.etsi.mts.tdl.graphical.labels; import org.eclipse.xtext.linking.ILinkingService; import org.eclipse.xtext.naming.IQualifiedNameProvider; import org.eclipse.xtext.parser.IParser; import org.eclipse.xtext.parser.IParser; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.scoping.IGlobalScopeProvider; import org.eclipse.xtext.serializer.sequencer.IContextFinder; import org.eclipse.xtext.serializer.sequencer.IContextFinder; import org.eclipse.xtext.serializer.tokens.ICrossReferenceSerializer; import org.eclipse.xtext.serializer.tokens.ICrossReferenceSerializer; import org.etsi.mts.tdl.graphical.labels.linking.ContextAwareLinkingService; import org.etsi.mts.tdl.graphical.labels.naming.QNameProvider; import org.etsi.mts.tdl.graphical.labels.parser.RuleBasedDataParser; import org.etsi.mts.tdl.graphical.labels.parser.RuleBasedDataParser; import org.etsi.mts.tdl.graphical.labels.resource.AdaptiveLinkingResource; import org.etsi.mts.tdl.graphical.labels.scoping.ConfigurableScopeProvider; import org.etsi.mts.tdl.graphical.labels.serializer.DataCrossReferenceSerializer; import org.etsi.mts.tdl.graphical.labels.serializer.DataCrossReferenceSerializer; /** /** Loading @@ -25,4 +33,20 @@ public class DataRuntimeModule extends AbstractDataRuntimeModule { public Class<? extends IParser> bindIParser() { public Class<? extends IParser> bindIParser() { return RuleBasedDataParser.class; return RuleBasedDataParser.class; } } public Class<? extends XtextResource> bindXtextResource() { return AdaptiveLinkingResource.class; } public Class<? extends ILinkingService> bindILinkingService() { return ContextAwareLinkingService.class; } public Class<? extends IQualifiedNameProvider> bindIQualifiedNameProvider() { return QNameProvider.class; } public Class<? extends IGlobalScopeProvider> bindIGlobalScopeProvider() { return ConfigurableScopeProvider.class; } } }
plugins/org.etsi.mts.tdl.graphical.labels.data/src/org/etsi/mts/tdl/graphical/labels/linking/ContextAwareLinkingService.java 0 → 100644 +134 −0 Original line number Original line Diff line number Diff line package org.etsi.mts.tdl.graphical.labels.linking; import java.util.Collections; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.linking.impl.DefaultLinkingService; import org.eclipse.xtext.linking.impl.IllegalNodeException; import org.eclipse.xtext.naming.IQualifiedNameConverter; import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.scoping.IScope; import org.etsi.mts.tdl.DataUse; import org.etsi.mts.tdl.tdlPackage; import com.google.inject.Inject; public class ContextAwareLinkingService extends DefaultLinkingService { private Map<EClass, AlternativeContext> alternativeContexts; @Inject private IQualifiedNameConverter qualifiedNameConverter; @Override public List<EObject> getLinkedObjects(EObject context, EReference ref, INode node) throws IllegalNodeException { final EClass requiredType = ref.getEReferenceType(); if (requiredType == null) return Collections.<EObject> emptyList(); final String crossRefString = getCrossRefNodeAsString(node); if (crossRefString != null && !crossRefString.equals("")) { QualifiedName qualifiedLinkName = qualifiedNameConverter.toQualifiedName(crossRefString); IScope scope = getScope(context, ref); Iterable<IEObjectDescription> eObjectDescriptions = scope.getElements(qualifiedLinkName); if (context instanceof DataUse && !eObjectDescriptions.iterator().hasNext()) { AlternativeContext alternative = getAlternativeContext(context); if (alternative != null) { //Keeps track of current object in the resource EObject current = context; for (int i = 0; i < alternative.classes.length; i++) { EObject alternativeContext = EcoreUtil.create(alternative.classes[i]); //Add new object to resource EcoreUtil.replace(current, alternativeContext); current = alternativeContext; IScope alternativeScope = getScope(alternativeContext, alternative.references[i]); Iterable<IEObjectDescription> altEObjectDescriptions = alternativeScope.getElements(qualifiedLinkName); if (altEObjectDescriptions.iterator().hasNext()) { alternative.copy(context, alternativeContext); context = alternativeContext; ref = alternative.references[i]; scope = alternativeScope; eObjectDescriptions = altEObjectDescriptions; break; } } if (context != current) //No alternative match, restore original EcoreUtil.replace(current, context); } } Iterator<IEObjectDescription> iter = eObjectDescriptions.iterator(); if (iter.hasNext()) { IEObjectDescription eObjectDescription = iter.next(); EObject linkedObject = eObjectDescription.getEObjectOrProxy(); if (!iter.hasNext() || !ref.isMany()) { // If we replaced the context object above then we need to // set this association here or it will be lost context.eSet(ref, linkedObject); return Collections.singletonList(linkedObject); } } } return Collections.emptyList(); } public AlternativeContext getAlternativeContext(EObject contextObject) { if (alternativeContexts == null) { alternativeContexts = new Hashtable<EClass, AlternativeContext>(); AlternativeContext dataUseContexts = new AlternativeContext() { @Override void copy(EObject from, EObject to) { ((DataUse)to).getReduction().addAll(((DataUse)from).getReduction()); ((DataUse)to).getArgument().addAll(((DataUse)from).getArgument()); } }; dataUseContexts.classes = new EClass[]{ tdlPackage.eINSTANCE.getDataInstanceUse(), tdlPackage.eINSTANCE.getFunctionCall(), tdlPackage.eINSTANCE.getPredefinedFunctionCall(), tdlPackage.eINSTANCE.getVariableUse(), tdlPackage.eINSTANCE.getFormalParameterUse() }; dataUseContexts.references = new EReference[]{ tdlPackage.eINSTANCE.getDataInstanceUse_DataInstance(), tdlPackage.eINSTANCE.getFunctionCall_Function(), tdlPackage.eINSTANCE.getPredefinedFunctionCall_Function(), tdlPackage.eINSTANCE.getVariableUse_Variable(), tdlPackage.eINSTANCE.getFormalParameterUse_Parameter() }; alternativeContexts.put(tdlPackage.eINSTANCE.getDataUse(), dataUseContexts); } for (EClass alternativeClass: alternativeContexts.keySet()) if (alternativeClass.isInstance(contextObject)) return alternativeContexts.get(alternativeClass); return null; } } abstract class AlternativeContext { EClass[] classes; EReference[] references; abstract void copy(EObject from, EObject to); } No newline at end of file
plugins/org.etsi.mts.tdl.graphical.labels.data/src/org/etsi/mts/tdl/graphical/labels/naming/QNameProvider.java 0 → 100644 +19 −0 Original line number Original line Diff line number Diff line package org.etsi.mts.tdl.graphical.labels.naming; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider; import org.eclipse.xtext.naming.QualifiedName; import org.etsi.mts.tdl.Element; import org.etsi.mts.tdl.NamedElement; public class QNameProvider extends DefaultDeclarativeQualifiedNameProvider { @Override public QualifiedName getFullyQualifiedName(EObject obj) { if (obj instanceof NamedElement) { String name = ((Element) obj).getName(); if (name != null) return QualifiedName.create(((Element) obj).getName()); } return super.getFullyQualifiedName(obj); } }
plugins/org.etsi.mts.tdl.graphical.labels.data/src/org/etsi/mts/tdl/graphical/labels/resource/AdaptiveLinkingResource.java 0 → 100644 +28 −0 Original line number Original line Diff line number Diff line package org.etsi.mts.tdl.graphical.labels.resource; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.xtext.linking.lazy.LazyLinkingResource; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.util.Triple; public class AdaptiveLinkingResource extends LazyLinkingResource { @Override protected EObject getEObject(String uriFragment, Triple<EObject, EReference, INode> triple) throws AssertionError { List<EObject> linkedObjects = getLinkingService().getLinkedObjects( triple.getFirst(), triple.getSecond(), triple.getThird()); if (!linkedObjects.isEmpty()) { EObject newObject = linkedObjects.get(0); if (!triple.getSecond().getEType().isInstance(newObject)) { //Was replaced return null; } } return super.getEObject(uriFragment, triple); } }
plugins/org.etsi.mts.tdl.graphical.labels.data/src/org/etsi/mts/tdl/graphical/labels/scoping/ConfigurableScopeProvider.java 0 → 100644 +81 −0 Original line number Original line Diff line number Diff line package org.etsi.mts.tdl.graphical.labels.scoping; import java.util.Hashtable; import java.util.LinkedHashSet; import java.util.Map; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.resource.IResourceDescription; import org.eclipse.xtext.resource.IResourceDescriptions; import org.eclipse.xtext.resource.IResourceServiceProvider; import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider; import org.eclipse.xtext.scoping.impl.SelectableBasedScope; import org.etsi.mts.tdl.ElementImport; import org.etsi.mts.tdl.Package; import org.etsi.mts.tdl.tdlPackage; import com.google.common.base.Predicate; import com.google.inject.Inject; public class ConfigurableScopeProvider extends ImportUriGlobalScopeProvider { @Inject private IResourceServiceProvider resourceServiceProvider; private Map<URI, LinkedHashSet<URI>> importedUris = new Hashtable<URI, LinkedHashSet<URI>>(); @Override protected LinkedHashSet<URI> getImportedUris(Resource resource) { URI uri = resource.getURI(); ResourceSet rs = new ResourceSetImpl(); Resource realResource = rs.getResource(uri, true); LinkedHashSet<URI> imports = new LinkedHashSet<URI>(); importedUris.put(uri, imports); imports.add(uri); //Add resource URIs of imported packages for (EObject e: realResource.getContents()) { if (tdlPackage.eINSTANCE.getPackage().isInstance(e)) { Package p = (Package) e; addImports(p, imports); } } return imports; } private void addImports(Package p, LinkedHashSet<URI> imports) { for (ElementImport pi: p.getImport()) { Package ip = pi.getImportedPackage(); URI iUri = EcoreUtil.getURI(ip).trimFragment(); imports.add(iUri); addImports(ip, imports); } } @Override protected IScope createLazyResourceScope(IScope parent, URI uri, IResourceDescriptions descriptions, EClass type, Predicate<IEObjectDescription> filter, boolean ignoreCase) { ResourceSet rs = new ResourceSetImpl(); Resource resource = rs.getResource(uri, true); IResourceDescription description = resourceServiceProvider.getResourceDescriptionManager().getResourceDescription(resource); IScope scope = SelectableBasedScope.createScope(parent, description, filter, type, ignoreCase); return scope; } }