/* * Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Business Objects nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * ValueNode.java * Creation date: (04/06/01 8:19:48 AM) * By: Michael Cheng */ package org.openquark.cal.valuenode; import org.openquark.cal.compiler.QualifiedName; import org.openquark.cal.compiler.SourceModel; import org.openquark.cal.compiler.TypeExpr; import org.openquark.cal.compiler.io.InputPolicy; import org.openquark.cal.compiler.io.OutputPolicy; /** * The underlying tree data structure used to represent values. * ValueNodes are immutable: * @author Michael Cheng */ public abstract class ValueNode { /** The TypeExpr of the data value which this ValueNode represents. */ private final TypeExpr typeExpr; /** * ValueNode constructor. * @param typeExprParam indicates the TypeExpr of the data value which this ValueNode represents. */ public ValueNode(TypeExpr typeExprParam) { super(); this.typeExpr = typeExprParam; } /** * Helper method for copyValueNode(). Checks to see if the new typeExpr is ok for the value node. * Throws an exception if not. */ protected final void checkCopyType(TypeExpr newTypeExpr) { // If the type expr is null, we're not valid anyway. (Maybe we got it from the ValueRunner). if (typeExpr == null) { return; } // check that the types are equivalent if (!typeExpr.sameType(newTypeExpr)) { throw new IllegalStateException("Programming error: attempting to copy a value node replacing type " + typeExpr + " with type " + newTypeExpr); } } /** * Helper method for ValueNode constructors to check if a type expression has a given type constructor * as its root. * @param typeExpr the type expression to check * @param typeConsName the type constructor name to check for * @throws IllegalArgumentException if the pruned type expression is not a type constructor with the given name */ protected static final void checkTypeConstructorName(TypeExpr typeExpr, QualifiedName typeConsName) { if (!typeExpr.hasRootTypeConstructor(typeConsName)) { throw new IllegalArgumentException("type expression is not type constructor " + typeConsName + ": " + typeExpr); } } /** * Makes a copy of this ValueNode (the copy will have the same value, TypeExpr, etc.) * Note: The returned copy will be the same type as this ValueNode. * (Eg: A ColourValueNode's copyValueNode method will return a ColourValueNode.) * @return ValueNode */ public final ValueNode copyValueNode() { ValueNode vn = copyValueNode(typeExpr); return vn; } /** * Makes a copy of this ValueNode, but with another TypeExpr instance (of the same type). * This is a deep copy, with respect to value nodes and the associated type expression. * Note: if the new TypeExpr is a different type from the present TypeExpr, an error is thrown. * @param newTypeExpr the new type of the copied node. * @return ValueNode */ public abstract ValueNode copyValueNode(TypeExpr newTypeExpr); /** * Returns the CAL text representation of the expression represented by this ValueNode. */ public final String getCALValue() { return getCALSourceModel().toSourceText(); } /** * @return the source model representation of the expression represented by this ValueNode. */ public abstract SourceModel.Expr getCALSourceModel(); /** * Returns whether this node contains a parametric value node * @return boolean */ public abstract boolean containsParametricValue(); /** * @return Object the most convenient Java representation of the value held onto by this ValueNode. * The contract of this method is that the returned Object is immutable, since ValueNodes are * intended to be immutable value classes. For example, if this method were to return a List * or other Collection object, the caller should assume that the Collection is not modifiable. */ abstract public Object getValue(); /** * Return an array of objects which are the values needed by the marshaller * described by 'getInputPolicy()'. * @return - an array of Java objects corresponding to the value represented by a value node instance. */ abstract public Object[] getInputJavaValues(); /** * Return an input policy which describes how to marshall a value represented * by a value node from Java to CAL. * @return - the input policy associated with ValueNode instance. */ abstract public InputPolicy getInputPolicy(); /** * Return an output policy which describes how to marshall a value represented * by a value node from CAL to Java. * @return - the output policy associated with the ValueNode instance. */ abstract public OutputPolicy getOutputPolicy(); /** * Set a value which is the result of the marshaller described by * 'getOutputPolicy()'. * @param value - the java value */ abstract public void setOutputJavaValue(Object value); /** * Returns the display text representation of the expression represented by this ValueNode. * @return String */ public abstract String getTextValue(); @Override public String toString() { return getTextValue(); } /** * Returns the TypeExpr of the data value represented by this ValueNode. * @return TypeExpr */ public TypeExpr getTypeExpr() { return typeExpr; } /** * Returns whether the object in the argument is the same as this valueNode in terms of their type and CAL value * @param object * @return boolean */ public boolean sameValue(Object object) { if (object instanceof ValueNode) { ValueNode valueNode = (ValueNode) object; return (getTypeExpr().sameType(valueNode.getTypeExpr()) && getCALValue().equals(valueNode.getCALValue())); } return false; } /** * Returns a new ValueNode according to type TypeExpr, and modeled after valueNode (which means that the returned ValueNode * will have as much common data as possible with valueNode).. * * This will return a new ValueNode with newTypeExpr as its assigned type expression. It does NOT provide a copy * of the newTypeExpr. So be careful not to share this newTypeExpr amongst multiple nodes! * * However, to copy the value of valueNode over to the returned ValueNode, the newTypeExpr that you pass in must be compatible with * the type expression of the value node that you are copying from. (Which means you should create a new TypeExpr and call * TransmuteTypeExpr on it to have it correspond), Otherwise, the valueNode that you create will really have nothing in common with * the valueNode. * @param valueNodeBuilderHelper * @param valueNodeTransformer * @param newTypeExpr * @return ValueNode a new ValueNode with newTypeExpr as its TypeExpr, and having as much common data with this ValueNode as possible. */ public abstract ValueNode transmuteValueNode(ValueNodeBuilderHelper valueNodeBuilderHelper, ValueNodeTransformer valueNodeTransformer, TypeExpr newTypeExpr); }