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