blob: d436e82a829c2c373863a2ff657cff906f9effae [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2012 IBM Corporation, Borland Software Corp., 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:
* IBM - Initial API and implementation
* E.D.Willink - Refactoring to support extensibility and flexible error handling
* Borland - Bug 265066
*******************************************************************************/
package org.eclipse.ocl.examples.pivot;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.domain.evaluation.DomainModelManager;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationEnvironment;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationVisitor;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationVisitorImpl;
import org.eclipse.ocl.examples.pivot.evaluation.TracingEvaluationVisitor;
import org.eclipse.ocl.examples.pivot.manager.PivotIdResolver;
/**
* Partial implementation of the {@link EnvironmentFactory} interface, useful
* for subclassing to define the Pivot binding for a metamodel.
*/
public abstract class AbstractEnvironmentFactory implements EnvironmentFactory, Adaptable {
private boolean traceEvaluation;
/**
* Initializes me.
*/
protected AbstractEnvironmentFactory() {
super();
}
/**
* Creates an environment for the specified package context.
*
* @param parent the parent environment of the environment to be created
* @param context the package context (must not be <code>null</code>)
* @return the new nested environment
*/
protected Environment createPackageContext(@NonNull Environment parent,
@NonNull org.eclipse.ocl.examples.pivot.Package context) {
Environment result =
createEnvironment(parent);
if (result instanceof AbstractEnvironment) {
((AbstractEnvironment) result)
.setContextPackage(context);
}
return result;
}
// implements the interface method
/* public Environment
createPackageContext(
Environment parent,
List<String> pathname) {
org.eclipse.ocl.examples.pivot.Package contextPackage = lookupPackage(pathname);
return (contextPackage == null)? null : createPackageContext(parent, contextPackage);
} */
// implements the interface method
public @NonNull Environment createClassifierContext(@NonNull Environment parent, @NonNull Type context) {
Environment result =
createEnvironment(parent);
Variable self = parent.getOCLFactory().createVariable();
self.setName(Environment.SELF_VARIABLE_NAME);
self.setType(context);
// result.addElement(self.getName(), self, true);
result.setSelfVariable(self);
return result;
}
// implements the interface method
public @NonNull Environment createInstanceContext(@NonNull Environment parent, @NonNull Object context) {
return createClassifierContext(parent, getClassifier(context));
}
// implements the interface method
public @NonNull Environment createOperationContext(@NonNull Environment parent, @NonNull Operation operation) {
Environment result = createEnvironment(parent);
if (result instanceof AbstractEnvironment) {
((AbstractEnvironment) result).setContextOperation(operation);
}
PivotFactory oclFactory = parent.getOCLFactory();
for (Parameter next : operation.getOwnedParameter()) {
// ensure that we use the OCL primitive types wherever possible
Variable var = oclFactory.createVariable();
var.setName(next.getName());
var.setType(next.getType());
var.setRepresentedParameter(next);
// result.addElement(var.getName(), var, true);
}
return result;
}
// implements the interface method
public @NonNull Environment createPropertyContext(@NonNull Environment parent, @NonNull Property property) {
Environment result =
createEnvironment(parent);
if (result instanceof AbstractEnvironment) {
((AbstractEnvironment) result)
.setContextProperty(property);
}
return result;
}
public @NonNull EvaluationVisitor createEvaluationVisitor(@Nullable Environment environment, @Nullable Object context, @NonNull ExpressionInOCL expression, @Nullable DomainModelManager modelManager) {
if (environment == null) {
environment = createEnvironment();
}
// can determine a more appropriate context from the context
// variable of the expression, to account for stereotype constraints
// context = HelperUtil.getConstraintContext(rootEnvironment, context, expression);
EvaluationEnvironment evaluationEnvironment = createEvaluationEnvironment();
Variable contextVariable = expression.getContextVariable();
if (contextVariable != null) {
PivotIdResolver idResolver = evaluationEnvironment.getMetaModelManager().getIdResolver();
Object value = idResolver.boxedValueOf(context);
evaluationEnvironment.add(contextVariable, value);
}
for (Variable parameterVariable : expression.getParameterVariable()) {
if (parameterVariable != null) {
evaluationEnvironment.add(parameterVariable, null);
}
}
DomainModelManager extents = modelManager;
if (extents == null) {
// let the evaluation environment create one
extents = evaluationEnvironment.createModelManager(context);
}
return createEvaluationVisitor(environment, evaluationEnvironment, extents);
}
// implements the interface method
public @NonNull EvaluationVisitor createEvaluationVisitor(@NonNull Environment env, @NonNull EvaluationEnvironment evalEnv,
@NonNull DomainModelManager modelManager) {
EvaluationVisitor result = new EvaluationVisitorImpl(env, evalEnv, modelManager);
if (isEvaluationTracingEnabled()) {
// decorate the evaluation visitor with tracing support
result = new TracingEvaluationVisitor(result);
}
return result;
}
/**
* Obtains client metamodel's classifier for the specified
* <code>context</code> object, which may be an instance of a classifier
* in the user model or may actually be a classifier in the user model.
*
* @param context a context object or classifier
* @return the user model's classifier for this context object, or the
* context itself if it is a classifier
*/
protected abstract @NonNull Type getClassifier(@NonNull Object context);
/**
* Queries whether tracing of evaluation is enabled. Tracing
* logs the progress of evaluation to the console, which may
* be of use in diagnosing problems.
* <p>
* In an Eclipse environment, tracing is also enabled by turning on the
* <tt>org.eclipse.ocl/debug/evaluation</tt> debug option.
* </p>
*
* @return whether evaluation tracing is enabled
*
* @see #setEvaluationTracingEnabled(boolean)
*/
protected boolean isEvaluationTracingEnabled() {
return traceEvaluation;
}
/**
* Sets whether tracing of evaluation is enabled. Tracing logs
* the progress of parsing to the console, which may be of use in diagnosing
* problems.
* <p>
* In an Eclipse environment, tracing is also enabled by turning on the
* <tt>org.eclipse.ocl/debug/evaluation</tt> debug option.
* </p>
*
* param b whether evaluation tracing is enabled
*
* @see #isEvaluationTracingEnabled()
*/
public void setEvaluationTracingEnabled(boolean b) {
traceEvaluation = b;
}
/**
* The abstract environment factory implementation is adaptable. The
* default implementation adapts to and interface actually implemented by
* the receiver.
* <p>
* Subclasses may override or extend this implementation.
* </p>
*/
@SuppressWarnings("unchecked")
public <T> T getAdapter(java.lang.Class<T> adapterType) {
T result;
if (adapterType.isAssignableFrom(getClass())) {
result = (T) this;
} else {
result = null;
}
return result;
}
}