Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.eclipse.ocl.AbstractEvaluationEnvironment Maven / Gradle / Ivy
/**
*
*
* Copyright (c) 2007 IBM 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:
* IBM - Initial API and implementation
*
*
*
* $Id: AbstractEvaluationEnvironment.java,v 1.7 2009/06/25 19:23:52 ewillink Exp $
*/
package org.eclipse.ocl;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.ocl.internal.OCLPlugin;
import org.eclipse.ocl.internal.OCLStatusCodes;
import org.eclipse.ocl.internal.l10n.OCLMessages;
import org.eclipse.ocl.options.Customizable;
import org.eclipse.ocl.options.Option;
import org.eclipse.ocl.util.Adaptable;
import org.eclipse.ocl.util.OCLUtil;
import org.eclipse.ocl.utilities.PredefinedType;
/**
* A partial implementation of the {@link EvaluationEnvironment} interface,
* providing some useful common behaviors. Implementors of metamodel-specific
* environments are encourage to extend this class rather than implement
* an evaluation environment "from scratch."
*
* See the {@link Environment} class for a description of the
* generic type parameters of this class.
*
* Since the 1.2 release, this interface is {@link Adaptable} to support the
* optional adapter protocols such as {@link EvaluationEnvironment.Enumerations}
* and {@link Customizable}.
*
*
* @author Christian W. Damus (cdamus)
*/
public abstract class AbstractEvaluationEnvironment
implements EvaluationEnvironment, Adaptable, Customizable {
private final EvaluationEnvironment parent;
private final Map map = new HashMap();
private final Map, Object> options =
new java.util.HashMap , Object>();
protected AbstractEvaluationEnvironment() {
this(null);
}
protected AbstractEvaluationEnvironment(
EvaluationEnvironment parent) {
this.parent = parent;
}
/**
* Obtains my parent (nesting) environment.
*
* @return my parent environment, or null
if none
*/
protected EvaluationEnvironment getParent() {
return parent;
}
/**
* Returns the value associated with the supplied name
*
* @param name
* the name whose value is to be returned
* @return the value associated with the name
*/
public Object getValueOf(String name) {
return map.get(name);
}
/**
* Replaces the current value of the supplied name with the supplied value.
*
* @param name
* the name
* @param value
* the new value
*/
public void replace(String name, Object value) {
map.put(name, value);
}
/**
* Adds the supplied name and value binding to the environment
*
* @param name
* the name to add
* @param value
* the associated binding
*/
public void add(String name, Object value) {
if (map.containsKey(name)) {
String message = OCLMessages.bind(
OCLMessages.BindingExist_ERROR_,
name,
map.get(name));
throw new IllegalArgumentException(message);
}
map.put(name, value);
}
/**
* Removes the supplied name and binding from the environment (if it exists)
* and returns it.
*
* @param name
* the name to remove
* @return the value associated with the removed name
*/
public Object remove(String name) {
return map.remove(name);
}
/**
* Clears the environment of variables.
*/
public void clear() {
map.clear();
}
/**
* Returns a string representation of the bindings
*/
@Override
public String toString() {
return map.toString();
}
/**
* By default, a subclass will not support overriding the operations defined
* by the OCL Standard Library. This implementation delegates to the
* parent environment (if any), otherwise returns false
.
*/
public boolean overrides(O operation, int opcode) {
return (getParent() != null)? getParent().overrides(operation, opcode) : false;
}
/**
* Implements the inherited method by attempting to find an appropriate
* Java method in the actual type of the source object and invoking
* it. On failure to find or invoke the method (e.g., an exception), the
* OclInvalid result is returned.
*
* @return the result of the Java method invocation, or OclInvalid
* on failure of the method invocation
*/
public Object callOperation(O operation, int opcode, Object source, Object[] args)
throws IllegalArgumentException {
if (getParent() != null) {
return getParent().callOperation(operation, opcode, source, args);
}
Method method = getJavaMethodFor(operation, source);
if (method != null) {
try {
// coerce any collection arguments to EList as necessary
Class>[] parmTypes = method.getParameterTypes();
for (int i = 0; i < parmTypes.length; i++) {
if (EList.class.isAssignableFrom(parmTypes[i])) {
if (args[i] == null) {
args[i] = ECollections.EMPTY_ELIST;
} else if (!(args[i] instanceof Collection>)) {
EList list = new BasicEList.FastCompare(1);
list.add(args[i]);
args[i] = list;
} else if (!(args[i] instanceof EList>)) {
args[i] = new BasicEList.FastCompare((Collection>) args[i]);
}
}
}
return method.invoke(source, args);
} catch (Exception e) {
OCLPlugin.catching(getClass(), "callOperation", e);//$NON-NLS-1$
OCLPlugin.log(
Diagnostic.ERROR,
OCLStatusCodes.IGNORED_EXCEPTION_WARNING,
OCLMessages.bind(
OCLMessages.ErrorMessage_ERROR_,
"calloperation", //$NON-NLS-1$
e.getLocalizedMessage()),
e);
return getInvalidResult();
}
}
// maybe it's a comparison operation that is implemented implicitly
// via the Comparable interface?
switch (opcode) {
case PredefinedType.LESS_THAN:
case PredefinedType.GREATER_THAN:
case PredefinedType.LESS_THAN_EQUAL:
case PredefinedType.GREATER_THAN_EQUAL:
if ((source instanceof Comparable>) && (args.length == 1)) {
@SuppressWarnings("unchecked")
Comparable comparable = (Comparable) source;
Object other = args[0];
switch (opcode) {
case PredefinedType.LESS_THAN:
return comparable.compareTo(other) < 0;
case PredefinedType.GREATER_THAN:
return comparable.compareTo(other) > 0;
case PredefinedType.LESS_THAN_EQUAL:
return comparable.compareTo(other) <= 0;
case PredefinedType.GREATER_THAN_EQUAL:
return comparable.compareTo(other) >= 0;
}
}
break;
}
throw new IllegalArgumentException();
}
/**
* Returns the java method that corresponds to the supplied
* EOperation
*
* @param operation
* the operation
* @return a java method
*/
protected abstract Method getJavaMethodFor(O operation, Object receiver);
/**
* Obtains the language-binding-specific representation of the predefined
* OclInvalid object.
*
* @return OclInvalid
*/
protected abstract Object getInvalidResult();
/**
* Implements the interface method by testing whether I am an instance of
* the requested adapter type.
*/
@SuppressWarnings("unchecked")
public T getAdapter(Class adapterType) {
T result;
if (adapterType.isInstance(this)) {
result = (T) this;
} else {
result = null;
}
return result;
}
protected Map, Object> basicGetOptions() {
return options;
}
public Map , Object> getOptions() {
Customizable parent = (getParent() != null)?
OCLUtil.getAdapter(getParent(), Customizable.class) : null;
Map , Object> result = (parent != null)
? new java.util.HashMap , Object>(parent.getOptions())
: new java.util.HashMap , Object>();
result.putAll(basicGetOptions());
return result;
}
public void setOption(Option option, T value) {
basicGetOptions().put(option, value);
}
public void putOptions(Map extends Option, ? extends T> options) {
Map, Object> myOptions = basicGetOptions();
myOptions.clear();
myOptions.putAll(options);
}
public T removeOption(Option option) {
T result = getValue(option);
basicGetOptions().remove(option);
return result;
}
public Map, T> removeOptions(Collection > options) {
Map , T> result = new java.util.HashMap , T>();
Map , Object> myOptions = basicGetOptions();
for (Option next : options) {
result.put(next, getValue(next));
myOptions.remove(next);
}
return result;
}
public Map, Object> clearOptions() {
Map , Object> myOptions = basicGetOptions();
Map , Object> result = new java.util.HashMap , Object>(
myOptions);
myOptions.clear();
return result;
}
public boolean isEnabled(Option option) {
Boolean result = getValue(option);
return (result == null)? false : result.booleanValue();
}
public T getValue(Option option) {
@SuppressWarnings("unchecked")
T result = (T) getOptions().get(option);
if (result == null) {
Customizable parent = (getParent() != null)?
OCLUtil.getAdapter(getParent(), Customizable.class) : null;
result = (parent != null)? parent.getValue(option)
: option.getDefaultValue();
}
return result;
}
}