Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsboyko2014-01-29 07:34:32 +0000
committersboyko2014-01-29 07:34:32 +0000
commitd21c22ea2ac43cdde470c99089948b12b15b4e03 (patch)
tree4cdad10a48a363843974d0f6a8f89609f6ee2c82 /plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox
parente92ca950ea3f97103251c7c9b6f18faffa34129a (diff)
downloadorg.eclipse.qvto-d21c22ea2ac43cdde470c99089948b12b15b4e03.tar.gz
org.eclipse.qvto-d21c22ea2ac43cdde470c99089948b12b15b4e03.tar.xz
org.eclipse.qvto-d21c22ea2ac43cdde470c99089948b12b15b4e03.zip
[289982] - Support concrete syntax definition of blackbox libraries
Diffstat (limited to 'plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox')
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/AbstractBlackboxProvider.java36
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/AbstractCompilationUnitDescriptor.java11
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/BlackboxRegistry.java22
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/OperationMatcher.java69
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/BlackboxResourceFactory.java11
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxMessages.java4
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxMessages.properties2
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxProvider.java77
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaMethodHandlerFactory.java36
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaModuleLoader.java16
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/OperationBuilder.java61
11 files changed, 283 insertions, 62 deletions
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/AbstractBlackboxProvider.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/AbstractBlackboxProvider.java
index 102a17d3f..e38dd5123 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/AbstractBlackboxProvider.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/AbstractBlackboxProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2009 Borland Software Corporation and others.
+ * Copyright (c) 2007, 2013 Borland Software Corporation and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,23 +8,30 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
+ * Christopher Gerking - bug 289982
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.blackbox;
+import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEvaluationEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalModuleEnv;
+import org.eclipse.m2m.internal.qvt.oml.compiler.BlackboxUnitResolver;
import org.eclipse.m2m.internal.qvt.oml.evaluator.ModuleInstance;
import org.eclipse.m2m.internal.qvt.oml.evaluator.ModuleInstanceFactory;
+import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
import org.eclipse.m2m.internal.qvt.oml.stdlib.CallHandler;
import org.eclipse.m2m.internal.qvt.oml.stdlib.CallHandlerAdapter;
public abstract class AbstractBlackboxProvider {
+
+ private static final ResolutionContext GLOBAL_RESOLUTION_CONTEXT = new ResolutionContextImpl(BlackboxUnitResolver.GLOBAL_CONTEXT);
public interface InstanceAdapterFactory {
Object createAdapter(EObject moduleInstance);
@@ -34,12 +41,7 @@ public abstract class AbstractBlackboxProvider {
super();
}
- protected String getProviderID() {
- // FIXME - avoid compilation breakage =>
- // make it abstract ensure all concrete subclasses provide concrete
- // operation
- return "unknown"; //$NON-NLS-1$
- }
+ protected abstract String getProviderID();
protected CompilationUnit createCompilationUnit(
QvtOperationalModuleEnv moduleEnv) {
@@ -85,7 +87,7 @@ public abstract class AbstractBlackboxProvider {
CallHandlerAdapter.attach(operation, actualHandler);
}
- public abstract List<AbstractCompilationUnitDescriptor> getModuleDescriptors(
+ public abstract Collection<AbstractCompilationUnitDescriptor> getModuleDescriptors(
ResolutionContext resolutionContext);
public abstract AbstractCompilationUnitDescriptor getModuleDescriptor(
@@ -94,4 +96,22 @@ public abstract class AbstractBlackboxProvider {
public abstract CompilationUnit loadCompilationUnit(
AbstractCompilationUnitDescriptor descriptor,
LoadContext loadContext) throws BlackboxException;
+
+ public Collection<CallHandler> getBlackboxCallHandler(ImperativeOperation operation, QvtOperationalModuleEnv env) {
+ Collection<CallHandler> result = Collections.emptyList();
+ for (AbstractCompilationUnitDescriptor d : getModuleDescriptors(GLOBAL_RESOLUTION_CONTEXT)) {
+ if (!env.getImportedNativeLibs().containsKey(d.getURI())) {
+ continue;
+ }
+ Collection<CallHandler> handlers = d.getBlackboxCallHandler(operation, env);
+ if (!handlers.isEmpty()) {
+ if (result.isEmpty()) {
+ result = new LinkedList<CallHandler>();
+ }
+ result.addAll(handlers);
+ }
+ }
+ return result;
+ }
+
}
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/AbstractCompilationUnitDescriptor.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/AbstractCompilationUnitDescriptor.java
index 09abf3b58..da518ab3d 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/AbstractCompilationUnitDescriptor.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/AbstractCompilationUnitDescriptor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2009 Borland Software Corporation and others.
+ * Copyright (c) 2008, 2013 Borland Software Corporation and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,10 +8,16 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
+ * Christopher Gerking - bug 289982
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.blackbox;
+import java.util.Collection;
+
import org.eclipse.emf.common.util.URI;
+import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalModuleEnv;
+import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation;
+import org.eclipse.m2m.internal.qvt.oml.stdlib.CallHandler;
@@ -72,4 +78,7 @@ public abstract class AbstractCompilationUnitDescriptor {
public String toString() {
return "Descriptor: " + fQualifiedName + " - " + getProvider().toString(); //$NON-NLS-1$ //$NON-NLS-2$
}
+
+ public abstract Collection<CallHandler> getBlackboxCallHandler(ImperativeOperation operation, QvtOperationalModuleEnv env);
+
} \ No newline at end of file
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/BlackboxRegistry.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/BlackboxRegistry.java
index d78afe658..e7f49aa1a 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/BlackboxRegistry.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/BlackboxRegistry.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2009 Borland Software Corporation and others.
+ * Copyright (c) 2008, 2013 Borland Software Corporation and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,10 +8,12 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
+ * Christopher Gerking - bug 289982
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.blackbox;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@@ -21,6 +23,9 @@ import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.m2m.internal.qvt.oml.QvtPlugin;
+import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalModuleEnv;
+import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation;
+import org.eclipse.m2m.internal.qvt.oml.stdlib.CallHandler;
/*
* TODO - handle collisions of multiple descriptors of the same qualified name
@@ -110,4 +115,19 @@ public class BlackboxRegistry {
return providers;
}
}
+
+ public Collection<CallHandler> getBlackboxCallHandler(ImperativeOperation operation, QvtOperationalModuleEnv env) {
+ Collection<CallHandler> result = Collections.emptyList();
+ for (AbstractBlackboxProvider provider : fProviders) {
+ Collection<CallHandler> handlers = provider.getBlackboxCallHandler(operation, env);
+ if (!handlers.isEmpty()) {
+ if (result.isEmpty()) {
+ result = new LinkedList<CallHandler>();
+ }
+ result.addAll(handlers);
+ }
+ }
+ return result;
+ }
+
}
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/OperationMatcher.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/OperationMatcher.java
new file mode 100644
index 000000000..7146e63d4
--- /dev/null
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/OperationMatcher.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2014 Borland Software Corporation 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:
+ * Borland Software Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.m2m.internal.qvt.oml.blackbox;
+
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEnv;
+import org.eclipse.m2m.internal.qvt.oml.ast.parser.QvtOperationalParserUtil;
+import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation;
+import org.eclipse.m2m.internal.qvt.oml.expressions.Library;
+import org.eclipse.ocl.util.TypeUtil;
+
+public class OperationMatcher {
+
+ private OperationMatcher() {
+ }
+
+ public static boolean matchOperation(QvtOperationalEnv env, ImperativeOperation imperativeOp, EOperation libraryOp) {
+
+ if (!libraryOp.getName().equals(imperativeOp.getName())) {
+ return false;
+ }
+
+ EClassifier contextType = QvtOperationalParserUtil.getContextualType(imperativeOp);
+ EClassifier owner = env.getUMLReflection().getOwningClassifier(libraryOp);
+ if (contextType == null) {
+ if (false == owner instanceof Library) {
+ return false;
+ }
+ }
+ else {
+ if (!TypeUtil.exactTypeMatch(env, contextType, owner)) {
+ return false;
+ }
+ }
+
+ if (imperativeOp.getEParameters().size() != libraryOp.getEParameters().size()) {
+ return false;
+ }
+ for (int i = 0, in = imperativeOp.getEParameters().size(); i < in; ++i) {
+ if (!TypeUtil.exactTypeMatch(env, imperativeOp.getEParameters().get(i).getEType(), libraryOp.getEParameters().get(i).getEType())) {
+ return false;
+ }
+ }
+
+ if (imperativeOp.getResult().size() == 0) {
+ if (libraryOp.getEType() != env.getOCLStandardLibrary().getOclVoid()) {
+ return false;
+ }
+ }
+ else {
+ if (!TypeUtil.exactTypeMatch(env, libraryOp.getEType(), imperativeOp.getResult().get(0).getEType())) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/BlackboxResourceFactory.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/BlackboxResourceFactory.java
index 1a91b90f0..dd70d8fe9 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/BlackboxResourceFactory.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/BlackboxResourceFactory.java
@@ -13,7 +13,6 @@ package org.eclipse.m2m.internal.qvt.oml.blackbox.java;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -26,8 +25,8 @@ import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.m2m.internal.qvt.oml.ast.binding.ASTBindingHelper;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalModuleEnv;
import org.eclipse.m2m.internal.qvt.oml.compiler.BlackboxUnitResolver;
-import org.eclipse.m2m.internal.qvt.oml.compiler.UnitProxy;
import org.eclipse.m2m.internal.qvt.oml.compiler.UnitContents.ModelContents;
+import org.eclipse.m2m.internal.qvt.oml.compiler.UnitProxy;
public class BlackboxResourceFactory implements Resource.Factory {
@@ -63,7 +62,7 @@ public class BlackboxResourceFactory implements Resource.Factory {
ModelContents contents = (ModelContents) unit.getContents();
List<EObject> topElements = contents.loadElements(rs.getPackageRegistry());
- List<QvtOperationalModuleEnv> modelEnvs = new ArrayList<QvtOperationalModuleEnv>(topElements.size());
+// List<QvtOperationalModuleEnv> modelEnvs = new ArrayList<QvtOperationalModuleEnv>(topElements.size());
for (EObject nextElement : topElements) {
QvtOperationalModuleEnv nextEnv = ASTBindingHelper.getEnvironment(nextElement, QvtOperationalModuleEnv.class);
@@ -72,10 +71,10 @@ public class BlackboxResourceFactory implements Resource.Factory {
// clear the environment problems, for now we do not consider errors
// like duplicate operation definitions to cause the importing unit to fail
nextEnv.clearProblems();
- modelEnvs.add(nextEnv);
+// modelEnvs.add(nextEnv);
- Resource resource = nextEnv.getModuleContextType().eResource();
- resource.setURI(unit.getURI());
+// Resource resource = nextEnv.getModuleContextType().eResource();
+// resource.setURI(unit.getURI());
}
}
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxMessages.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxMessages.java
index 172100188..16fb6208b 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxMessages.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxMessages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 Borland Software Corporation and others.
+ * Copyright (c) 2008, 2013 Borland Software Corporation 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
@@ -7,6 +7,7 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
+ * Christopher Gerking - bug 289982
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.blackbox.java;
@@ -19,6 +20,7 @@ public class JavaBlackboxMessages extends NLS {
public static String FirstContextualOperationParameterRequired;
public static String QvtoContextParameterRequired;
+ public static String ConstructorRequiresContextualOperation;
public static String InvalidJavaClassForModule;
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxMessages.properties b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxMessages.properties
index 5411b80f5..4ff11cdec 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxMessages.properties
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaBlackboxMessages.properties
@@ -7,10 +7,12 @@
#
# Contributors:
# Borland - initial API and implementation
+# Christopher Gerking - bug 289982
###############################################################################
BlackboxUnitLoadFailed=Failed to load java black-box unit ''{0}''
FirstContextualOperationParameterRequired=Contextual operation must declare the first parameter to provide a context. Method=''{0}''
QvtoContextParameterRequired=Operation annotated as <withExecutionContext> must declare the first parameter to provide QVTo execution context. Method=''{0}''
+ConstructorRequiresContextualOperation=Constructor operation must be annotated with <contextual=true>. Method=''{0}''
InvalidJavaClassForModule=Invalid java class ''{0}'' for black-box module ''{1}''
LoadModuleDiagnostics=Loading Java module diagnostics ''{0}''
LoadOperationDiagnostics=Loading Operation diagnostics ''{0}''
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 89d438b63..763859a03 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2009 Borland Software Corporation and others.
+ * Copyright (c) 2008, 2013 Borland Software Corporation and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,16 +8,20 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
+ * Christopher Gerking - bug 289982
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.blackbox.java;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
@@ -35,9 +39,13 @@ import org.eclipse.m2m.internal.qvt.oml.blackbox.AbstractCompilationUnitDescript
import org.eclipse.m2m.internal.qvt.oml.blackbox.BlackboxException;
import org.eclipse.m2m.internal.qvt.oml.blackbox.CompilationUnit;
import org.eclipse.m2m.internal.qvt.oml.blackbox.LoadContext;
+import org.eclipse.m2m.internal.qvt.oml.blackbox.OperationMatcher;
import org.eclipse.m2m.internal.qvt.oml.blackbox.ResolutionContext;
import org.eclipse.m2m.internal.qvt.oml.cst.CSTFactory;
+import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
+import org.eclipse.m2m.internal.qvt.oml.stdlib.CallHandler;
+import org.eclipse.m2m.internal.qvt.oml.stdlib.CallHandlerAdapter;
public class JavaBlackboxProvider extends AbstractBlackboxProvider {
@@ -58,7 +66,8 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
private static final String METAMODEL_ELEM = "metamodel"; //$NON-NLS-1$
private static final String NSURI_ATTR = "nsURI"; //$NON-NLS-1$
- private final Map<String, Descriptor> fDescriptorMap;
+ private final Map<String, AbstractCompilationUnitDescriptor> fDescriptorMap;
+ private final Map<Descriptor, CompilationUnit> fBlackboxUnits = new LinkedHashMap<Descriptor, CompilationUnit>();
public JavaBlackboxProvider() {
if(EMFPlugin.IS_ECLIPSE_RUNNING) {
@@ -80,11 +89,9 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
}
@Override
- public List<AbstractCompilationUnitDescriptor> getModuleDescriptors(ResolutionContext resolutionContext) {
+ public Collection<AbstractCompilationUnitDescriptor> getModuleDescriptors(ResolutionContext resolutionContext) {
// TODO - Should we necessarily be available in all contexts ?
- ArrayList<AbstractCompilationUnitDescriptor> result = new ArrayList<AbstractCompilationUnitDescriptor>(fDescriptorMap.size());
- result.addAll(fDescriptorMap.values());
- return Collections.unmodifiableList(result);
+ return fDescriptorMap.values();
}
@Override
@@ -92,15 +99,20 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
if(descriptor instanceof Descriptor == false) {
throw new IllegalArgumentException("Invalid descriptor"); //$NON-NLS-1$
}
-
Descriptor libDescriptor = (Descriptor) descriptor;
+
+ CompilationUnit compilationUnit = fBlackboxUnits.get(libDescriptor);
+ if (compilationUnit != null) {
+ return compilationUnit;
+ }
+
JavaModuleLoader javaModuleLoader = createJavaModuleLoader();
BasicDiagnostic errors = null;
List<QvtOperationalModuleEnv> loadedModules = new LinkedList<QvtOperationalModuleEnv>();
- for (ModuleHandle nextModuleHandle : libDescriptor.fModules) {
- Diagnostic diagnostic = javaModuleLoader.loadModule(nextModuleHandle);
+ for (Map.Entry<ModuleHandle, Map<String, List<EOperation>>> nextEntry : libDescriptor.fModules.entrySet()) {
+ Diagnostic diagnostic = javaModuleLoader.loadModule(nextEntry.getKey(), nextEntry.getValue());
if(DiagnosticUtil.isSuccess(diagnostic)) {
QvtOperationalModuleEnv nextModuleEnv = javaModuleLoader.getLoadedModule();
@@ -125,9 +137,11 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
throw new BlackboxException(errors);
}
- return createCompilationUnit(loadedModules);
+ compilationUnit = createCompilationUnit(loadedModules);
+ fBlackboxUnits.put(libDescriptor, compilationUnit);
+ return compilationUnit;
}
-
+
private JavaModuleLoader createJavaModuleLoader() {
return new JavaModuleLoader() {
JavaMethodHandlerFactory handlerFactory;
@@ -149,7 +163,7 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
}
};
}
-
+
static InstanceAdapterFactory createInstanceAdapterFactory(final Class<?> javaModuleClass) {
return new InstanceAdapterFactory() {
public Object createAdapter(EObject moduleInstance) {
@@ -157,7 +171,7 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
return javaModuleClass.newInstance();
} catch (InstantiationException e) {
// FIXME - choose a better exception
- throw new IllegalArgumentException("Illegal adapter instance", e); //$NON-NLS-1$
+ throw new IllegalArgumentException("Illegal adapter instance", e); //$NON-NLS-1$
} catch (IllegalAccessException e) {
// FIXME - choose a better exception
throw new IllegalArgumentException("Illegal adapter instance", e); //$NON-NLS-1$
@@ -166,8 +180,8 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
};
}
- private Map<String, Descriptor> readDescriptors() {
- Map<String, Descriptor> providers = new HashMap<String, Descriptor>();
+ private Map<String, AbstractCompilationUnitDescriptor> readDescriptors() {
+ Map<String, AbstractCompilationUnitDescriptor> providers = new HashMap<String, AbstractCompilationUnitDescriptor>();
IConfigurationElement[] configs = Platform.getExtensionRegistry()
.getConfigurationElementsFor(QvtPlugin.ID, EXTENSION_POINT);
@@ -232,7 +246,7 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
}
private class Descriptor extends AbstractCompilationUnitDescriptor {
- private List<ModuleHandle> fModules = Collections.emptyList();
+ private Map<ModuleHandle, Map<String, List<EOperation>>> fModules = Collections.emptyMap();
private String fContributingBundleId;
Descriptor(IConfigurationElement configurationElement, String unitQualifiedName, String description) {
@@ -250,6 +264,33 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
}
}
}
+
+ public Collection<CallHandler> getBlackboxCallHandler(ImperativeOperation imperativeOp, QvtOperationalModuleEnv env) {
+ Set<String> importedLibs = env.getImportedNativeLibs().get(getURI());
+ Collection<CallHandler> result = Collections.emptyList();
+
+ for(Map.Entry<ModuleHandle, Map<String, List<EOperation>>> nextEntry : fModules.entrySet()) {
+ if (!importedLibs.contains(nextEntry.getKey().getModuleName())) {
+ continue;
+ }
+
+ List<EOperation> listOp = nextEntry.getValue().get(imperativeOp.getName());
+ if (listOp == null) {
+ continue;
+ }
+
+ for (EOperation libraryOp : listOp) {
+ if (OperationMatcher.matchOperation(env, imperativeOp, libraryOp)) {
+ if (result.isEmpty()) {
+ result = new LinkedList<CallHandler>();
+ }
+ result.add(CallHandlerAdapter.getDispatcher(libraryOp));
+ }
+ }
+ }
+
+ return result;
+ }
String getContributorId() {
return fContributingBundleId;
@@ -257,7 +298,7 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
private void addModuleHandle(IConfigurationElement moduleElement) {
if(fModules.isEmpty()) {
- fModules = new LinkedList<ModuleHandle>();
+ fModules = new LinkedHashMap<ModuleHandle, Map<String, List<EOperation>>>();
}
String bundleId = moduleElement.getContributor().getName();
@@ -269,7 +310,7 @@ public class JavaBlackboxProvider extends AbstractBlackboxProvider {
}
ModuleHandle moduleHandle = new BundleModuleHandle(bundleId, className, moduleName, readUsedPackagesNsURIs(moduleElement));
- fModules.add(moduleHandle);
+ fModules.put(moduleHandle, new LinkedHashMap<String, List<EOperation>>());
}
private List<String> readUsedPackagesNsURIs(IConfigurationElement moduleConfigElement) {
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaMethodHandlerFactory.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaMethodHandlerFactory.java
index b22e1c9ca..b93d32f23 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaMethodHandlerFactory.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaMethodHandlerFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2010 Borland Software Corporation and others.
+ * Copyright (c) 2008, 2013 Borland Software Corporation and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,6 +8,7 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
+ * Christopher Gerking - bug 289982
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.blackbox.java;
@@ -24,6 +25,7 @@ import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEvaluationEnv;
import org.eclipse.m2m.internal.qvt.oml.evaluator.ModuleInstance;
import org.eclipse.m2m.internal.qvt.oml.evaluator.NumberConversions;
import org.eclipse.m2m.internal.qvt.oml.evaluator.QvtRuntimeException;
+import org.eclipse.m2m.internal.qvt.oml.evaluator.TransformationInstance;
import org.eclipse.m2m.internal.qvt.oml.stdlib.CallHandler;
import org.eclipse.m2m.internal.qvt.oml.stdlib.CallHandlerAdapter;
import org.eclipse.m2m.qvt.oml.blackbox.java.Operation;
@@ -86,7 +88,7 @@ class JavaMethodHandlerFactory {
boolean isStatic = Modifier.isStatic(fMethod.getModifiers());
if(!isStatic) {
Class<?> moduleJavaClass = fMethod.getDeclaringClass();
- javaCallSource = module.getAdapter(moduleJavaClass);
+ javaCallSource = getJavaCallSource(module, moduleJavaClass, evalEnv); //module.getAdapter(moduleJavaClass);
assert javaCallSource != null;
}
@@ -105,7 +107,14 @@ class JavaMethodHandlerFactory {
evalEnv.getAdapter(InternalEvaluationEnv.class).throwQVTException(
new QvtRuntimeException(NLS.bind(JavaBlackboxMessages.MethodInvocationError, fMethod), e));
return CallHandlerAdapter.getInvalidResult(evalEnv);
- }
+ }
+ catch (InstantiationException e) {
+ fFatalErrorCount++;
+ QvtPlugin.error(NLS.bind(JavaBlackboxMessages.MethodInvocationError, fMethod), e);
+ evalEnv.getAdapter(InternalEvaluationEnv.class).throwQVTException(
+ new QvtRuntimeException(NLS.bind(JavaBlackboxMessages.MethodInvocationError, fMethod), e));
+ return CallHandlerAdapter.getInvalidResult(evalEnv);
+ }
catch (InvocationTargetException e) {
fFatalErrorCount++;
QvtPlugin.error(NLS.bind(JavaBlackboxMessages.MethodInvocationError, fMethod), e.getTargetException());
@@ -119,6 +128,27 @@ class JavaMethodHandlerFactory {
clearArguments();
}
}
+
+ private Object getJavaCallSource(ModuleInstance moduleInstance, Class<?> javaClass, QvtOperationalEvaluationEnv evalEnv)
+ throws IllegalAccessException, InstantiationException {
+
+ Object callSource = moduleInstance.getAdapter(javaClass);
+ if (callSource != null) {
+ return callSource;
+ }
+
+ TransformationInstance rootTransformation = evalEnv.getRoot().getAdapter(InternalEvaluationEnv.class).getCurrentTransformation();
+
+ callSource = rootTransformation.getAdapter(javaClass);
+ if (callSource == null) {
+ callSource = javaClass.newInstance();
+ rootTransformation.getAdapter(ModuleInstance.Internal.class).addAdapter(callSource);
+ }
+
+ moduleInstance.getAdapter(ModuleInstance.Internal.class).addAdapter(callSource);
+
+ return callSource;
+ }
boolean isDisabled() {
return fFatalErrorCount > FAILURE_COUNT_TOLERANCE;
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaModuleLoader.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaModuleLoader.java
index 83f00233f..2d877ce8b 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaModuleLoader.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/JavaModuleLoader.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2009 Borland Software Corporation and others.
+ * Copyright (c) 2008, 2013 Borland Software Corporation and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,6 +8,7 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
+ * Christopher Gerking - bug 289982
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.blackbox.java;
@@ -15,7 +16,9 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
@@ -46,7 +49,7 @@ abstract class JavaModuleLoader {
return (fDiagnostics != null) ? fDiagnostics : Diagnostic.OK_INSTANCE;
}
- public Diagnostic loadModule(ModuleHandle moduleHandle) {
+ public Diagnostic loadModule(ModuleHandle moduleHandle, Map<String, List<EOperation>> definedOperations) {
fDiagnostics = DiagnosticUtil.createRootDiagnostic(NLS.bind(JavaBlackboxMessages.LoadModuleDiagnostics, moduleHandle));
Class<?> javaClass;
try {
@@ -82,6 +85,13 @@ abstract class JavaModuleLoader {
Diagnostic operationStatus = fOperBuilder.getDiagnostics();
if(DiagnosticUtil.isSuccess(operationStatus)) {
loadOperation(operation, method);
+
+ List<EOperation> listOp = definedOperations.get(operation.getName());
+ if (listOp == null) {
+ listOp = new LinkedList<EOperation>();
+ definedOperations.put(operation.getName(), listOp);
+ }
+ listOp.add(operation);
}
if(operationStatus.getSeverity() != Diagnostic.OK) {
@@ -95,7 +105,7 @@ abstract class JavaModuleLoader {
protected abstract void loadModule(QvtOperationalModuleEnv moduleEnv, Class<?> javaModule);
protected abstract void loadOperation(EOperation eOperation, Method javaOperation);
- private boolean isLibraryOperation(Method method) {
+ private static boolean isLibraryOperation(Method method) {
return Modifier.isPublic(method.getModifiers());
}
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/OperationBuilder.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/OperationBuilder.java
index 5a195448b..9d53b33c3 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/OperationBuilder.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/OperationBuilder.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2010 Borland Software Corporation and others.
+ * Copyright (c) 2008, 2013 Borland Software Corporation and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,6 +8,7 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
+ * Christopher Gerking - bug 289982
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.blackbox.java;
@@ -29,8 +30,8 @@ import org.eclipse.m2m.internal.qvt.oml.expressions.Helper;
import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation;
import org.eclipse.m2m.internal.qvt.oml.expressions.VarParameter;
import org.eclipse.m2m.qvt.oml.blackbox.java.Operation;
-import org.eclipse.m2m.qvt.oml.blackbox.java.Parameter;
import org.eclipse.m2m.qvt.oml.blackbox.java.Operation.Kind;
+import org.eclipse.m2m.qvt.oml.blackbox.java.Parameter;
import org.eclipse.m2m.qvt.oml.util.IContext;
import org.eclipse.ocl.Environment;
@@ -73,24 +74,33 @@ class OperationBuilder {
method), method);
}
- Operation.Kind operKind = (operAnnotation != null) ? operAnnotation.kind() : Operation.Kind.OPERATION;
- if(operKind == Kind.OPERATION) {
- // FIXME - avoid this, create typedef on the keeping this operation instead
- operKind = Kind.HELPER;
- }
+ Operation.Kind operKind = getOperationKind(operAnnotation);
- EOperation operation;
- if(operKind == Kind.OPERATION) {
- operation = EcoreFactory.eINSTANCE.createEOperation();
- } else if(operKind == Kind.QUERY || operKind == Kind.HELPER) {
- Helper helper = ExpressionsFactory.eINSTANCE.createHelper();
- helper.setIsQuery(operKind == Kind.QUERY);
- operation = helper;
- } else {
- assert false : "unsupported operation kind"; //$NON-NLS-1$
- operation = EcoreFactory.eINSTANCE.createEOperation();
- }
-
+ EOperation operation = null;
+ switch (operKind) {
+ case OPERATION:
+ operation = EcoreFactory.eINSTANCE.createEOperation();
+ break;
+ case MAPPING:
+ operation = ExpressionsFactory.eINSTANCE.createMappingOperation();
+ break;
+ case CONSTRUCTOR:
+ if (!isContextual) {
+ reportError(NLS.bind(JavaBlackboxMessages.ConstructorRequiresContextualOperation, method.getName()), method);
+ }
+ operation = ExpressionsFactory.eINSTANCE.createConstructor();
+ break;
+ case QUERY: case HELPER:
+ Helper helper = ExpressionsFactory.eINSTANCE.createHelper();
+ helper.setIsQuery(operKind == Kind.QUERY);
+ operation = helper;
+ break;
+ default:
+ assert false : "unsupported operation kind"; //$NON-NLS-1$
+ operation = EcoreFactory.eINSTANCE.createEOperation();
+ break;
+ }
+
operation.setName(name);
operation.setEType(fTypeResolver.toEClassifier(resultType));
if(operation.getEType() == null) {
@@ -150,9 +160,18 @@ class OperationBuilder {
} else if(contextType != null) {
environment.getTypeResolver().resolveAdditionalOperation(contextType, operation);
}
-
+
return operation;
- }
+ }
+
+ static Kind getOperationKind(Operation operAnnotation) {
+ Operation.Kind operKind = (operAnnotation != null) ? operAnnotation.kind() : Operation.Kind.OPERATION;
+ if(operKind == Kind.OPERATION) {
+ // FIXME - avoid this, create typedef on the keeping this operation instead
+ operKind = Kind.HELPER;
+ }
+ return operKind;
+ }
private static Parameter getParameterAnnotation(Annotation[] allAnnotations) {
for (Annotation annotation : allAnnotations) {

Back to the top