Commit 8a202d01 authored by Martti Käärik's avatar Martti Käärik
Browse files

Model operations implemented in Java (null-safe, proxy-tolerant and...

Model operations implemented in Java (null-safe, proxy-tolerant and cycle-safe), validated against source OCL. *ImplCustom classes override (instantiated by custom factory) the generated operations and delegate to TdlNavigation (compiled OCL kept as backup). No call site changes. Predefined and time types are found through Xtext index (replaces allInstances).
parent dac54e09
Loading
Loading
Loading
Loading
+4 −0
Changes for plugins/org.etsi.mts.tdl.TDLan2/src/org/etsi/mts/tdl/TDLan2RuntimeModule.java: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -16,4 +16,8 @@ public class TDLan2RuntimeModule extends AbstractTDLan2RuntimeModule {
		return TDLan2Formatter.class;
	}

	/** Standard-library lookup for literals/time labels through the index (no import needed). */
	public void configureIndexLibraryLookup(com.google.inject.Binder binder) {
		binder.bind(org.etsi.mts.tdl.scoping.IndexLibraryLookup.class).asEagerSingleton();
	}
}
+4 −0
Changes for plugins/org.etsi.mts.tdl.TPLan2/src/org/etsi/mts/tdl/TPLan2RuntimeModule.java: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -14,4 +14,8 @@ public class TPLan2RuntimeModule extends AbstractTPLan2RuntimeModule {
		return TPLan2Formatter.class;
	}

	/** Standard-library lookup for literals/time labels through the index (no import needed). */
	public void configureIndexLibraryLookup(com.google.inject.Binder binder) {
		binder.bind(org.etsi.mts.tdl.scoping.IndexLibraryLookup.class).asEagerSingleton();
	}
}
+75 −0
Changes for plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/IndexLibraryLookup.java: 75 added lines, 0 removed lines.
Original line number Diff line number Diff line
package org.etsi.mts.tdl.scoping;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider;
import org.etsi.mts.tdl.PackageableElement;
import org.etsi.mts.tdl.navigation.TdlNavigation;
import org.etsi.mts.tdl.tdlPackage;

import com.google.inject.Inject;
import com.google.inject.Singleton;

/**
 * Finds standard-library elements ({@code TDL.Integer}, the {@code Time} type, …)
 * through the Xtext index of the context's resource set, so that literals and
 * time labels are typed without the library being imported or already loaded
 * (see {@link TdlNavigation#libraryElement}). Installed into the model plugin's
 * hook when the language injector is created (eager singleton in the runtime
 * modules).
 */
@Singleton
public class IndexLibraryLookup implements TdlNavigation.LibraryLookup {

	@Inject
	private ResourceDescriptionsProvider descriptionsProvider;

	@Inject
	public IndexLibraryLookup() {
		TdlNavigation.setLibraryLookup(this);
	}

	@Override
	public PackageableElement find(EObject context, Class<? extends PackageableElement> kind, String name) {
		Resource resource = context == null ? null : context.eResource();
		if (resource == null || resource.getResourceSet() == null || descriptionsProvider == null) {
			return null;
		}
		EClass type = eClassOf(kind);
		if (type == null) {
			return null;
		}
		IResourceDescriptions descriptions = descriptionsProvider.getResourceDescriptions(resource.getResourceSet());
		Iterable<IEObjectDescription> candidates = name != null
				? descriptions.getExportedObjects(type, QualifiedName.create(TdlNavigation.LIBRARY_PACKAGE, name), false)
				: descriptions.getExportedObjectsByType(type);
		for (IEObjectDescription d : candidates) {
			if (name == null && !TdlNavigation.LIBRARY_PACKAGE.equals(d.getQualifiedName().getFirstSegment())) {
				continue;
			}
			EObject o = d.getEObjectOrProxy();
			if (o.eIsProxy()) {
				o = EcoreUtil.resolve(o, context);
			}
			if (kind.isInstance(o)) {
				return (PackageableElement) o;
			}
		}
		return null;
	}

	private static EClass eClassOf(Class<?> kind) {
		for (EClassifier c : tdlPackage.eINSTANCE.getEClassifiers()) {
			if (c instanceof EClass && c.getInstanceClass() == kind) {
				return (EClass) c;
			}
		}
		return null;
	}
}
+2 −1
Changes for plugins/org.etsi.mts.tdl.model.gen/META-INF/MANIFEST.MF: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -22,7 +22,8 @@ Require-Bundle: org.eclipse.core.runtime,
 org.apache.log4j;resolution:=optional,
 org.apache.commons.logging;resolution:=optional,
 org.eclipse.ocl.xtext.oclinecore,
 org.eclipse.emf.mwe2.lib
 org.eclipse.emf.mwe2.lib,
 org.eclipse.uml2.codegen.ecore
Eclipse-LazyStart: true
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.etsi.mts.tdl.Activator
+6 −9
Changes for plugins/org.etsi.mts.tdl.model.gen/src/org/etsi/mts/tdl/gen/OCLinEcoreGenerator.java: 6 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -7,9 +7,7 @@ import java.nio.file.Paths;

import org.apache.log4j.Logger;
import org.eclipse.emf.codegen.ecore.generator.Generator;
import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
import org.eclipse.emf.codegen.ecore.genmodel.generator.GenModelGeneratorAdapterFactory;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
import org.eclipse.emf.ecore.resource.ResourceSet;
@@ -59,19 +57,18 @@ public class OCLinEcoreGenerator extends EcoreGeneratorCustom {
        ResourceSet resourceSet = ocl.getResourceSet();
        setResourceSet(resourceSet);
        
        GeneratorAdapterFactory.Descriptor.Registry.INSTANCE.addDescriptor(
                GenModelPackage.eNS_URI,
                GenModelGeneratorAdapterFactory.DESCRIPTOR);          // standard EMF codegen
        GeneratorAdapterFactory.Descriptor.Registry.INSTANCE.addDescriptor(
                GenModelPackage.eNS_URI,
                OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR);        // OCL→Java compilation
        // Adapter factories are registered per generator in addAdapters(): the generator's
        // local registry hides the global one and the extension-registered plain EMF
        // factory is never called (otherwise it would generate the default files as duplicates).

        super.invoke(ctx);	
	}
	
	@Override
	protected void addAdapters() {
//		super.addAdapters();
		super.addAdapters(); // *ImplCustom aware EMF generator adapter
		generator.getAdapterFactoryDescriptorRegistry().addDescriptor(GenModelPackage.eNS_URI,
				OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR);   // OCL -> Java operation bodies
//		generator.getAdapterFactoryDescriptorRegistry().addDescriptor(
//                GenModelPackage.eNS_URI,
//                GenModelGeneratorAdapterFactory.DESCRIPTOR);          // standard EMF codegen
Loading