/*
* 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.
*/
/*
* Argument.java
* Creation date: (1/30/01 5:52:16 PM)
* By: Luke Evans
*/
package org.openquark.gems.client;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.openquark.cal.compiler.TypeExpr;
import org.openquark.util.Pair;
/**
* A representation of a single function argument.
* This class is a utility package class designed to be useful in several situations
* where function arguments need to be passed around.
* Creation date: (1/30/01 5:52:16 PM)
* @author Luke Evans
*/
public class Argument {
/**
* Argument status enum pattern.
* Creation date: (Aug 14, 2002 12:29:16 PM)
* @author Edward Lam
*/
public static final class Status {
private final String typeString;
private Status(String s) {
typeString = s;
}
@Override
public String toString() {
return typeString;
}
/** This argument is unconnected, unburnt. */
public static final Status NATURAL = new Status("NATURAL");
/** This argument's type is undefined. */
public static final Status TYPE_UNDEFINED = new Status("TYPE_UNDEFINED");
/** This argument is burnt. */
public static final Status BURNT = new Status("BURNT");
/** This argument is connected. */
public static final Status CONNECTED = new Status("CONNECTED");
/** This argument is connected, but is unused (eg. if it doesn't appear in code gem text). */
public static final Status CONNECTED_UNUSED = new Status("CONNECTED_UNUSED");
/** This argument has a connection causing a type clash. */
public static final Status TYPE_CLASH = new Status("TYPE_CLASH");
}
/**
* A simple wrapper class to hold an argument's (string) name and type.
* @author Edward Lam
*/
public static final class NameTypePair {
private final String argName;
private final TypeExpr type;
/**
* Construct an Argument from qualified name and type
* @param argName String the name of the argument
* @param type TypeExpr the type
*/
public NameTypePair(String argName, TypeExpr type) {
this.argName = argName;
this.type = type;
}
/**
* Name field accessor.
* @return the name field of the argument
*/
public String getName() {
return argName;
}
/**
* Type field accessor.
* @return TypeExpr the type field of the argument
*/
public TypeExpr getType() {
return type;
}
}
/**
* This is a class to encapsulate information about an argument during the load process.
* This is used in cases where information about the argument is obtained at an earlier stage in the load process
* from where the information can actually be used.
* @author Edward Lam
*/
public static class LoadInfo {
/**
* Map from gem to its argument info, which is a pair of:
* Input identifier: (input gem id, input index)
* Other info: this can be null.
* */
private final Map<Gem, List<Pair<Pair<String, Integer>, Object>>> gemToArgumentInfoListMap = new HashMap<Gem, List<Pair<Pair<String, Integer>, Object>>>();
/**
* Trivial constructor for this class.
*/
public LoadInfo() {
}
/**
* @see #addArgument(Gem, String, Integer, Object) {
*/
public void addArgument(Gem gem, String inputGemId, Integer inputIndex) {
addArgument(gem, inputGemId, inputIndex, null);
}
/**
* Add an argument to this load info object.
* @param gem the gem associated with the argument.
* @param inputGemId the id of the gem on which the input appears.
* @param inputIndex the index of the inputs on the gem in which it appears.
* @param otherInfo any other info to associate with the input. May be null.
*/
public void addArgument(Gem gem, String inputGemId, Integer inputIndex, Object otherInfo) {
List<Pair<Pair<String, Integer>, Object>> argumentInfoList = gemToArgumentInfoListMap.get(gem);
if (argumentInfoList == null) {
argumentInfoList = new ArrayList<Pair<Pair<String, Integer>, Object>>();
gemToArgumentInfoListMap.put(gem, argumentInfoList);
}
Pair<String, Integer> argumentIdPair = new Pair<String, Integer>(inputGemId, inputIndex);
argumentInfoList.add(new Pair<Pair<String, Integer>, Object>(argumentIdPair, otherInfo));
}
/**
* Change the info in this load info object so that getting info for a given gem returns the info for another gem.
* @param oldGem the gem to be replaced.
* @param newGem the gem for which, when asked for its info, the info for oldGem will be returned.
*/
public void remapGem(Gem oldGem, Gem newGem) {
// This deals with the remapping of the target collector while loading.
gemToArgumentInfoListMap.put(newGem, gemToArgumentInfoListMap.get(oldGem));
}
/**
* Get the number of arguments associated with a given gem.
* @param gem the gem in question.
* @return the number of arguments associated with a given gem.
*/
public int getNArguments(Gem gem) {
List<Pair<Pair<String, Integer>, Object>> argumentInfoList = gemToArgumentInfoListMap.get(gem);
if (argumentInfoList == null) {
return 0;
}
return argumentInfoList.size();
}
/**
* Get the input information held by this info object.
* @param gem the gem for which the argument info is relevant.
* @param argumentIndex the index of the argument within the gem's argument info.
* @return Pair of (input gem id, input index)
*/
public Pair<String, Integer> getInputInfo(Gem gem, int argumentIndex) {
List<Pair<Pair<String, Integer>, Object>> argumentInfoList = gemToArgumentInfoListMap.get(gem);
return argumentInfoList.get(argumentIndex).fst();
}
/**
* Get the non-input information held by this info object.
* @param gem the gem for which the argument info is relevant.
* @param argumentIndex the index of the argument within the gem's argument info.
* @return the other info associated with the argument - may be null.
*/
public Object getOtherInfo(Gem gem, int argumentIndex) {
List<Pair<Pair<String, Integer>, Object>> argumentInfoList = gemToArgumentInfoListMap.get(gem);
return argumentInfoList.get(argumentIndex).snd();
}
}
}