Home » Modeling » QVT-OML » Standalone mode for QVTO (deployed to an online modeler)(Use a blackbox java library without Eclipse )
| |
Re: Standalone mode for QVTO (deployed to an online modeler) [message #957539 is a reply to message #956108] |
Thu, 25 October 2012 09:45 |
thomas legrand Messages: 10 Registered: September 2010 |
Junior Member |
|
|
Hi Rolf,
I would be glad to add the patch but I'm facing two problems.
To fix the bug one year ago, I modified 3 classes in the 3.1 version of org.eclipse.m2m.qvt.oml.
In the meantime, the plugin has evolved. A patch imposes to merge with the latest version of the public repository; it can take some time.
Moreover, a trick in the modified code is not very beautiful. In the JavaBlackboxProvider class, I set a hard-coded variable to give the namespace of the loaded Java library. I assumed the libraries are all based on Ecore metamodel because that was the case for my qvto transformations and It was not appropriated to add a registration mechanism in the plugin for the specific metamodels of the imported libraries.
To help you right now, what I suggest :
- I append below the 3 modified classes : JavaBlackboxProvider, BlackboxRegistry, BlackboxUnitResolver
- I study in details the latest snapshot and see the best way to merge those modifications
Let me know if the given classes help and let's go further.
/*******************************************************************************
* Copyright (c) 2008 Borland Software Corporation
*
* 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.java;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.m2m.internal.qvt.oml.NLS;
import org.eclipse.m2m.internal.qvt.oml.QvtPlugin;
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.blackbox.AbstractBlackboxProvider;
import org.eclipse.m2m.internal.qvt.oml.blackbox.AbstractCompilationUnitDescriptor;
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.ResolutionContext;
import org.eclipse.m2m.internal.qvt.oml.cst.CSTFactory;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
public class JavaBlackboxProvider extends AbstractBlackboxProvider {
private static final String PROVIDER_ID = "Java"; //$NON-NLS-1$
private static final String EXTENSION_POINT = "javaBlackboxUnits"; //$NON-NLS-1$
private static final String CLASS_NAME_SEPARATOR = "."; //$NON-NLS-1$
private static final String UNIT_ELEM = "unit"; //$NON-NLS-1$
private static final String LIBRARY_ELEM = "library"; //$NON-NLS-1$
private static final String CLASS_ATTR = "class"; //$NON-NLS-1$
private static final String NAME_ATTR = "name"; //$NON-NLS-1$
private static final String NAMESPACE_ATTR = "namespace"; //$NON-NLS-1$
private static final String DESC_ATTR = "description"; //$NON-NLS-1$
private static final String METAMODEL_ELEM = "metamodel"; //$NON-NLS-1$
private static final String NSURI_ATTR = "nsURI"; //$NON-NLS-1$
private Map<String, Descriptor> fDescriptorMap;
private static final String ECORE_METAMODEL_URI = "http://www.eclipse.org/emf/2002/Ecore";
public JavaBlackboxProvider() {
if(EMFPlugin.IS_ECLIPSE_RUNNING) {
fDescriptorMap = readDescriptors();
} else {
fDescriptorMap = new HashMap<String, Descriptor>();
}
}
@Override
public AbstractCompilationUnitDescriptor getModuleDescriptor(String qualifiedName, ResolutionContext resolutionContext) {
// TODO - Should we necessarily be available in all contexts ?
return fDescriptorMap.get(qualifiedName);
}
@Override
protected String getProviderID() {
return PROVIDER_ID;
}
@Override
public List<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);
}
@Override
public CompilationUnit loadCompilationUnit(AbstractCompilationUnitDescriptor descriptor, LoadContext loadContext) throws BlackboxException {
if(descriptor instanceof Descriptor == false) {
throw new IllegalArgumentException("Invalid descriptor"); //$NON-NLS-1$
}
Descriptor libDescriptor = (Descriptor) descriptor;
JavaModuleLoader javaModuleLoader = createJavaModuleLoader();
BasicDiagnostic errors = null;
List<QvtOperationalModuleEnv> loadedModules = new LinkedList<QvtOperationalModuleEnv>();
for (ModuleHandle nextModuleHandle : libDescriptor.fModules) {
Diagnostic diagnostic = javaModuleLoader.loadModule(nextModuleHandle);
if(DiagnosticUtil.isSuccess(diagnostic)) {
QvtOperationalModuleEnv nextModuleEnv = javaModuleLoader.getLoadedModule();
nextModuleEnv.getTypeResolver().getResource().setURI(descriptor.getURI());
loadedModules.add(nextModuleEnv);
if(diagnostic.getSeverity() != Diagnostic.OK) {
QvtPlugin.logDiagnostic(diagnostic);
}
} else {
if(errors == null) {
String message = NLS.bind(JavaBlackboxMessages.BlackboxUnitLoadFailed, descriptor.getQualifiedName());
errors = DiagnosticUtil.createErrorDiagnostic(message);
}
errors.add(diagnostic);
}
}
if(errors != null) {
assert errors.getSeverity() == Diagnostic.ERROR;
throw new BlackboxException(errors);
}
return createCompilationUnit(loadedModules);
}
private JavaModuleLoader createJavaModuleLoader() {
return new JavaModuleLoader() {
JavaMethodHandlerFactory handlerFactory;
@Override
protected void loadModule(QvtOperationalModuleEnv moduleEnv, final Class<?> javaModuleClass) {
handlerFactory = new JavaMethodHandlerFactory(moduleEnv.getOCLStandardLibrary());
Module module = moduleEnv.getModuleContextType();
// FIXME - workaround to make Environment available with the module for
// non-transformation execution context
ASTBindingHelper.createCST2ASTBinding(CSTFactory.eINSTANCE.createLibraryCS(), module, moduleEnv);
setInstanceAdapterFactory(module, createInstanceAdapterFactory(javaModuleClass));
}
@Override
protected void loadOperation(EOperation operation, Method javaOperation) {
setOperationHandler(operation, handlerFactory.createHandler(javaOperation), true);
}
};
}
static InstanceAdapterFactory createInstanceAdapterFactory(final Class<?> javaModuleClass) {
return new InstanceAdapterFactory() {
public Object createAdapter(EObject moduleInstance) {
try {
return javaModuleClass.newInstance();
} catch (InstantiationException e) {
// FIXME - choose a better exception
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$
}
}
};
}
private Map<String, Descriptor> readDescriptors() {
Map<String, Descriptor> providers = new HashMap<String, Descriptor>();
IConfigurationElement[] configs = Platform.getExtensionRegistry()
.getConfigurationElementsFor(QvtPlugin.ID, EXTENSION_POINT);
for (IConfigurationElement element : configs) {
try {
Descriptor descriptor = createDescriptor(element);
String id = descriptor.getQualifiedName();
if(!providers.containsKey(id)) {
providers.put(id, descriptor);
} else {
String message = NLS.bind(JavaBlackboxMessages.UnitAlreadyRegisteredContributionIgnored, id, descriptor.getContributorId());
QvtPlugin.error(message);
}
} catch (IllegalArgumentException e) {
QvtPlugin.error("Failed to read java black-box definition: " + e.getMessage()); //$NON-NLS-1$
}
}
return providers;
}
private Descriptor createDescriptor(IConfigurationElement configurationElement) throws IllegalArgumentException {
if(UNIT_ELEM.equals(configurationElement.getName())) {
String name = configurationElement.getAttribute(NAME_ATTR);
String namespace = configurationElement.getAttribute(NAMESPACE_ATTR);
if(namespace == null) {
configurationElement.getContributor().getName();
}
String description = configurationElement.getAttribute(DESC_ATTR);
String qualifiedName = namespace + CLASS_NAME_SEPARATOR + name;
return new Descriptor(configurationElement, qualifiedName, description);
} else if(LIBRARY_ELEM.equals(configurationElement.getName())) {
return new Descriptor(configurationElement, deriveQualifiedNameFromSimpleDefinition(configurationElement), null);
}
throw new IllegalArgumentException("Unsupported configuration element " + configurationElement); //$NON-NLS-1$
}
private static String getPackageNameFromJavaClass(String className) {
int lastSeparatorPos = className.lastIndexOf(CLASS_NAME_SEPARATOR);
if(lastSeparatorPos < 0) {
return null;
}
return className.substring(0, lastSeparatorPos);
}
private static String deriveQualifiedNameFromSimpleDefinition(IConfigurationElement moduleElement) {
String className = moduleElement.getAttribute(CLASS_ATTR);
String name = moduleElement.getAttribute(NAME_ATTR);
if(name == null) {
return className;
}
// name overridden in descriptor
String packageName = getPackageNameFromJavaClass(className);
if(packageName == null) {
return name; // default package
}
return packageName + CLASS_NAME_SEPARATOR + name;
}
public void addDescriptor(String javaLibQualifiedName){
List<String> namespaceUris= new ArrayList<String>();
// assume that's the unique possible case
namespaceUris.add(ECORE_METAMODEL_URI);
Descriptor descriptor = new Descriptor(javaLibQualifiedName,namespaceUris);
String id = descriptor.getQualifiedName();
fDescriptorMap.put(id, descriptor);
}
private class Descriptor extends AbstractCompilationUnitDescriptor {
private List<ModuleHandle> fModules = Collections.emptyList();
private String fContributingBundleId;
Descriptor(IConfigurationElement configurationElement, String unitQualifiedName, String description) {
super(JavaBlackboxProvider.this, unitQualifiedName,
//configurationElement.getContributor().getName(),
unitQualifiedName);
fContributingBundleId = configurationElement.getContributor().getName();
if(configurationElement.getName().equals(LIBRARY_ELEM)) {
addModuleHandle(configurationElement);
} else {
IConfigurationElement[] libraries = configurationElement.getChildren(LIBRARY_ELEM);
for (IConfigurationElement moduleElement : libraries) {
addModuleHandle(moduleElement);
}
}
}
Descriptor(String unitQualifiedName, List<String> nsURIs) {
super(JavaBlackboxProvider.this, unitQualifiedName, unitQualifiedName);
fContributingBundleId = unitQualifiedName;
addModuleHandle(unitQualifiedName, unitQualifiedName, unitQualifiedName,nsURIs);
}
String getContributorId() {
return fContributingBundleId;
}
private void addModuleHandle(IConfigurationElement moduleElement) {
if(fModules.isEmpty()) {
fModules = new LinkedList<ModuleHandle>();
}
String bundleId = moduleElement.getContributor().getName();
String className = moduleElement.getAttribute(CLASS_ATTR);
String moduleName = moduleElement.getAttribute(NAME_ATTR);
if(moduleName == null) {
// derive the name from the java class name
moduleName = getSimpleNameFromJavaClass(className);
}
ModuleHandle moduleHandle = new BundleModuleHandle(bundleId, className, moduleName, readUsedPackagesNsURIs(moduleElement));
fModules.add(moduleHandle);
}
private void addModuleHandle(String bundleId, String className, String moduleName,List<String> namespaceUris) {
if(fModules.isEmpty()) {
fModules = new LinkedList<ModuleHandle>();
}
if(moduleName == null) {
// derive the name from the java class name
moduleName = getSimpleNameFromJavaClass(className);
}
ModuleHandle moduleHandle = new BundleModuleHandle(bundleId, className, moduleName, namespaceUris);
fModules.add(moduleHandle);
}
private List<String> readUsedPackagesNsURIs(IConfigurationElement moduleConfigElement) {
ArrayList<String> uris = new ArrayList<String>(3);
for (IConfigurationElement nextElement : moduleConfigElement.getChildren(METAMODEL_ELEM)) {
String nsURI = nextElement.getAttribute(NSURI_ATTR);
if(nsURI != null) {
uris.add(nsURI);
}
}
return uris;
}
private String getSimpleNameFromJavaClass(String className) {
int lastSeparatorPos = className.lastIndexOf(CLASS_NAME_SEPARATOR);
if(lastSeparatorPos < 0) {
return className;
}
return className.substring(lastSeparatorPos + 1);
}
}
}
/*******************************************************************************
* Copyright (c) 2008 Borland Software Corporation
*
* 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 java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
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.blackbox.java.JavaBlackboxProvider;
/*
* TODO - handle collisions of multiple descriptors of the same qualified name
*/
public class BlackboxRegistry {
private static final String CLASS_ATTR = "class"; //$NON-NLS-1$
private static final String PROVIDER_ELEMENT = "provider"; //$NON-NLS-1$
private static final String BLACKBOX_PROVIDER_EXTENSION = "blackboxProvider"; //$NON-NLS-1$
public static BlackboxRegistry INSTANCE = new BlackboxRegistry();
// instance fields
private List<AbstractBlackboxProvider> fProviders;
private BlackboxRegistry() {
try {
if(EMFPlugin.IS_ECLIPSE_RUNNING) {
fProviders = Eclipse.readProviders();
} else {
fProviders = new ArrayList<AbstractBlackboxProvider>();
}
} catch (RuntimeException e) {
fProviders = Collections.emptyList();
QvtPlugin.error(e);
}
}
public AbstractCompilationUnitDescriptor getCompilationUnitDescriptor(String qualifiedName, ResolutionContext context) {
for (AbstractBlackboxProvider provider : fProviders) {
AbstractCompilationUnitDescriptor descriptor = provider.getModuleDescriptor(qualifiedName, context);
if(descriptor != null) {
return descriptor;
}
}
return null;
}
public CompilationUnit loadCompilationUnit(AbstractCompilationUnitDescriptor descriptor, LoadContext loadContext) throws BlackboxException {
if(descriptor == null) {
throw new IllegalArgumentException("Null blackbox descriptor"); //$NON-NLS-1$
}
AbstractBlackboxProvider provider = descriptor.getProvider();
return provider.loadCompilationUnit(descriptor, loadContext);
}
public List<AbstractCompilationUnitDescriptor> getCompilationUnitDescriptors(ResolutionContext loadContext) {
ArrayList<AbstractCompilationUnitDescriptor> result = new ArrayList<AbstractCompilationUnitDescriptor>();
for (AbstractBlackboxProvider provider : fProviders) {
for (AbstractCompilationUnitDescriptor abstractCompilationUnitDescriptor : provider.getModuleDescriptors(loadContext)) {
result.add(abstractCompilationUnitDescriptor);
}
}
return result;
}
public void addJavaBlackBoxProvider(String javaLibQualifiedName) {
JavaBlackboxProvider provider = new JavaBlackboxProvider();
provider.addDescriptor(javaLibQualifiedName);
fProviders.add((AbstractBlackboxProvider)provider);
}
private static class Eclipse {
private static List<AbstractBlackboxProvider> readProviders() {
List<AbstractBlackboxProvider> providers = new LinkedList<AbstractBlackboxProvider>();
IConfigurationElement[] configs =
Platform.getExtensionRegistry().getConfigurationElementsFor(
QvtPlugin.ID, BLACKBOX_PROVIDER_EXTENSION);
for (IConfigurationElement element : configs) {
if (element.getName().equals(PROVIDER_ELEMENT)) {
try {
Object extension = element.createExecutableExtension(CLASS_ATTR);
if(extension instanceof AbstractBlackboxProvider == false) {
QvtPlugin.error("Provider must implement AbstractBlackboxProvider interace: " + extension); //$NON-NLS-1$
continue;
}
providers.add((AbstractBlackboxProvider)extension);
} catch (CoreException e) {
QvtPlugin.getDefault().log(e.getStatus());
}
}
}
return providers;
}
}
}
/*******************************************************************************
* Copyright (c) 2009 Borland Software Corporation
*
* 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.compiler;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage.Registry;
import org.eclipse.m2m.internal.qvt.oml.NLS;
import org.eclipse.m2m.internal.qvt.oml.QvtPlugin;
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.ast.parser.QvtOperationalParserUtil;
import org.eclipse.m2m.internal.qvt.oml.ast.parser.ValidationMessages;
import org.eclipse.m2m.internal.qvt.oml.blackbox.AbstractCompilationUnitDescriptor;
import org.eclipse.m2m.internal.qvt.oml.blackbox.BlackboxException;
import org.eclipse.m2m.internal.qvt.oml.blackbox.BlackboxRegistry;
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.ResolutionContext;
import org.eclipse.m2m.internal.qvt.oml.blackbox.ResolutionContextImpl;
import org.eclipse.m2m.internal.qvt.oml.compiler.UnitContents.ModelContents;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
public class BlackboxUnitResolver implements UnitResolver {
// the global scope black-box resolver
public static final BlackboxUnitResolver DEFAULT = new BlackboxUnitResolver(URI.createURI("/")); //$NON-NLS-1$
private ResolutionContext fContext;
public BlackboxUnitResolver(URI context) {
fContext = new ResolutionContextImpl(context);
}
public static boolean isBlackboxUnitURI(URI uri) {
return AbstractCompilationUnitDescriptor.URI_SCHEME.equals(uri.scheme()) &&
AbstractCompilationUnitDescriptor.URI_AUTHORITY.equals(uri.authority());
}
public static UnitProxy getUnit(URI uri) {
if(isBlackboxUnitURI(uri) && uri.segmentCount() > 0) {
// TODO - use 1st segment as provider ID to be used in library ID clash resolution
String id = uri.lastSegment();
return BlackboxUnitResolver.DEFAULT.resolveUnit(id);
}
return null;
}
public UnitProxy resolveUnit(String qualifiedName) {
BlackboxRegistry.INSTANCE.addJavaBlackBoxProvider(qualifiedName);
AbstractCompilationUnitDescriptor descriptor = BlackboxRegistry.INSTANCE.getCompilationUnitDescriptor(qualifiedName, fContext);
if (descriptor != null) {
int namePos = qualifiedName.lastIndexOf('.');
String name;
String namespace;
if(namePos > 0) {
namespace = qualifiedName.substring(0, namePos);
if(namePos + 1 < qualifiedName.length()) {
++namePos;
}
name = qualifiedName.substring(namePos);
} else {
name = qualifiedName;
namespace = null;
}
return new BBoxUnit(namespace, name, descriptor);
}
return null;
}
class BBoxUnit extends UnitProxy {
private AbstractCompilationUnitDescriptor fDescriptor;
BBoxUnit(String namespace, String name, AbstractCompilationUnitDescriptor descriptor) {
super(namespace, name, descriptor.getURI());
fDescriptor = descriptor;
}
@Override
public int getContentType() {
return UnitProxy.TYPE_MODEL;
}
@Override
public UnitContents getContents() throws IOException {
return new BBoxUnitContents(fDescriptor);
}
@Override
public UnitResolver getResolver() {
return BlackboxUnitResolver.this;
}
}
class BBoxUnitContents implements ModelContents {
private AbstractCompilationUnitDescriptor fDescriptor;
private Diagnostic fProblems;
BBoxUnitContents(AbstractCompilationUnitDescriptor descriptor) {
assert descriptor != null;
fDescriptor = descriptor;
}
public Diagnostic getProblems() {
return fProblems;
}
public List<EObject> loadElements(Registry packageRegistry) {
LoadContext loadContext = new LoadContext(packageRegistry);
CompilationUnit cunit = null;
try {
cunit = BlackboxRegistry.INSTANCE.loadCompilationUnit(fDescriptor, loadContext);
} catch (BlackboxException e) {
Diagnostic diagnostic = e.getDiagnostic();
if(diagnostic != null) {
QvtPlugin.logDiagnostic(diagnostic);
} else {
QvtPlugin.error(NLS.bind(ValidationMessages.FailedToLoadUnit,
new Object[] { fDescriptor.getQualifiedName() }), e);
}
String errMessage = NLS.bind(ValidationMessages.FailedToLoadUnit, fDescriptor.getQualifiedName());
fProblems = new BasicDiagnostic(diagnostic.getSource(), diagnostic.getCode(),
QvtOperationalParserUtil.wrappInSeeErrorLogMessage(errMessage), null);
}
if(cunit == null) {
return Collections.emptyList();
}
List<QvtOperationalModuleEnv> elementEnvs = cunit.getElements();
List<EObject> unitElements = new ArrayList<EObject>(elementEnvs.size());
for (QvtOperationalModuleEnv nextEnv : elementEnvs) {
Module module = nextEnv.getModuleContextType();
if(module != null) {
unitElements.add(module);
ASTBindingHelper.setEnvironment(module, nextEnv);
}
}
return unitElements;
}
}
}
|
|
|
Goto Forum:
Current Time: Sat Apr 20 02:12:30 GMT 2024
Powered by FUDForum. Page generated in 0.03020 seconds
|