blob: b3bcac1350a92aabded0245c40ec1e35b93a0c64 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2005, 2009 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
*
* </copyright>
*
* $Id: AbstractEnvironmentFactory.java,v 1.4 2011/02/11 20:00:28 ewillink Exp $
*/
package org.eclipse.ocl.examples.pivot;
import org.eclipse.ocl.examples.domain.evaluation.DomainModelManager;
import org.eclipse.ocl.examples.pivot.Operation;
import org.eclipse.ocl.examples.pivot.Parameter;
import org.eclipse.ocl.examples.pivot.Property;
import org.eclipse.ocl.examples.pivot.Type;
import org.eclipse.ocl.examples.pivot.Variable;
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;
/**
* Partial implementation of the {@link EnvironmentFactory} interface, useful
* for subclassing to define the OCL binding for a metamodel. This abstract
* class takes care of some of the more common (and mundane) chores, such as:
* <ul>
* <li>defining the "self" variable in the classifier context</li>
* <li>creating variables for operation parameters in an operation context</li>
* </ul>
* <p>
* The subclass's responsibility (in addition to implementing any other
* interface methods not implemented here) is to define how to:
* </p>
* <ul>
* <li>{@linkplain #getClassifier obtain} the classifier in the
* user model of an input element (which may already be a classifier
* or an may be an M0 instance)</li>
* <li>{@linkplain #lookupPackage lookup} a package in the model associated
* with this environment factory</li>
* </ul>
* <p>
* This class is intended to be extended by clients, for the purpose of
* implementing metamodel-specific environment factories.
* </p>
* <p>
* See the {@link EnvironmentFactory} class for a description of the
* generic type parameters of this class.
* </p>
*
* @author Christian W. Damus (cdamus)
*/
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(Environment parent,
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 Environment
createClassifierContext(
Environment parent,
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 Environment
createInstanceContext(
Environment parent,
Object context) {
return createClassifierContext(parent, getClassifier(context));
}
// implements the interface method
public Environment createOperationContext(Environment parent, 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 Environment
createAttributeContext(
Environment parent,
Property property) {
Environment result =
createEnvironment(parent);
if (result instanceof AbstractEnvironment) {
((AbstractEnvironment) result)
.setContextProperty(property);
}
return result;
}
// implements the interface method
public EvaluationVisitor createEvaluationVisitor(Environment env,
EvaluationEnvironment evalEnv,
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 Type getClassifier(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;
}
}