/******************************************************************************* * Copyright (c) 2012, 2015 Willink Transformations 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: * E.D.Willink - Initial API and implementation *******************************************************************************/ package org.eclipse.ocl.pivot.internal.context; import java.io.IOException; import java.io.InputStream; import java.util.List; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.plugin.EcorePlugin; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.URIConverter; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.Element; import org.eclipse.ocl.pivot.ExpressionInOCL; import org.eclipse.ocl.pivot.OCLExpression; import org.eclipse.ocl.pivot.PivotFactory; import org.eclipse.ocl.pivot.Type; import org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager; import org.eclipse.ocl.pivot.internal.messages.PivotMessagesInternal; import org.eclipse.ocl.pivot.internal.resource.EnvironmentFactoryAdapter; import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal; import org.eclipse.ocl.pivot.resource.CSResource; import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.ocl.pivot.utilities.EnvironmentFactory; import org.eclipse.ocl.pivot.utilities.Nameable; import org.eclipse.ocl.pivot.utilities.ParserContext; import org.eclipse.ocl.pivot.utilities.ParserException; import org.eclipse.ocl.pivot.utilities.PivotUtil; import org.eclipse.ocl.pivot.utilities.Pivotable; import org.eclipse.ocl.pivot.utilities.StringUtil; public abstract class AbstractParserContext /*extends AdapterImpl*/ implements ParserContext { protected final @NonNull EnvironmentFactoryInternal environmentFactory; protected final @NonNull URI uri; protected @Nullable Element rootElement = null; protected AbstractParserContext(@NonNull EnvironmentFactory environmentFactory, @Nullable URI uri) { this.environmentFactory = (EnvironmentFactoryInternal) environmentFactory; if (uri != null) { this.uri = uri; } else { this.uri = ClassUtil.nonNullEMF(URI.createURI(EcoreUtil.generateUUID() + ".essentialocl")); } } @Override public @NonNull CSResource createBaseResource(@NonNull String expression) throws IOException, ParserException { InputStream inputStream = new URIConverter.ReadableInputStream(expression, "UTF-8"); try { ResourceSetImpl resourceSet = new ResourceSetImpl(); Resource resource = resourceSet.createResource(uri); if (resource == null) { throw new ParserException("Failed to load '" + uri + "'" + getDoSetupMessage()); } if (!(resource instanceof CSResource)) { throw new ParserException("Failed to create Xtext resource for '" + uri + "'" + getDoSetupMessage()); } CSResource baseResource = (CSResource)resource; getEnvironmentFactory().adapt(resource); baseResource.setParserContext(this); baseResource.load(inputStream, null); return baseResource; } finally { inputStream.close(); } } @Override public @Nullable Type getClassContext() { return null; } protected @NonNull String getDoSetupMessage() { if (EcorePlugin.IS_ECLIPSE_RUNNING) { return ""; } String doSetup = environmentFactory.getDoSetupName(uri); if (doSetup == null) { return ""; } return "\n\tMake sure " + doSetup + " has been called."; } public @NonNull EnvironmentFactoryInternal getEnvironmentFactory() { return environmentFactory; } public @Nullable Type getInstanceContext() { return null; } @Override public @NonNull ExpressionInOCL getExpression(@NonNull CSResource resource) throws ParserException { List<EObject> contents = resource.getContents(); int size = contents.size(); if (size < 1) { throw new ParserException("Missing parse returns"); } if (size > 1) { throw new ParserException("Extra parse returns"); } EObject csObject = contents.get(0); if (csObject instanceof Pivotable) { Element pivotElement = ((Pivotable)csObject).getPivot(); if (pivotElement instanceof ExpressionInOCL) { return (ExpressionInOCL) pivotElement; } } throw new ParserException("Non-expression ignored"); } @Override public @NonNull PivotMetamodelManager getMetamodelManager() { return environmentFactory.getMetamodelManager(); } @Override public @Nullable Element getRootElement() { return rootElement; } @Override public void initialize(@NonNull Base2ASConversion conversion, @NonNull ExpressionInOCL expression) { // List<String> language = expression.getLanguage(); // language.clear(); // language.add(PivotConstants.OCL_LANGUAGE); } @Override public @NonNull ExpressionInOCL parse(@Nullable EObject owner, @NonNull String expression) throws ParserException { CSResource resource = null; try { resource = createBaseResource(expression); String childName = owner instanceof Nameable ? ((Nameable)owner).getName() : "<unknown>"; EObject eContainer = owner != null ? owner.eContainer() : null; String parentName = eContainer instanceof Nameable ? ((Nameable)eContainer).getName() : "<unknown>"; PivotUtil.checkResourceErrors(StringUtil.bind(PivotMessagesInternal.ValidationConstraintIsInvalid_ERROR_, parentName, childName, expression.trim()), resource); ExpressionInOCL expressionInOCL = getExpression(resource); expressionInOCL.setBody(expression); return expressionInOCL; } catch (IOException e) { // throw new ParserException("Failed to load expression", e); @NonNull ExpressionInOCL specification = PivotFactory.eINSTANCE.createExpressionInOCL(); OCLExpression invalidValueBody = getMetamodelManager().createInvalidExpression(); PivotUtil.setBody(specification, invalidValueBody, null); return specification; } finally { if (resource != null) { resource.unload(); ResourceSet resourceSet = resource.getResourceSet(); if (resourceSet != null) { resourceSet.getResources().remove(resource); } EnvironmentFactoryAdapter.disposeAll(resource); } } } @Override public void setRootElement(@Nullable Element rootElement) { this.rootElement = rootElement; } }