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
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')
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/schema/javaBlackboxUnits.exsd34
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/QvtEnvironmentBase.java41
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/TypeCheckerImpl.java3
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalParserUtil.java102
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalUtil.java4
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalValidationVisitor.java4
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalVisitorCS.java120
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.java12
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.properties12
-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
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/compiler/BlackboxUnitResolver.java4
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/compiler/CompiledUnit.java37
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/EvaluationMessages.java5
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/QvtOperationalEvaluationVisitorImpl.java100
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/messages.properties5
-rw-r--r--plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/qvt/oml/blackbox/java/Operation.java13
26 files changed, 669 insertions, 172 deletions
diff --git a/plugins/org.eclipse.m2m.qvt.oml/schema/javaBlackboxUnits.exsd b/plugins/org.eclipse.m2m.qvt.oml/schema/javaBlackboxUnits.exsd
index 1fb45187e..a903920d4 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/schema/javaBlackboxUnits.exsd
+++ b/plugins/org.eclipse.m2m.qvt.oml/schema/javaBlackboxUnits.exsd
@@ -2,9 +2,9 @@
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.m2m.qvt.oml" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
- <appinfo>
+ <appInfo>
<meta.schema plugin="org.eclipse.m2m.qvt.oml" id="javaBlackboxUnits" name="Java black-box units"/>
- </appinfo>
+ </appInfo>
<documentation>
This extension point provides a mechanism for contributing QVT black-box units. Conceptually, it corresponds to QVT compilation units (OMG spec 7.13.1), though it rather represents sort of deployment unit as there is no concrete syntax source file to compile. Instead, the source is represented by a Java class, which realizes the top level unit elements using Java language constructs mapped to corresponding QVT counterpart elements.&lt;/br&gt;&lt;/br&gt;
See the details on the Java implementation class format at &lt;a href=&quot;../blackboxing.html&quot;&gt;Java black-box to QVT mappings&lt;/a&gt;.
@@ -13,9 +13,9 @@ See the details on the Java implementation class format at &lt;a href=&quot;../b
<element name="extension">
<annotation>
- <appinfo>
+ <appInfo>
<meta.element />
- </appinfo>
+ </appInfo>
<documentation>
Extension point to register QVT black-box unit of Java implementations
</documentation>
@@ -46,9 +46,9 @@ See the details on the Java implementation class format at &lt;a href=&quot;../b
<documentation>
</documentation>
- <appinfo>
+ <appInfo>
<meta.attribute translatable="true"/>
- </appinfo>
+ </appInfo>
</annotation>
</attribute>
</complexType>
@@ -61,7 +61,7 @@ See the details on the Java implementation class format at &lt;a href=&quot;../b
</documentation>
</annotation>
<complexType>
- <sequence>
+ <sequence minOccurs="1" maxOccurs="unbounded">
<element ref="library"/>
</sequence>
<attribute name="name" type="string" use="required">
@@ -84,9 +84,9 @@ Along with the &lt;b&gt;name&lt;/b&gt;, it composes the qualified name of the un
<documentation>
A textual description of this unit element, typically used by a tooling support
</documentation>
- <appinfo>
+ <appInfo>
<meta.attribute translatable="true"/>
- </appinfo>
+ </appInfo>
</annotation>
</attribute>
</complexType>
@@ -116,9 +116,9 @@ Corresponding implicit unit is synthesized based on the implementation class and
<documentation>
The implementation class of the library (see &lt;a href=&quot;../blackboxing.html&quot;&gt;Java black-box to QVT mappings&lt;/a&gt;)
</documentation>
- <appinfo>
+ <appInfo>
<meta.attribute kind="java"/>
- </appinfo>
+ </appInfo>
</annotation>
</attribute>
</complexType>
@@ -142,18 +142,18 @@ Corresponding implicit unit is synthesized based on the implementation class and
</element>
<annotation>
- <appinfo>
+ <appInfo>
<meta.section type="since"/>
- </appinfo>
+ </appInfo>
<documentation>
2.0
</documentation>
</annotation>
<annotation>
- <appinfo>
+ <appInfo>
<meta.section type="examples"/>
- </appinfo>
+ </appInfo>
<documentation>
&lt;p&gt;
The following examples registers the &lt;code&gt;ExampleJavaLib&lt;/code&gt; black-box unit, which is resolvable as
@@ -178,9 +178,9 @@ The library operation reference types defined in the &lt;code&gt;Ecore&lt;/code&
<annotation>
- <appinfo>
+ <appInfo>
<meta.section type="copyright"/>
- </appinfo>
+ </appInfo>
<documentation>
Copyright (c) 2008 Borland Software Corporation
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/QvtEnvironmentBase.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/QvtEnvironmentBase.java
index 4e040f9f6..7edac866b 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/QvtEnvironmentBase.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/QvtEnvironmentBase.java
@@ -17,14 +17,17 @@ import static org.eclipse.ocl.utilities.UMLReflection.SAME_TYPE;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import lpg.runtime.ParseErrorCodes;
import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
@@ -113,7 +116,8 @@ public abstract class QvtEnvironmentBase extends EcoreEnvironment implements QVT
private QVTUMLReflection fQVUMLReflection;
private List<QvtEnvironmentBase> fByAccess;
private List<QvtEnvironmentBase> fByExtension;
- private List<QvtEnvironmentBase> fAllExtendedModuleEnvs;
+ private List<QvtEnvironmentBase> fAllExtendedModuleEnvs;
+ private Map<URI, Set<String>> fImportedNativeLibs;
private Set<EOperation> fOperationsHolder;
protected QvtEnvironmentBase(QvtEnvironmentBase parent) {
@@ -414,7 +418,7 @@ public abstract class QvtEnvironmentBase extends EcoreEnvironment implements QVT
}
if(importedEnv == null || importedEnv == this || isOneOfParents(importedEnv)) {
- throw new IllegalArgumentException("Illegal import environemnt"); //$NON-NLS-1$
+ throw new IllegalArgumentException("Illegal import environment: " + String.valueOf(importedEnv)); //$NON-NLS-1$
}
List<QvtEnvironmentBase> container;
@@ -430,6 +434,7 @@ public abstract class QvtEnvironmentBase extends EcoreEnvironment implements QVT
container = fByExtension;
fAllExtendedModuleEnvs = null;
}
+ fImportedNativeLibs = null;
assert container != null;
container.add(importedEnv);
@@ -475,6 +480,38 @@ public abstract class QvtEnvironmentBase extends EcoreEnvironment implements QVT
return fByExtension != null ? fByExtension : Collections.<QvtEnvironmentBase>emptyList();
}
+
+ public Map<URI, Set<String>> getImportedNativeLibs() {
+ QvtEnvironmentBase rootEnv = getRootEnv();
+ if(rootEnv != this) {
+ return rootEnv.getImportedNativeLibs();
+ }
+
+ if(fImportedNativeLibs == null) {
+ Collection<QvtEnvironmentBase> imports = new LinkedHashSet<QvtEnvironmentBase>();
+ imports.addAll(getImportsByExtends());
+ imports.addAll(getImportsByAccess());
+
+ Map<URI, Set<String>> result = new LinkedHashMap<URI, Set<String>>(imports.size());
+ for (QvtEnvironmentBase sibling : imports) {
+ Module module = sibling.getModuleContextType();
+ if (module == null || module.eResource() == null) {
+ continue;
+ }
+ URI uri = module.eResource().getURI();
+ Set<String> names = result.get(uri);
+ if (names == null) {
+ names = new LinkedHashSet<String>();
+ result.put(uri, names);
+ }
+ names.add(module.getName());
+ }
+
+ fImportedNativeLibs = Collections.unmodifiableMap(result);
+ }
+
+ return fImportedNativeLibs;
+ }
protected final CollisionStatus findCollidingOperation(EClassifier ownerType, ImperativeOperation operation) {
try {
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/TypeCheckerImpl.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/TypeCheckerImpl.java
index a88bce809..d97132ebc 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/TypeCheckerImpl.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/TypeCheckerImpl.java
@@ -206,6 +206,9 @@ class TypeCheckerImpl extends AbstractTypeChecker<EClassifier, EOperation, EStru
if(type1 == type2) {
return UMLReflection.SAME_TYPE;
}
+ if (type1 == null) {
+ return UMLReflection.UNRELATED_TYPE;
+ }
boolean isList1 = type1 instanceof ListType;
boolean isList2 = type2 instanceof ListType;
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalParserUtil.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalParserUtil.java
index 25491c796..d25cec02e 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalParserUtil.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalParserUtil.java
@@ -8,6 +8,7 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
+ * Christopher Gerking - bug 289982
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.ast.parser;
@@ -41,11 +42,16 @@ import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtEnvironmentBase;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalStdLibrary;
import org.eclipse.m2m.internal.qvt.oml.compiler.CompiledUnit;
+import org.eclipse.m2m.internal.qvt.oml.cst.ConstructorCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ImportCS;
import org.eclipse.m2m.internal.qvt.oml.cst.LibraryCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingDeclarationCS;
+import org.eclipse.m2m.internal.qvt.oml.cst.MappingExtensionCS;
+import org.eclipse.m2m.internal.qvt.oml.cst.MappingExtensionKindCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingMethodCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingModuleCS;
+import org.eclipse.m2m.internal.qvt.oml.cst.MappingQueryCS;
+import org.eclipse.m2m.internal.qvt.oml.cst.MappingRuleCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ModelTypeCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ModulePropertyCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ScopedNameCS;
@@ -56,7 +62,6 @@ import org.eclipse.m2m.internal.qvt.oml.expressions.ContextualProperty;
import org.eclipse.m2m.internal.qvt.oml.expressions.DirectionKind;
import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation;
import org.eclipse.m2m.internal.qvt.oml.expressions.ImportKind;
-import org.eclipse.m2m.internal.qvt.oml.expressions.MappingOperation;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
import org.eclipse.m2m.internal.qvt.oml.expressions.ModuleImport;
import org.eclipse.m2m.internal.qvt.oml.expressions.VarParameter;
@@ -71,6 +76,7 @@ import org.eclipse.ocl.cst.SimpleNameCS;
import org.eclipse.ocl.cst.TupleTypeCS;
import org.eclipse.ocl.cst.TypeCS;
import org.eclipse.ocl.cst.VariableCS;
+import org.eclipse.ocl.cst.impl.CSTNodeImpl;
import org.eclipse.ocl.ecore.CallOperationAction;
import org.eclipse.ocl.ecore.CollectionType;
import org.eclipse.ocl.ecore.Constraint;
@@ -93,7 +99,7 @@ public class QvtOperationalParserUtil {
private static final String NAMESPACE_SEPARATOR = "."; //$NON-NLS-1$
public static final String QVT_NAMESPACE_URI = "http://www.eclipse.org/m2m/1.0.0/QVT"; //$NON-NLS-1$
- private static final String QVT_IS_ABSTACT = "abstract"; //$NON-NLS-1$
+ private static final String QVT_IS_ABSTRACT = "abstract"; //$NON-NLS-1$
private static final String QVT_IS_STATIC = "static"; //$NON-NLS-1$
private static final String QVT_INIT_EXPRESSION_URI = QVT_NAMESPACE_URI + "/initExp"; //$NON-NLS-1$
@@ -547,18 +553,18 @@ public class QvtOperationalParserUtil {
return context instanceof EClass;
}
- public static String safeGetMappingQualifiedName(QvtOperationalEnv env, MappingOperation mappingOperation) {
- if(mappingOperation != null) {
+ public static String safeGetMappingQualifiedName(QvtOperationalEnv env, ImperativeOperation operation) {
+ if(operation != null) {
StringBuilder buf = new StringBuilder();
- EClassifier ctxType = getContextualType(mappingOperation);
+ EClassifier ctxType = getContextualType(operation);
if(ctxType != null) {
buf.append(safeGetQualifiedName(env, ctxType));
buf.append(EmfUtil.PATH_SEPARATOR);
}
- if(mappingOperation.getName() != null) {
- buf.append(mappingOperation.getName());
+ if(operation.getName() != null) {
+ buf.append(operation.getName());
}
return buf.toString();
@@ -663,17 +669,17 @@ public class QvtOperationalParserUtil {
return null;
}
- public static void markAsAbstractMappingOperation(MappingOperation mappingOperation) {
+ static void markAsAbstractOperation(ImperativeOperation operation) {
EAnnotation annotation = EcoreFactory.eINSTANCE.createEAnnotation();
annotation.setSource(QVT_NAMESPACE_URI);
- annotation.getDetails().put(QVT_IS_ABSTACT, Boolean.toString(true));
- mappingOperation.getEAnnotations().add(annotation);
+ annotation.getDetails().put(QVT_IS_ABSTRACT, Boolean.toString(true));
+ operation.getEAnnotations().add(annotation);
}
- public static boolean isAbstractMappingOperation(MappingOperation mappingOperation) {
- EAnnotation annotation = mappingOperation.getEAnnotation(QVT_NAMESPACE_URI);
+ static boolean isAbstractOperation(ImperativeOperation operation) {
+ EAnnotation annotation = operation.getEAnnotation(QVT_NAMESPACE_URI);
if(annotation != null) {
- String value = annotation.getDetails().get(QVT_IS_ABSTACT);
+ String value = annotation.getDetails().get(QVT_IS_ABSTRACT);
return Boolean.valueOf(value);
}
return false;
@@ -706,16 +712,62 @@ public class QvtOperationalParserUtil {
return cstNode;
}
- public static CSTNode getImperativeOperationProblemNode(MappingMethodCS methodCS) {
+ public static CSTNode getMethodNameProblemNodeCS(MappingMethodCS methodCS) {
MappingDeclarationCS mappingDeclCS = methodCS.getMappingDeclarationCS();
if(mappingDeclCS != null) {
+ final int pos[] = {mappingDeclCS.getStartOffset(), mappingDeclCS.getEndOffset()};
+
+ if(mappingDeclCS.getContextType() != null) {
+ pos[0] = mappingDeclCS.getContextType().getStartOffset();
+ pos[1] = mappingDeclCS.getContextType().getEndOffset();
+ }
+
if(mappingDeclCS.getSimpleNameCS() != null) {
- return mappingDeclCS.getSimpleNameCS();
+ pos[1] = mappingDeclCS.getSimpleNameCS().getEndOffset();
}
+ return new CSTNodeImpl() {
+ @Override
+ public int getStartOffset() {
+ return pos[0];
+ }
+ @Override
+ public int getEndOffset() {
+ return pos[1];
+ }
+ };
+ }
+ return methodCS;
+ }
+
+ public static CSTNode getMethodHeaderProblemNodeCS(MappingMethodCS methodCS) {
+ MappingDeclarationCS mappingDeclCS = methodCS.getMappingDeclarationCS();
+ if(mappingDeclCS != null) {
+ final int pos[] = {mappingDeclCS.getStartOffset(), mappingDeclCS.getEndOffset()};
+
if(mappingDeclCS.getContextType() != null) {
- return mappingDeclCS.getContextType();
+ pos[1] = mappingDeclCS.getContextType().getEndOffset();
}
+ if(mappingDeclCS.getSimpleNameCS() != null) {
+ pos[1] = mappingDeclCS.getSimpleNameCS().getEndOffset();
+ }
+ if(!mappingDeclCS.getParameters().isEmpty()) {
+ pos[1] = mappingDeclCS.getParameters().get(mappingDeclCS.getParameters().size()-1).getEndOffset();
+ }
+ if(!mappingDeclCS.getResult().isEmpty()) {
+ pos[1] = mappingDeclCS.getResult().get(mappingDeclCS.getResult().size()-1).getEndOffset();
+ }
+
+ return new CSTNodeImpl() {
+ @Override
+ public int getStartOffset() {
+ return pos[0];
+ }
+ @Override
+ public int getEndOffset() {
+ return pos[1];
+ }
+ };
}
return methodCS;
}
@@ -818,5 +870,23 @@ public class QvtOperationalParserUtil {
}
return result;
}
+
+ public static boolean hasOperationBody(MappingMethodCS methodCS) {
+ return
+ (methodCS instanceof MappingRuleCS && ((MappingRuleCS) methodCS).getMappingBody() != null) ||
+ (methodCS instanceof ConstructorCS && !((ConstructorCS) methodCS).getExpressions().isEmpty()) ||
+ (methodCS instanceof MappingQueryCS && !((MappingQueryCS) methodCS).getExpressions().isEmpty()) ||
+ (methodCS instanceof ConstructorCS && !((ConstructorCS) methodCS).getExpressions().isEmpty());
+ }
+
+ public static boolean isDisjunctiveMappingOperation(MappingMethodCS methodCS) {
+ for (MappingExtensionCS extensionCS : methodCS.getMappingDeclarationCS().getMappingExtension()) {
+ if(extensionCS.getKind() == MappingExtensionKindCS.DISJUNCTS) {
+ return true;
+ }
+ }
+
+ return false;
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalUtil.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalUtil.java
index f2f8eb684..6e67538a9 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalUtil.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalUtil.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
@@ -147,7 +147,7 @@ public class QvtOperationalUtil {
return false;
}
- public static boolean hasAbstractOutputParamerter(ImperativeOperation operation) {
+ public static boolean hasAbstractOutputParameter(ImperativeOperation operation) {
for (VarParameter nextParam : operation.getResult()) {
if(nextParam.getEType() != null && isAbstract(nextParam.getEType())) {
return true;
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalValidationVisitor.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalValidationVisitor.java
index 0b8103f95..818424f7d 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalValidationVisitor.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalValidationVisitor.java
@@ -431,8 +431,8 @@ public class QvtOperationalValidationVisitor extends QvtOperationalAstWalker {
if(mappingCallExp.getReferredOperation() instanceof MappingOperation) {
MappingOperation mappingOperation = (MappingOperation) mappingCallExp.getReferredOperation();
- if(QvtOperationalUtil.hasAbstractOutputParamerter(mappingOperation) &&
- QvtOperationalParserUtil.isAbstractMappingOperation(mappingOperation) &&
+ if(QvtOperationalUtil.hasAbstractOutputParameter(mappingOperation) &&
+ QvtOperationalParserUtil.isAbstractOperation(mappingOperation) &&
mappingOperation.getDisjunct().isEmpty()) {
String errMessage = NLS.bind(ValidationMessages.directCallToAbstractMappingDisallowed,
QvtOperationalParserUtil.safeGetMappingQualifiedName(fEnv, mappingOperation));
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalVisitorCS.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalVisitorCS.java
index 606da4440..ba559c1ef 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalVisitorCS.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalVisitorCS.java
@@ -7,7 +7,7 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
- * Christopher Gerking - bugs 302594, 310991
+ * Christopher Gerking - bugs 302594, 310991, 289982
* Alex Paperno - bugs 272869, 268636, 404647, 414363, 414363, 401521,
* 419299, 414619, 403440, 415024, 420970, 413391
*******************************************************************************/
@@ -57,6 +57,7 @@ import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalFileEnv;
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.blackbox.BlackboxRegistry;
import org.eclipse.m2m.internal.qvt.oml.compiler.CompilerMessages;
import org.eclipse.m2m.internal.qvt.oml.compiler.QvtCompilerOptions;
import org.eclipse.m2m.internal.qvt.oml.compiler.UnitProxy;
@@ -2209,29 +2210,56 @@ public class QvtOperationalVisitorCS
}
// process operation qualifiers
- EList<QualifierKindCS> qualifiersCS = (methodCS.getMappingDeclarationCS() == null) ? null
+ List<QualifierKindCS> qualifiersCS = (methodCS.getMappingDeclarationCS() == null) ? Collections.<QualifierKindCS>emptyList()
: methodCS.getMappingDeclarationCS().getQualifiers();
- if(imperativeOp instanceof MappingOperation) {
- if (qualifiersCS != null) {
- for (QualifierKindCS nextQualifierCS : qualifiersCS) {
- if(nextQualifierCS != QualifierKindCS.ABSTRACT) {
- // only 'abstract' qualifier for mapping is currently supported
- String errMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_unsupportedQualifierOnOperation,
- nextQualifierCS.getName(), QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));
- env.reportError(errMessage, QvtOperationalParserUtil.getImperativeOperationProblemNode(methodCS));
- } else {
- QvtOperationalParserUtil.markAsAbstractMappingOperation((MappingOperation) imperativeOp);
- }
- }
- }
- }
+ for (QualifierKindCS nextQualifierCS : qualifiersCS) {
+ switch (nextQualifierCS) {
+ case ABSTRACT:
+ if(imperativeOp instanceof MappingOperation) {
+ QvtOperationalParserUtil.markAsAbstractOperation(imperativeOp);
+ }
+ if(imperativeOp instanceof Constructor) {
+ // only 'blackbox' qualifier for constructor is currently supported
+ String errMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_unsupportedQualifierOnConstructor, nextQualifierCS.getName(),
+ QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));
+ env.reportWarning(errMessage, QvtOperationalParserUtil.getMethodNameProblemNodeCS(methodCS));
+ }
+ break;
+ case BLACKBOX:
+ if (QvtOperationalParserUtil.hasOperationBody(methodCS)) {
+ if(imperativeOp instanceof Constructor) {
+ String errMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_blackboxConstructorWithBodyNotAllowed,
+ QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));
+ env.reportError(errMessage, QvtOperationalParserUtil.getMethodHeaderProblemNodeCS(methodCS));
+ }
+ else {
+ String errMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_blackboxOperationWithBodyNotAllowed,
+ QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));
+ env.reportError(errMessage, QvtOperationalParserUtil.getMethodHeaderProblemNodeCS(methodCS));
+ }
+ }
+ if (QvtOperationalParserUtil.isDisjunctiveMappingOperation(methodCS)) {
+ String errMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_unsupportedBlackboxQualifierOnDisjunctiveMapping,
+ QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));
+ env.reportError(errMessage, QvtOperationalParserUtil.getMethodNameProblemNodeCS(methodCS));
+ }
+ imperativeOp.setIsBlackbox(true);
+ break;
+ case STATIC:
+ String msg = (imperativeOp instanceof Constructor) ? ValidationMessages.QvtOperationalVisitorCS_unsupportedQualifierOnConstructor
+ : ValidationMessages.QvtOperationalVisitorCS_unsupportedQualifierOnOperation;
+ String errMessage = NLS.bind(msg, nextQualifierCS.getName(), QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));
+ env.reportWarning(errMessage, QvtOperationalParserUtil.getMethodNameProblemNodeCS(methodCS));
+ break;
+ }
+ }
Collection<QualifierKindCS> qualifierDups = QvtOperationalParserUtil.selectDuplicateQualifiers(qualifiersCS);
for(QualifierKindCS duplicate : qualifierDups) {
String errMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_duplicateQualifierOnOperation,
duplicate.getName(), QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));
- env.reportError(errMessage, QvtOperationalParserUtil.getImperativeOperationProblemNode(methodCS));
+ env.reportError(errMessage, QvtOperationalParserUtil.getMethodNameProblemNodeCS(methodCS));
}
if(myCompilerOptions.isGenerateCompletionData()) {
@@ -3535,6 +3563,20 @@ public class QvtOperationalVisitorCS
else {
visitMappingQueryCS((MappingQueryCS) methodCS, env, methodEnv, declaredOperation);
}
+
+ if(declaredOperation.isIsBlackbox() && !QvtOperationalParserUtil.isDisjunctiveMappingOperation(methodCS)) {
+ Collection<CallHandler> handlers = BlackboxRegistry.INSTANCE.getBlackboxCallHandler(declaredOperation, env.getAdapter(QvtOperationalModuleEnv.class));
+ if (handlers.isEmpty()) {
+ String warning = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_noBlackboxImplementationFound,
+ QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));
+ env.reportWarning(warning, QvtOperationalParserUtil.getMethodHeaderProblemNodeCS(methodCS));
+ }
+ if (handlers.size() > 1) {
+ String warning = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_ambiguousBlackboxImplementationFound,
+ QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));
+ env.reportWarning(warning, QvtOperationalParserUtil.getMethodHeaderProblemNodeCS(methodCS));
+ }
+ }
}
private void visitConstructorCS(ConstructorCS methodCS, QvtOperationalEnv env, QvtOperationalEnv newEnv, ImperativeOperation constructor) throws SemanticException {
@@ -3658,13 +3700,13 @@ public class QvtOperationalVisitorCS
body.getEndSection().addAll(ends);
}
- checkAbstractOutParamsInitialized(operation.getResult(), methodCS, env);
+ checkAbstractOutParamsInitialized(operation, methodCS, env);
processMappingExtensions(methodCS, operation, env);
-
+
// adjust implicit variables for serialization
consolidateImplicitVariables(newEnv);
- //
+
return operation;
}
@@ -3813,12 +3855,27 @@ public class QvtOperationalVisitorCS
boolean isAdded = false;
MappingOperation extendedMapping = mappings.get(0);
if(kind == MappingExtensionKindCS.INHERITS) {
+ if (operation.isIsBlackbox()) {
+ env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_unsupportedInheritanceOnBlackboxMapping,
+ QvtOperationalParserUtil.getStringRepresentation(identifierCS), QvtOperationalParserUtil.getMappingStringRepresentation(mappingCS)),
+ identifierCS);
+ }
+ if (extendedMapping.isIsBlackbox()) {
+ env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_unsupportedInheritedBlackboxMapping,
+ QvtOperationalParserUtil.getStringRepresentation(identifierCS), QvtOperationalParserUtil.getMappingStringRepresentation(mappingCS)),
+ identifierCS);
+ }
isAdded = operation.getInherited().add(extendedMapping);
MappingExtensionHelper.bind2SourceElement(operation, identifierCS, kind);
}
else if(kind == MappingExtensionKindCS.MERGES) {
+ if (extendedMapping.isIsBlackbox()) {
+ env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_unsupportedMergedBlackboxMapping,
+ QvtOperationalParserUtil.getStringRepresentation(identifierCS), QvtOperationalParserUtil.getMappingStringRepresentation(mappingCS)),
+ identifierCS);
+ }
isAdded = operation.getMerged().add(extendedMapping);
- MappingExtensionHelper.bind2SourceElement(operation, identifierCS, kind);
+ MappingExtensionHelper.bind2SourceElement(operation, identifierCS, kind);
}
else if(kind == MappingExtensionKindCS.DISJUNCTS) {
isAdded = operation.getDisjunct().add(extendedMapping);
@@ -3846,7 +3903,7 @@ public class QvtOperationalVisitorCS
if (mappingDeclarationCS == null) {
return false;
}
- mappingDeclarationCS.setAst(operation);
+ mappingDeclarationCS.setAst(operation);
operation.setIsBlackbox(mappingMethodCS.isBlackBox());
operation.setStartPosition(mappingDeclarationCS.getStartOffset());
operation.setEndPosition(mappingDeclarationCS.getEndOffset());
@@ -4385,7 +4442,7 @@ public class QvtOperationalVisitorCS
if(referredType != null && (TypeUtil.getRelationship(env, actualType, referredType) & UMLReflection.SAME_TYPE) == 0) {
String actualTypeName = QvtOperationalParserUtil.safeGetQualifiedName(env, actualType);
String referredTypeName = QvtOperationalParserUtil.safeGetQualifiedName(env, referredType);
- String errorMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_instatiatedTypeDoesNotConformToReferredType,
+ String errorMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_instantiatedTypeDoesNotConformToReferredType,
actualTypeName, referredTypeName);
env.reportError(errorMessage, getStartOffset(objectExp, problemCS), getEndOffset(objectExp, problemCS));
@@ -5125,8 +5182,8 @@ public class QvtOperationalVisitorCS
}
}
- private void checkAbstractOutParamsInitialized(EList<VarParameter> result, MappingRuleCS methodCS, QvtOperationalEnv env) {
- for (VarParameter varParameter : result) {
+ private void checkAbstractOutParamsInitialized(MappingOperation operation, MappingRuleCS methodCS, QvtOperationalEnv env) {
+ for (VarParameter varParameter : operation.getResult()) {
EClassifier type = varParameter.getEType();
if (type instanceof EClass) {
EClass eClass = (EClass) type;
@@ -5136,16 +5193,11 @@ public class QvtOperationalVisitorCS
// TODO: The check could be more accurate
return;
}
- if((methodCS.getMappingDeclarationCS() != null) && !(methodCS.getMappingDeclarationCS().getQualifiers().contains(QualifierKindCS.ABSTRACT))) {
- boolean hasDisjunct = false;
- for (MappingExtensionCS extensionCS : methodCS.getMappingDeclarationCS().getMappingExtension()) {
- if(extensionCS.getKind() == MappingExtensionKindCS.DISJUNCTS) {
- hasDisjunct = true;
- break;
- }
- }
+ boolean isAbstract = (methodCS.getMappingDeclarationCS() != null && methodCS.getMappingDeclarationCS().getQualifiers().contains(QualifierKindCS.ABSTRACT));
+ if(!operation.isIsBlackbox() && !isAbstract) {
+ boolean hasDisjunct = QvtOperationalParserUtil.isDisjunctiveMappingOperation(methodCS);
if(!hasDisjunct) {
- env.reportError(ValidationMessages.QvtOperationalVisitorCS_AbstractTypesNotInitialized, methodCS);
+ env.reportError(ValidationMessages.QvtOperationalVisitorCS_AbstractTypesNotInitialized, QvtOperationalParserUtil.getMethodHeaderProblemNodeCS(methodCS));
}
}
}
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.java
index aaaafdb97..4aaba6899 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.java
@@ -9,6 +9,7 @@
* Contributors:
* Borland Software Corporation - initial API and implementation
* Alex Paperno - bugs 272869, 268636, 414363, 419299, 414619, 420970, 413391
+ * Christopher Gerking - bug 289982
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.ast.parser;
@@ -61,7 +62,12 @@ public final class ValidationMessages extends NLS {
public static String QvtOperationalVisitorCS_ContextualPropertyTypeIsMissed;
public static String QvtOperationalVisitorCS_duplicateMappingRereferenceInExtensionKind;
public static String QvtOperationalVisitorCS_duplicateQualifierOnOperation;
- public static String QvtOperationalVisitorCS_instatiatedTypeDoesNotConformToReferredType;
+ public static String QvtOperationalVisitorCS_unsupportedInheritedBlackboxMapping;
+ public static String QvtOperationalVisitorCS_unsupportedMergedBlackboxMapping;
+ public static String QvtOperationalVisitorCS_unsupportedInheritanceOnBlackboxMapping;
+ public static String QvtOperationalVisitorCS_noBlackboxImplementationFound;
+ public static String QvtOperationalVisitorCS_ambiguousBlackboxImplementationFound;
+ public static String QvtOperationalVisitorCS_instantiatedTypeDoesNotConformToReferredType;
public static String QvtOperationalVisitorCS_ResolveInMappingNotFound;
public static String QvtOperationalVisitorCS_transformationNameDuplicates;
public static String QvtOperationalVisitorCS_unresolvedMappingOperationReference;
@@ -99,6 +105,10 @@ public final class ValidationMessages extends NLS {
public static String QvtOperationalVisitorCS_resultParamNameNotAllowed;
public static String QvtOperationalVisitorCS_SeeErrorLogForDetails;
public static String QvtOperationalVisitorCS_unsupportedQualifierOnOperation;
+ public static String QvtOperationalVisitorCS_blackboxOperationWithBodyNotAllowed;
+ public static String QvtOperationalVisitorCS_unsupportedQualifierOnConstructor;
+ public static String QvtOperationalVisitorCS_blackboxConstructorWithBodyNotAllowed;
+ public static String QvtOperationalVisitorCS_unsupportedBlackboxQualifierOnDisjunctiveMapping;
public static String QvtOperationalVisitorCS_WrongImperativeIteratorConditionType;
public static String QvtOperationalVisitorCS_incrementalAssignmentResultNotAllowed;
public static String QvtOperationalVisitorCS_assignmentResultNotAllowed;
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.properties b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.properties
index 7dbe08473..23c4d644a 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.properties
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.properties
@@ -10,6 +10,7 @@
# Borland Software Corporation - initial API and implementation
# Alex Paperno - bugs 272869, 268636, 414363, 419299, 419299, 414619,
# 420970, 413391, 414347
+# Christopher Gerking - bug 289982
###############################################################################
AmbiguousModuleReference=Ambiguous module reference ''{0}''
AmbiguousOperationLookup=Ambiguous operation lookup
@@ -99,9 +100,18 @@ QvtOperationalVisitorCS_transformationNameDuplicates=Transformation with name ''
QvtOperationalVisitorCS_booleanTypeExpressionExpected=''Boolean'' type expression expected, expression of ''{0}'' type found.
QvtOperationalVisitorCS_canNotInstantiateAbstractType=Can''t instantiate abstract type ''{0}''
QvtOperationalVisitorCS_duplicateQualifierOnOperation=Duplicate qualifier ''{0}'' on operation ''{1}''
+QvtOperationalVisitorCS_unsupportedInheritedBlackboxMapping=Unsupported inherited blackbox mapping ''{0}'' on mapping ''{1}''
+QvtOperationalVisitorCS_unsupportedMergedBlackboxMapping=Unsupported merged blackbox mapping ''{0}'' on mapping ''{1}''
+QvtOperationalVisitorCS_unsupportedInheritanceOnBlackboxMapping=Unsupported inherited mapping ''{0}'' on blackbox mapping ''{1}''
+QvtOperationalVisitorCS_noBlackboxImplementationFound=No blackbox implementation found for operation ''{0}''. Make sure that an implementation is available when running the transformation.
+QvtOperationalVisitorCS_ambiguousBlackboxImplementationFound=Ambiguous blackbox implementation found for operation ''{0}''. More than one Java method match the operation's signature.
QvtOperationalVisitorCS_AbstractTypesNotInitialized=Result and out parameters of abstract types must be instantiated or assigned in the init-section
QvtOperationalVisitorCS_unsupportedMetamodelComplianceKind=Metamodel compliance kind ''{0}'' not supported. Assumed 'strict' compliance instead
QvtOperationalVisitorCS_unsupportedQualifierOnOperation=Unsupported qualifier ''{0}'' on operation ''{1}''
+QvtOperationalVisitorCS_blackboxOperationWithBodyNotAllowed=Blackbox operation ''{0}'' must not specify an operation body
+QvtOperationalVisitorCS_unsupportedQualifierOnConstructor=Unsupported qualifier ''{0}'' on constructor ''{1}''
+QvtOperationalVisitorCS_blackboxConstructorWithBodyNotAllowed=Blackbox constructor ''{0}'' must not specify an operation body
+QvtOperationalVisitorCS_unsupportedBlackboxQualifierOnDisjunctiveMapping=Disjunctive mapping ''{0}'' must not be declared as blackbox
QvtOperationalVisitorCS_unresolvedMappingOperationReference=Unresolved mapping operation reference ''{0}''
QvtOperationalVisitorCS_metamodelPackageRefInconsistent=Cannot locate metamodel name ''{0}'' under specified URI
QvtOperationalVisitorCS_metamodelConditionsNotSupported=Metamodel conditions are not supported in current implementation
@@ -140,7 +150,7 @@ returnNotAllowedInMappingYet=Using ''return'' from mapping operation is not yet
returnUsedOutsideOperationBody=Using ''return'' outside operation body
useReturnExpForOperationResult=Use 'return' expression to return result from operation. The last expression or 'null' from empty body is returned implicitly.
directCallToAbstractMappingDisallowed=Can not call abstract mapping ''{0}'' with abstract out/result parameter type directly. Use with 'inherits', 'disjuncts', 'merges' in other mappings
-QvtOperationalVisitorCS_instatiatedTypeDoesNotConformToReferredType=Instantiated object type ''{0}'' does not conform to referred object type ''{1}''
+QvtOperationalVisitorCS_instantiatedTypeDoesNotConformToReferredType=Instantiated object type ''{0}'' does not conform to referred object type ''{1}''
QvtOperationalVisitorCS_duplicateMappingRereferenceInExtensionKind=Duplicate ''{0}'' reference to mapping operation ''{1}''
QvtOperationalVisitorCS_LibrarySignatureErrorDirectionKindSpecified=Direction kind cannot be specified here. Library signature must be a list of model types\!
QvtOperationalVisitorCS_LibrarySignatureErrorDuplicateModelType=Model type {0} is already present in the library signature\!
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) {
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/compiler/BlackboxUnitResolver.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/compiler/BlackboxUnitResolver.java
index 810329718..81d682763 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/compiler/BlackboxUnitResolver.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/compiler/BlackboxUnitResolver.java
@@ -39,8 +39,10 @@ import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
public class BlackboxUnitResolver implements UnitResolver {
+ public static final URI GLOBAL_CONTEXT = URI.createURI("/"); //$NON-NLS-1$
+
// the global scope black-box resolver
- public static final BlackboxUnitResolver DEFAULT = new BlackboxUnitResolver(URI.createURI("/")); //$NON-NLS-1$
+ public static final BlackboxUnitResolver DEFAULT = new BlackboxUnitResolver(GLOBAL_CONTEXT);
private ResolutionContext fContext;
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/compiler/CompiledUnit.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/compiler/CompiledUnit.java
index 83c28c007..7d1916cca 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/compiler/CompiledUnit.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/compiler/CompiledUnit.java
@@ -45,6 +45,7 @@ import org.eclipse.m2m.internal.qvt.oml.ast.parser.QvtOperationalParserUtil;
import org.eclipse.m2m.internal.qvt.oml.cst.CSTFactory;
import org.eclipse.m2m.internal.qvt.oml.cst.UnitCS;
import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation;
+import org.eclipse.m2m.internal.qvt.oml.expressions.ImportKind;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
import org.eclipse.m2m.internal.qvt.oml.expressions.ModuleImport;
import org.eclipse.ocl.Environment;
@@ -116,18 +117,28 @@ public class CompiledUnit {
this.fImports = new UniqueEList<CompiledUnit>();
unitMap.put(fUri, this);
-
- computeImports(unitXMIResource, unitMap);
+
+ if (!BlackboxUnitResolver.isBlackboxUnitURI(fUri)) {
+ computeImports(unitXMIResource, unitMap);
+ }
// Note: Environment initialization should be optional as it make sense to be used
// only in case this unit is to be a compilation dependency to parsed CST Unit
for(EObject rootElement : new ArrayList<EObject>(unitXMIResource.getContents())) {
- if(rootElement instanceof Module) {
- Module nextModule = (Module) rootElement;
- QvtOperationalModuleEnv nextModuleEnv = QvtOperationalEnvFactory.INSTANCE.createModuleEnvironment(nextModule);
+ if(false == rootElement instanceof Module) {
+ continue;
+ }
+ Module nextModule = (Module) rootElement;
+ QvtOperationalModuleEnv nextModuleEnv = null;
+
+ if (BlackboxUnitResolver.isBlackboxUnitURI(fUri)) {
+ nextModuleEnv = (QvtOperationalModuleEnv) ASTBindingHelper.resolveEnvironment(nextModule);
+ }
+ else {
+ nextModuleEnv = QvtOperationalEnvFactory.INSTANCE.createModuleEnvironment(nextModule);
QVTOTypeResolver typeResolver = nextModuleEnv.getTypeResolver();
-
- // FIXME -
+
+ // FIXME -
// 1) workaround to make Environment available with the module for
// non-transformation execution context
// 2) move this initialization code to QVTEnvironment related classes
@@ -142,8 +153,14 @@ public class CompiledUnit {
}
}
- this.moduleEnvs.add(nextModuleEnv);
+ for (CompiledUnit importedUnit : getCompiledImports()) {
+ for (QvtOperationalModuleEnv importedEnv : importedUnit.moduleEnvs) {
+ nextModuleEnv.addImport(ImportKind.ACCESS, importedEnv);
+ }
+ }
}
+
+ this.moduleEnvs.add(nextModuleEnv);
}
//validate(unitXMIResource, this.fAllProblems);
@@ -228,10 +245,10 @@ public class CompiledUnit {
unitMap.put(importedResourceURI, importedUnit);
}
- fImports.add(new CompiledUnit(importedResource, unitMap));
+ fImports.add(importedUnit);
}
} else {
- throw new IllegalArgumentException("imported module must be in a resource"); //$NON-NLS-1$
+ throw new IllegalArgumentException("imported module must be in a resource: " + String.valueOf(importedModule)); //$NON-NLS-1$
}
}
}
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/EvaluationMessages.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/EvaluationMessages.java
index f7a1b519d..ae124206b 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/EvaluationMessages.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/EvaluationMessages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2009 Borland Software Corporation and others.
+ * Copyright (c) 2007, 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
@@ -32,6 +32,9 @@ public class EvaluationMessages extends NLS {
public static String UknownSourceLabel;
public static String MappingPreconditionFailed;
public static String ModelTypeConstraintFailed;
+ public static String NoBlackboxOperationFound;
+ public static String AmbiguousBlackboxOperationFound;
+ public static String BlackboxMappingFailedToAssignResult;
public static String IteratorNotImpl;
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/QvtOperationalEvaluationVisitorImpl.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/QvtOperationalEvaluationVisitorImpl.java
index 1164c6ae8..421b9b21a 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/QvtOperationalEvaluationVisitorImpl.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/QvtOperationalEvaluationVisitorImpl.java
@@ -52,12 +52,14 @@ import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtEvaluationResult;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEnvFactory;
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.ast.env.QvtOperationalStdLibrary;
import org.eclipse.m2m.internal.qvt.oml.ast.parser.ConstructorOperationAdapter;
import org.eclipse.m2m.internal.qvt.oml.ast.parser.IntermediateClassFactory;
import org.eclipse.m2m.internal.qvt.oml.ast.parser.IntermediateClassFactory.ExceptionClassInstance;
import org.eclipse.m2m.internal.qvt.oml.ast.parser.QvtOperationalParserUtil;
import org.eclipse.m2m.internal.qvt.oml.ast.parser.QvtOperationalUtil;
+import org.eclipse.m2m.internal.qvt.oml.blackbox.BlackboxRegistry;
import org.eclipse.m2m.internal.qvt.oml.emf.util.EmfUtil;
import org.eclipse.m2m.internal.qvt.oml.evaluator.TransformationInstance.InternalTransformation;
import org.eclipse.m2m.internal.qvt.oml.evaluator.iterators.QvtIterationTemplateCollectSelect;
@@ -143,6 +145,7 @@ import org.eclipse.ocl.EvaluationVisitorImpl;
import org.eclipse.ocl.ParserException;
import org.eclipse.ocl.ecore.CallOperationAction;
import org.eclipse.ocl.ecore.Constraint;
+import org.eclipse.ocl.ecore.EcoreEnvironment;
import org.eclipse.ocl.ecore.EcoreFactory;
import org.eclipse.ocl.ecore.EcorePackage;
import org.eclipse.ocl.ecore.SendSignalAction;
@@ -166,6 +169,7 @@ import org.eclipse.ocl.types.VoidType;
import org.eclipse.ocl.util.Bag;
import org.eclipse.ocl.util.CollectionUtil;
import org.eclipse.ocl.util.Tuple;
+import org.eclipse.ocl.utilities.ASTNode;
import org.eclipse.ocl.utilities.PredefinedType;
import org.eclipse.ocl.utilities.UMLReflection;
@@ -498,6 +502,12 @@ implements QvtOperationalEvaluationVisitor, InternalEvaluator, DeferredAssignmen
public Object visitHelper(Helper helper) {
visitImperativeOperation(helper);
+
+ if (helper.isIsBlackbox()) {
+ Object result = doVisitBlackboxOperation(helper);
+ return new OperationCallResult(result, getOperationalEvaluationEnv());
+ }
+
return new OperationCallResult(visitOperationBody(helper.getBody()), getOperationalEvaluationEnv());
}
@@ -527,6 +537,31 @@ implements QvtOperationalEvaluationVisitor, InternalEvaluator, DeferredAssignmen
pushedStack(getOperationalEvaluationEnv());
return null;
}
+
+ private Object doVisitBlackboxOperation(ImperativeOperation operation) {
+
+ assert operation.isIsBlackbox() : "Blackbox operation expected"; //$NON-NLS-1$
+
+ EcoreEnvironment moduleEnv = ASTBindingHelper.resolveEnvironment((ASTNode) operation.eContainer());
+ if (false == moduleEnv instanceof QvtOperationalModuleEnv) {
+ moduleEnv = ASTBindingHelper.getEnvironment(operation.eContainer(), QvtOperationalModuleEnv.class);
+ }
+
+ Collection<CallHandler> handlers = BlackboxRegistry.INSTANCE.getBlackboxCallHandler(operation,
+ //getOperationalEnv().getAdapter(QvtOperationalModuleEnv.class));
+ (QvtOperationalModuleEnv) moduleEnv);
+ if (handlers.isEmpty()) {
+ throwQVTException(new QvtRuntimeException(NLS.bind(EvaluationMessages.NoBlackboxOperationFound,
+ QvtOperationalParserUtil.safeGetMappingQualifiedName(getOperationalEnv(), operation))));
+ }
+ if (handlers.size() > 1) {
+ throwQVTException(new QvtRuntimeException(NLS.bind(EvaluationMessages.AmbiguousBlackboxOperationFound,
+ QvtOperationalParserUtil.safeGetMappingQualifiedName(getOperationalEnv(), operation))));
+ }
+
+ QvtOperationalEvaluationEnv evalEnv = getOperationalEvaluationEnv();
+ return handlers.iterator().next().invoke(evalEnv.getThisOfType(QvtOperationalParserUtil.getOwningModule(operation)), evalEnv.getOperationSelf(), evalEnv.getOperationArgs().toArray(), evalEnv);
+ }
public Object visitLibrary(Library library) {
return null;
@@ -616,24 +651,25 @@ implements QvtOperationalEvaluationVisitor, InternalEvaluator, DeferredAssignmen
}
// call merged mappings
- if(!currentMappingCalled.getMerged().isEmpty()) {
- for (MappingOperation extendedMapping : currentMappingCalled.getMerged()) {
-
- // consider overriding mapping
- ImperativeOperation overridingOper = EvaluationUtil.getOverridingOperation(getOperationalEvaluationEnv(), extendedMapping);
- if (overridingOper instanceof MappingOperation) {
- extendedMapping = (MappingOperation) overridingOper;
- }
-
- executeImperativeOperation(extendedMapping, evalEnv.getOperationSelf(), evalEnv.getOperationArgs(), true);
- }
- }
+ callMergedMappings(currentMappingCalled, evalEnv);
// result may have changed in body, end section, or merged mappings, so retrieve it again (fixed by bug 388325)
result = getRuntimeValue(Environment.RESULT_VARIABLE_NAME);
return result;
}
+
+ private void callMergedMappings(MappingOperation mappingOperation, QvtOperationalEvaluationEnv evalEnv) {
+ for (MappingOperation extendedMapping : mappingOperation.getMerged()) {
+ // consider overriding mapping
+ ImperativeOperation overridingOper = EvaluationUtil.getOverridingOperation(getOperationalEvaluationEnv(), extendedMapping);
+ if (overridingOper instanceof MappingOperation) {
+ extendedMapping = (MappingOperation) overridingOper;
+ }
+
+ executeImperativeOperation(extendedMapping, evalEnv.getOperationSelf(), evalEnv.getOperationArgs(), true);
+ }
+ }
public Object visitMappingCallExp(MappingCallExp mappingCallExp) {
return visitOperationCallExp(mappingCallExp);
@@ -800,9 +836,25 @@ implements QvtOperationalEvaluationVisitor, InternalEvaluator, DeferredAssignmen
if(!mappingOperation.getDisjunct().isEmpty()) {
return dispatchDisjunctMapping(mappingOperation);
}
-
- return new MappingCallResult(((OperationBodyImpl) mappingOperation.getBody()).accept(getVisitor()),
- evalEnv, MappingCallResult.BODY_EXECUTED);
+
+ if (mappingOperation.isIsBlackbox()) {
+ Object result = doVisitBlackboxOperation(mappingOperation);
+ if (isUndefined(result)) {
+ throwQVTException(new QvtRuntimeException(NLS.bind(EvaluationMessages.BlackboxMappingFailedToAssignResult,
+ QvtOperationalParserUtil.safeGetMappingQualifiedName(getOperationalEnv(), mappingOperation))));
+ }
+
+ replaceInEnv(Environment.RESULT_VARIABLE_NAME, result, mappingOperation.getEType());
+ TraceUtil.addTraceRecord(getOperationalEvaluationEnv(), mappingOperation);
+
+ // call merged mappings
+ callMergedMappings(mappingOperation, evalEnv);
+
+ return new MappingCallResult(result, evalEnv, MappingCallResult.BODY_EXECUTED);
+ }
+
+ return new MappingCallResult(((OperationBodyImpl) mappingOperation.getBody()).accept(getVisitor()), evalEnv,
+ MappingCallResult.BODY_EXECUTED);
}
public Object execute(OperationalTransformation transformation) throws QvtRuntimeException {
@@ -932,6 +984,10 @@ implements QvtOperationalEvaluationVisitor, InternalEvaluator, DeferredAssignmen
Adapter adapter = EcoreUtil.getAdapter(objectExp.eAdapters(), ConstructorOperationAdapter.class);
if (adapter != null) {
Constructor constructorOp = ((ConstructorOperationAdapter) adapter).getReferredConstructor();
+
+ for (int i = 0, in = constructorOp.getEParameters().size(); i < in; ++i) {
+ actualArguments.set(i, doImplicitListCoercion(constructorOp.getEParameters().get(i).getEType(), actualArguments.get(i)));
+ }
executeImperativeOperation(constructorOp, owner, actualArguments, false);
}
@@ -1444,9 +1500,16 @@ implements QvtOperationalEvaluationVisitor, InternalEvaluator, DeferredAssignmen
public Object visitConstructor(Constructor constructor) {
visitImperativeOperation(constructor);
+
QvtOperationalEvaluationEnv env = getOperationalEvaluationEnv();
+
+ if (constructor.isIsBlackbox()) {
+ Object result = doVisitBlackboxOperation(constructor);
+ return new OperationCallResult(result, env);
+ }
+
env.add(Environment.RESULT_VARIABLE_NAME, env.remove(Environment.SELF_VARIABLE_NAME));
- return new OperationCallResult(visitOperationBody(constructor.getBody()), getOperationalEvaluationEnv());
+ return new OperationCallResult(visitOperationBody(constructor.getBody()), env);
}
public Object visitConstructorBody(ConstructorBody constructorBody) {
@@ -1715,11 +1778,6 @@ implements QvtOperationalEvaluationVisitor, InternalEvaluator, DeferredAssignmen
}
private OperationCallResult executeImperativeOperation(ImperativeOperation method, Object source, List<Object> args, boolean isReusingMappingCall) {
- if (method.isIsBlackbox() && method.getBody() == null) {
- throw new IllegalArgumentException(
- "Can't execute blackbox operation" + method.getName()); //$NON-NLS-1$
- }
-
QvtOperationalEvaluationEnv oldEvalEnv = getOperationalEvaluationEnv();
boolean isMapping = method instanceof MappingOperation;
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/messages.properties b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/messages.properties
index 0728d9062..3e9529123 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/messages.properties
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/evaluator/messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2007, 2009 Borland Software Corporation and others.
+# Copyright (c) 2007, 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
@@ -23,3 +23,6 @@ QvtOperationalEvaluationVisitorImpl_invalidConfigPropertyValue=Failed to get ''{
QvtOperationalEvaluationVisitorImpl_UndefModelParamInTransf=Undefined model passed to transformation
QvtOperationalEvaluationVisitorImpl_unexpectedRuntimeExc=Unexpected runtime exception caught during execution
IteratorNotImpl=Iterator ({0}) not yet implemented.
+NoBlackboxOperationFound=No blackbox implementation found for operation ''{0}''
+AmbiguousBlackboxOperationFound=Ambiguous blackbox implementation found for operation ''{0}''
+BlackboxMappingFailedToAssignResult=Blackbox operation ''{0}'' failed to assign mapping result \ No newline at end of file
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/qvt/oml/blackbox/java/Operation.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/qvt/oml/blackbox/java/Operation.java
index 4a55dd508..7dc74bd83 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/qvt/oml/blackbox/java/Operation.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/qvt/oml/blackbox/java/Operation.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.qvt.oml.blackbox.java;
@@ -43,6 +44,16 @@ public @interface Operation {
*/
QUERY,
/**
+ * The operation is defined as operational<code>mapping</code>.
+ * @since 3.4
+ */
+ MAPPING,
+ /**
+ * The operation is defined as contextual<code>constructor</code>.
+ * @since 3.4
+ */
+ CONSTRUCTOR,
+ /**
* The operation is defined as normal operation. If the associated operation is defined as
* <code>contextual</code>, the Typedef class is used to represent it as additional operation
* in the owning <code>Module</code> class.

Back to the top