blob: f401aab82ba554912a1e2105505f3d9abf8f03ef [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2018 IBM 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:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.examples.interpreter.console;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.ocl.OCL;
import org.eclipse.ocl.ParserException;
import org.eclipse.ocl.examples.interpreter.console.text.OCLDocument;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.helper.ConstraintKind;
import org.eclipse.ocl.helper.OCLHelper;
import org.eclipse.ocl.util.ToStringVisitor;
/**
* A resource for loading and saving OCL expressions.
*/
public class OCLResource
extends XMIResourceImpl {
private static Map<String, Object> saveOptions = new java.util.HashMap<String, Object>();
static {
saveOptions.put(XMLResource.OPTION_SAVE_TYPE_INFORMATION, true);
}
/**
* Initializes me with my URI.
*
* @param uri my URI
*/
public OCLResource(URI uri) {
super(uri);
}
@Override
protected boolean useIDs() {
return true;
}
@Override
protected boolean useUUIDs() {
return true;
}
/**
* Loads an OCL expression from the specified <code>path</code>. The
* OCL expression is converted to a string using a custom AST visitor that
* renders the string representation.
*
* @param path the absolute path of the XMI file to load
* @return the string representation of the OCL expression, if found
* @throws IOException if anything goes wrong in loading the XMI file
*/
public static String load(String path) throws IOException {
String result = null;
ResourceSet rset = new ResourceSetImpl();
// create and load the resource
OCLResource res = new OCLResource(URI.createFileURI(path));
rset.getResources().add(res);
res.load(Collections.EMPTY_MAP);
OCLExpression<Object> expr = res.getOCLExpression();
if (expr != null) {
result = expr.accept(ToStringVisitor.getInstance(expr));
}
return result;
}
/**
* Saves the specified OCL expression to an XMI file.
*
* @param path the fully-qualified path of the XMI file to save
* @param document the current OCL document
* @param expression the expression to save
*
* @throws RuntimeException if anything goes wrong in parsing
* @throws IOException if anything goes wrong in saving
* @throws ParserException if anything goes wrong in parsing
*/
public static void save(String path, OCLDocument document, String expression)
throws IOException, ParserException {
final OCLResource res = new OCLResource(URI.createFileURI(path));
// create an OCL helper to do our parsing
OCL<?, Object, ?, ?, ?, ?, ?, ?, ?, Object, ?, ?> ocl =
document.getOCLFactory().createOCL(document.getModelingLevel(), res);
OCLHelper<Object, ?, ?, Object> helper = ocl.createOCLHelper();
// set our helper's context classifier to parse against it
ConstraintKind kind = document.getModelingLevel().setContext(
helper, document.getOCLContext(), document.getOCLFactory());
OCLExpression<Object> parsed = null;
switch (document.getModelingLevel()) {
case M2:
parsed = helper.createQuery(expression);
break;
case M1:
Object constraint = helper.createConstraint(kind, expression);
parsed = ocl.getEnvironment().getUMLReflection().getSpecification(
constraint).getBodyExpression();
break;
}
// add the AST to the resource and save it
res.setOCLExpression(parsed);
res.save(saveOptions);
}
/**
* Sets my contents to the specified OCL expression.
*
* @param expr an OCL expression
*/
public void setOCLExpression(OCLExpression<Object> expr) {
// add my expression as the first root, because I already contain
// variables and EPackages defining dynamically-generated types
getContents().add(0, expr);
}
/**
* Obtains the OCL expression that I store.
*
* @return my OCL expression
*/
@SuppressWarnings("unchecked")
public OCLExpression<Object> getOCLExpression() {
OCLExpression<Object> result = null;
if (!getContents().isEmpty()) {
result = (OCLExpression<Object>) getContents().get(0);
}
return result;
}
}