blob: aa9c8a161233b198720c21e9f9b047a0f2f69d04 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2022 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 v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Borland Software Corporation - initial API and implementation
* Christopher Gerking - bug 537041
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.compiler;
import java.util.ArrayList;
import java.util.Arrays;
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.EPackage.Registry;
import org.eclipse.m2m.internal.qvt.oml.NLS;
import org.eclipse.m2m.internal.qvt.oml.QvtMessage;
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.BlackboxException;
import org.eclipse.m2m.internal.qvt.oml.blackbox.BlackboxRegistry;
import org.eclipse.m2m.internal.qvt.oml.blackbox.BlackboxUnit;
import org.eclipse.m2m.internal.qvt.oml.blackbox.BlackboxUnitDescriptor;
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.emf.util.mmregistry.IMetamodelRegistryProvider;
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(GLOBAL_CONTEXT);
private ResolutionContext fContext;
public BlackboxUnitResolver(URI context) {
fContext = new ResolutionContextImpl(context);
}
public static boolean isBlackboxUnitURI(URI uri) {
return BlackboxUnitDescriptor.URI_QVTO_SCHEME.equals(uri.scheme()) &&
BlackboxUnitDescriptor.URI_BLACKBOX_AUTHORITY.equals(uri.authority());
}
public UnitProxy resolveUnit(String qualifiedName) {
BlackboxUnitDescriptor 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 BlackboxUnitProxy(namespace, name, descriptor);
}
return null;
}
class BlackboxUnitProxy extends UnitProxy {
private BlackboxUnitDescriptor fDescriptor;
BlackboxUnitProxy(String namespace, String name, BlackboxUnitDescriptor descriptor) {
super(namespace, name, descriptor.getURI());
fDescriptor = descriptor;
}
@Override
public int getContentType() {
return UnitProxy.TYPE_MODEL;
}
@Override
public BlackboxUnitContents getContents() {
return new BlackboxUnitContents(fDescriptor);
}
@Override
public UnitResolver getResolver() {
return BlackboxUnitResolver.this;
}
public CompiledUnit load(IMetamodelRegistryProvider provider) {
BlackboxUnitContents contents = getContents();
List<Module> modules = contents.loadElements(CompilerUtils.getEPackageRegistry(fDescriptor.reconvertURI(), provider));
List<QvtOperationalModuleEnv> modelEnvs = new ArrayList<QvtOperationalModuleEnv>(modules.size());
for (Module nextModule : modules) {
QvtOperationalModuleEnv nextEnv = ASTBindingHelper.getEnvironment(nextModule, QvtOperationalModuleEnv.class);
if(nextEnv != null) {
// FIXME -
// 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);
}
}
CompiledUnit compiledUnit = new CompiledUnit(Arrays.asList(ResolverUtils.getNameSegments(getQualifiedName())), getURI(), modelEnvs, provider.getResolutionResourceSet());
Diagnostic loadProblems = contents.getProblems();
if(loadProblems != null) {
compiledUnit.addProblem(new QvtMessage(loadProblems.getMessage()));
}
return compiledUnit;
}
}
class BlackboxUnitContents implements ModelContents {
private BlackboxUnitDescriptor fDescriptor;
private Diagnostic fProblems;
BlackboxUnitContents(BlackboxUnitDescriptor descriptor) {
assert descriptor != null;
fDescriptor = descriptor;
}
public Diagnostic getProblems() {
return fProblems;
}
public List<Module> loadElements(Registry packageRegistry) {
LoadContext loadContext = new LoadContext(packageRegistry);
BlackboxUnit cunit = null;
try {
cunit = fDescriptor.load(loadContext);
if (cunit.getDiagnostic().getSeverity() == Diagnostic.ERROR) {
String errMessage = NLS.bind(ValidationMessages.FailedToLoadUnit, fDescriptor.getQualifiedName());
fProblems = new BasicDiagnostic(cunit.getDiagnostic().getSource(), cunit.getDiagnostic().getCode(),
QvtOperationalParserUtil.wrappInSeeErrorLogMessage(errMessage), null);
}
} 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<Module> unitElements = new ArrayList<Module>(elementEnvs.size());
for (QvtOperationalModuleEnv nextEnv : elementEnvs) {
Module module = nextEnv.getModuleContextType();
if(module != null) {
unitElements.add(module);
ASTBindingHelper.setEnvironment(module, nextEnv);
}
}
return unitElements;
}
}
}