/* * 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. */ /* * InputPolicy.java * Created: Jan 19, 2004 at 12:15:01 PM * By: Raymond Cypher */ package org.openquark.cal.compiler.io; import org.openquark.cal.compiler.SourceModel; import org.openquark.cal.compiler.SourceModel.Expr; import org.openquark.cal.compiler.SourceModel.TypeExprDefn; import org.openquark.cal.module.Cal.Core.CAL_Prelude; /** * The InputPolicy class contains the information necessary for the runtime to marshal * Java input values into the CAL domain. * @author RCypher * @author mbyne */ public final class InputPolicy { /** * this expression is used for inputting CAL values, it has the following form: * unsafeFromCalValue # input */ private static final SourceModel.Expr calValueInputExpr = SourceModel.Expr.BinaryOp.Compose.make( SourceModel.Expr.makeGemCall(CAL_Prelude.Functions.unsafeFromCalValue), SourceModel.Expr.makeGemCall(CAL_Prelude.Functions.input)); /** * this expression is used as the default input marshaler */ private static final SourceModel.Expr defaultInputExpr = SourceModel.Expr.makeGemCall(CAL_Prelude.Functions.input); /** * This is the default input policy. It can be used for for inputs that are inputable * and are not ambiguous, e.g. Double, String, [Int], etc, but not Num a => a, [a], etc */ public static final InputPolicy DEFAULT_INPUT_POLICY = makeWithMarshaler(defaultInputExpr); /** * This input policy is: (unsafeCoerce # ( input :: JObject -> CalValue)) * It can be used for inputting an opaque CAL value (Prelude.CalValue), typically obtained using the CAL_VALUE_OUTPUT_POLICY * or STRICT_CAL_VALUE_OUTPUT_POLICY, to a CAL function. The CAL function must not have an ambiguous type for the corresponding parameter. * If the type is ambiguous you should use makeTypedCalValueInputPolicy. * <p> * @see #makeTypedCalValueInputPolicy */ public static final InputPolicy CAL_VALUE_INPUT_POLICY = makeWithMarshaler(calValueInputExpr); /** * This is a typed input policy for Prelude.Boolean values. It should be used instead of * the default input policy when the functionalAgent is polymorphic * and it needs to be bound to a Boolean. */ public static final InputPolicy BOOLEAN_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Boolean)); /** * This is a typed input policy for Prelude.Char values. It should be used instead of * the default input policy when the functionalAgent is polymorphic * and it needs to be bound to a Char. */ public static final InputPolicy CHAR_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Char)); /** * This is a typed input policy for Prelude.Byte values. It should be used instead of * the default input policy when the functionalAgent is polymorphic * and it needs to be bound to a Byte. */ public static final InputPolicy BYTE_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Byte)); /** * This is a typed input policy for Prelude.Short values. It should be used instead of * the default input policy when the functionalAgent is polymorphic * and it needs to be bound to a Short. */ public static final InputPolicy SHORT_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Short)); /** * This is a typed input policy for Prelude.Int values. It should be used instead of * the default input policy when the functionalAgent has a polymorphic input * and it needs to be bound to an Int. */ public static final InputPolicy INT_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Int)); /** * This is a typed input policy for Prelude.Long values. It should be used instead of * the default input policy when the functionalAgent has a polymorphic input * and it needs to be bound to a Long. */ public static final InputPolicy LONG_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Long)); /** * This is a typed input policy for Prelude.Float values. It should be used instead of * the default input policy when the functionalAgent is polymorphic * and it needs to be bound to a Float. */ public static final InputPolicy FLOAT_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Float)); /** * This is a typed input policy for Prelude.Double values. It should be used instead of * the default input policy when the functionalAgent has a polymorphic input * and it needs to be bound to a Double. */ public static final InputPolicy DOUBLE_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Double)); /** * This is a typed input policy for Prelude.String values. It should be used instead of * the default input policy when the functionalAgent has a polymorphic input * and it needs to be bound to a String. */ public static final InputPolicy STRING_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.String)); /** * This is a typed input policy for Prelude.Integer values. It should be used instead of * the default input policy when the functionalAgent is polymorphic * and it needs to be bound to a Integer. */ public static final InputPolicy INTEGER_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Integer)); /** * This is a typed input policy for Prelude.Decimal values. It should be used instead of * the default input policy when the functionalAgent is polymorphic * and it needs to be bound to a Decimal. */ public static final InputPolicy DECIMAL_INPUT_POLICY = makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.Decimal)); /** A piece of CAL source code that converts from JObject(s) to a CAL type. Cannot be null. */ private final SourceModel.Expr marshaler; /** The number of arguments needed by the marshaler. Must be zero or more.*/ private final int nArguments; /** * Constructs an InputPolicy with an expression in source model * representation specifying the marshaler. * * @param type * the CAL type to marshal to, cannot be null * @param marshaler * the marshaler that converts from JObject(s) to a CAL type, cannot be null * @param nArguments * the number of arguments needed by the marshaler, must be zero or more */ private InputPolicy (SourceModel.TypeExprDefn type, SourceModel.Expr marshaler, int nArguments) { if (marshaler == null) { throw new NullPointerException("Argument marshaler cannot be null."); } if (type == null) { throw new NullPointerException("Argument typeExprDefn cannot be null."); } if (nArguments < 0) { throw new IllegalArgumentException("Argument nArguments must be 0 or more."); } SourceModel.TypeExprDefn marshalerType = type; for (int i = 0; i < nArguments; i++) { marshalerType = SourceModel.TypeExprDefn.Function.make( SourceModel.TypeExprDefn.TypeCons.make(CAL_Prelude.TypeConstructors.JObject), marshalerType); } this.marshaler = SourceModel.Expr.ExprTypeSignature.make(marshaler, SourceModel.TypeSignature.make(marshalerType)); this.nArguments = nArguments; } /** * Constructs an InputPolicy with an expression in source model * representation specifying the marshaler. * @param marshaler source expression representing the marshaler, this cannot be null. */ private InputPolicy (SourceModel.Expr marshaler) { if (marshaler == null) { throw new NullPointerException("Argument marshaler cannot be null."); } this.marshaler = marshaler; this.nArguments = 1; } /** * This is a factory method for creating a typed default input policy * It should be used when the input is ambiguous (e.g a) and an explicit type is required. * If the input is non-ambiguous (e.g. Double) it is easier to use DEFAULT_INPUT_POLICY * @param type the CAL type of the input * @return the input policy * * @see #DEFAULT_INPUT_POLICY */ public static InputPolicy makeTypedDefaultInputPolicy(SourceModel.TypeExprDefn type) { return makeWithTypeAndMarshaler(type, defaultInputExpr, 1); } /** * This is a factory method for creating a CAL Value input policy * It should be used when the input is ambiguous (e.g [a]) and an explicit type is required. * If the input is non-ambiguous (e.g. [Double]) it is easier to use CAL_VALUE_INPUT_POLICY * @param type the type of the opaque CAL value * @return the input policy * * @see #CAL_VALUE_INPUT_POLICY */ public static InputPolicy makeTypedCalValueInputPolicy(SourceModel.TypeExprDefn type) { return makeWithTypeAndMarshaler(type, calValueInputExpr, 1); } /** * This is a factory method to create a new input policy with a specified marshaler * @param marshaler * @return the new input policy */ public static InputPolicy makeWithMarshaler(Expr marshaler) { return new InputPolicy(marshaler); } /** * This is a factory method for creating an input policy with a typedefn and a marshaler * @param type * @param marshaler * @param nArguments the number of arguments with input policy requires * @return the new input policy */ public static InputPolicy makeWithTypeAndMarshaler(TypeExprDefn type, Expr marshaler, int nArguments) { return new InputPolicy(type, marshaler, nArguments); } /** * Get the source model expression representing the marshaler. * @return a marshaler expression from JObject(s) to a CAL type. This is never null. */ public SourceModel.Expr getMarshaler() { return marshaler; } /** * Get the number of arguments used by the marshaler. * @return the number of arguments needed by the marshaler. This is always zero or more. */ public int getNArguments() { return nArguments; } /** * {@inheritDoc} */ @Override public String toString () { return "InputPolicy: Marshaler = " + marshaler + ", nArguments = " + nArguments; } }