[573449] Detect workspace metamodels during blackbox resolution
diff --git a/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/runtime/blackbox/JdtBlackboxProvider.java b/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/runtime/blackbox/JdtBlackboxProvider.java
index 7cde9ea..a595e0e 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/runtime/blackbox/JdtBlackboxProvider.java
+++ b/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/runtime/blackbox/JdtBlackboxProvider.java
@@ -25,10 +25,14 @@
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.ecore.EPackage;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.m2m.internal.qvt.oml.QvtPlugin;
+import org.eclipse.m2m.internal.qvt.oml.blackbox.BlackboxException;
+import org.eclipse.m2m.internal.qvt.oml.blackbox.BlackboxUnit;
import org.eclipse.m2m.internal.qvt.oml.blackbox.BlackboxUnitDescriptor;
+import org.eclipse.m2m.internal.qvt.oml.blackbox.LoadContext;
import org.eclipse.m2m.internal.qvt.oml.blackbox.ResolutionContext;
import org.eclipse.m2m.internal.qvt.oml.blackbox.java.JavaBlackboxProvider;
import org.eclipse.m2m.internal.qvt.oml.emf.util.URIUtils;
@@ -40,6 +44,8 @@
private static Map<IProject, Map<String, JdtDescriptor>> descriptors = new HashMap<IProject, Map<String, JdtDescriptor>>();
+ private EPackage.Registry fPackageRegistry;
+
@Override
public Collection<? extends BlackboxUnitDescriptor> getUnitDescriptors(ResolutionContext resolutionContext) {
IProject project = getProject(resolutionContext);
@@ -251,6 +257,16 @@
return result;
}
+
+ @Override
+ public BlackboxUnit load(LoadContext context) throws BlackboxException {
+ if (fPackageRegistry != context.getMetamodelRegistry()) {
+ unload();
+ fPackageRegistry = context.getMetamodelRegistry();
+ }
+
+ return super.load(context);
+ }
}
}
diff --git a/plugins/org.eclipse.m2m.qvt.oml/META-INF/MANIFEST.MF b/plugins/org.eclipse.m2m.qvt.oml/META-INF/MANIFEST.MF
index 5481b5a..f94eb6b 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.m2m.qvt.oml/META-INF/MANIFEST.MF
@@ -106,7 +106,8 @@
org.eclipse.m2m.qvt.oml.cst.parser;bundle-version="[3.0.0,4.0.0)";visibility:=reexport,
org.eclipse.ocl.ecore;bundle-version="[3.1.0,4.0.0)";visibility:=reexport,
org.eclipse.m2m.qvt.oml.ecore.imperativeocl;bundle-version="[3.0.0,4.0.0)";visibility:=reexport,
- org.eclipse.ocl;visibility:=reexport
+ org.eclipse.ocl;visibility:=reexport,
+ org.eclipse.emf.codegen.ecore;bundle-version="[2.8.0,3.0.0)"
Eclipse-BuddyPolicy: registered
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/Java2QVTTypeResolver.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/Java2QVTTypeResolver.java
index fbb6ca9..85a33f6 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/Java2QVTTypeResolver.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/Java2QVTTypeResolver.java
@@ -20,22 +20,31 @@
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import org.eclipse.emf.codegen.ecore.genmodel.GenClassifier;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
+import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EGenericType;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypeParameter;
import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.plugin.EcorePlugin;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.m2m.internal.qvt.oml.NLS;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalModuleEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalStdLibrary;
+import org.eclipse.m2m.internal.qvt.oml.emf.util.EmfUtil;
+import org.eclipse.m2m.internal.qvt.oml.emf.util.ModelContent;
import org.eclipse.m2m.qvt.oml.blackbox.java.JavaModelInstance;
import org.eclipse.m2m.qvt.oml.util.Dictionary;
import org.eclipse.m2m.qvt.oml.util.MutableList;
@@ -233,7 +242,7 @@
SortedSet<EClassifier> subtypes = new TreeSet<EClassifier>(HIERARCHY_COMPARATOR_DESC);
SortedSet<EClassifier> supertypes = new TreeSet<EClassifier>(HIERARCHY_COMPARATOR_ASC);
-
+
Iterable<String> packageURIs = fPackageURIs.isEmpty() ? fEnv.getEPackageRegistry().keySet() : fPackageURIs;
for (String nsURI : packageURIs) {
@@ -243,15 +252,18 @@
// early return for same-named classifier
EClassifier sameNamedClassifier = ePackage.getEClassifier(type.getSimpleName());
- if (sameNamedClassifier != null && type == sameNamedClassifier.getInstanceClass()) {
- return sameNamedClassifier;
+ if (sameNamedClassifier != null) {
+ if (isMatchingInstanceClass(sameNamedClassifier, type)) {
+ return sameNamedClassifier;
+ }
}
for (EClassifier eClassifier : ePackage.getEClassifiers()) {
- Class<?> instanceClass = eClassifier.getInstanceClass();
- if(type == instanceClass) {
+ if (isMatchingInstanceClass(eClassifier, type)) {
return eClassifier;
}
+
+ Class<?> instanceClass = eClassifier.getInstanceClass();
// fall-back strategy for resolving sub/super types
if ((relationship & ALLOW_SUBTYPE) == ALLOW_SUBTYPE) {
@@ -278,7 +290,7 @@
return null;
}
-
+
private boolean isAssignableFromTo(Class<?> from, Class<?> to) {
return from != null && to != null && to.isAssignableFrom(from);
}
@@ -391,5 +403,50 @@
return null;
}
+
+ private static boolean isMatchingInstanceClass(EClassifier eClassifier, Class<?> type) {
+
+ Class<?> instanceClass = eClassifier.getInstanceClass();
+
+ if(type == instanceClass) {
+ return true;
+ }
+ else if (instanceClass == null && EmfUtil.isDynamic(eClassifier)) {
+ EPackage ePackage = eClassifier.getEPackage();
+ String nsURI = ePackage.getNsURI();
+
+ Map<String, URI> genModelMap = EcorePlugin.getEPackageNsURIToGenModelLocationMap(true);
+ URI genModelUri = genModelMap.get(nsURI);
+
+ if (genModelUri != null) {
+ ResourceSet resourceSet = ePackage.eResource().getResourceSet();
+ ModelContent genModelContent = EmfUtil.safeLoadModel(genModelUri, resourceSet);
+
+ if (genModelContent != null) {
+ Iterator<EObject> iterator = EcoreUtil.getAllContents(genModelContent.getContent());
+
+ while (iterator.hasNext()) {
+ EObject eObject = iterator.next();
+
+ if (eObject instanceof GenClassifier) {
+ GenClassifier genClassifier = (GenClassifier) eObject;
+
+ EClassifier ecoreClassifier = genClassifier.getEcoreClassifier();
+
+ if (ecoreClassifier == eClassifier) {
+ String classifierInstanceName = genClassifier.getRawInstanceClassName();
+
+ if (type.getName().equals(classifierInstanceName)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+ }
}
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxProvider.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxProvider.java
index cc000d7..8a85562 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxProvider.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxProvider.java
@@ -242,6 +242,14 @@
return unit;
}
+ protected void unload() {
+ for (Map<String, List<EOperation>> operations : fModules.values()) {
+ operations.clear();
+ }
+
+ unit = null;
+ }
+
}
}