/******************************************************************************* * Copyright (c) 2009, 2015 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.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(getURI(), 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); 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; } } }