Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsboyko2014-01-29 07:34:32 +0000
committersboyko2014-01-29 07:34:32 +0000
commitd21c22ea2ac43cdde470c99089948b12b15b4e03 (patch)
tree4cdad10a48a363843974d0f6a8f89609f6ee2c82 /plugins/org.eclipse.m2m.qvt.oml/src
parente92ca950ea3f97103251c7c9b6f18faffa34129a (diff)
downloadorg.eclipse.qvto-d21c22ea2ac43cdde470c99089948b12b15b4e03.tar.gz
org.eclipse.qvto-d21c22ea2ac43cdde470c99089948b12b15b4e03.tar.xz
org.eclipse.qvto-d21c22ea2ac43cdde470c99089948b12b15b4e03.zip
[289982] - Support concrete syntax definition of blackbox libraries
Diffstat (limited to 'plugins/org.eclipse.m2m.qvt.oml/src')
-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
25 files changed, 652 insertions, 155 deletions
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