/* * This file or a portion of this file is licensed under the terms of * the Globus Toolkit Public License, found in file ../GTPL, or at * http://www.globus.org/toolkit/download/license.html. This notice must * appear in redistributions of this file, with or without modification. * * Redistributions of this Software, with or without modification, must * reproduce the GTPL in: (1) the Software, or (2) the Documentation or * some other similar material which is provided with the Software (if * any). * * Copyright 1999-2004 University of Chicago and The University of * Southern California. All rights reserved. */ package org.griphyn.vdl.classes; import org.griphyn.vdl.classes.*; import java.util.*; import java.io.IOException; import java.io.Writer; import java.io.Serializable; /** * <code>Transformation</code> is an implementation of an abstract VDL * <code>Definition</code>. A transformation describes the immutable * template of an input, processing, and output (IPO) application. The * environment is part of the capture. The template can be parametrized * using formal arguments, which are part of the transformation * definition. Think of a transformation as something similar to a C * function definition. Mutable parts are hidden in the arguments, and * instantiated in <code>Derivation</code>.<p> * * FIXME: The mixing of compounds with simple transformations within * the same class instead of hierarchy needs some serious redesigning. * Unfortunately, this entails a redesign of just about everything... * * @author Jens-S. Vöckler * @author Yong Zhao * @version $Revision$ * * @see Definition * @see Definitions * @see Derivation */ public class Transformation extends Definition // thus implements VDL implements Serializable { /** * Captures the argument name indexed map of formal arguments. Each * element is of type {@link Declare} with an optional default value * of type {@link Value}. * * @see Declare */ private TreeMap m_declareMap; /** * The profile list encapsulates scheduler specific data in a * generic structure. * * @see Profile */ private ArrayList m_profileList; /** * The argument list describes the command line arguments as sum of * substrings. Each element is an {@link Argument}, and can be * optionally addressed by a name. * * @see Argument */ private ArrayList m_argumentList; /** * All arguments are, for ease-of-use, separated by a single * space. If this is not wanted, the user can overwrite the * separator, including setting it to the empty string and null. */ private String m_argumentSeparator = " "; /** * Each compound transformation may declare local variables. */ private TreeMap m_localMap; /** * Each entry in the call list describes an invocation of another * transformation, complete with actual arguments etc. * * @see Call */ private ArrayList m_callList; /** * Type accessor for quick distinction between definitions. * @return the value of {@link Definition#TRANSFORMATION} */ public int getType() { return Definition.TRANSFORMATION; } /** * Default ctor: This ctor will frequently be used by the SAX parser * to create a hollow instance. Note that a transformation can be named. */ public Transformation() { super(); this.m_argumentList = new ArrayList(); this.m_declareMap = new TreeMap(); this.m_profileList = new ArrayList(); this.m_localMap = new TreeMap(); this.m_callList = new ArrayList(); } /** * Minimum c'tor: Any transformation should be named. * * @param name is the name of the transformation in the current namespace * and version context. * @see Definition */ public Transformation( String name ) { super(name); this.m_argumentList = new ArrayList(); this.m_declareMap = new TreeMap(); this.m_profileList = new ArrayList(); this.m_localMap = new TreeMap(); this.m_callList = new ArrayList(); } /** * Standard ctor: This will name a transformation with the complete * tripel necessary to access it correctly (w/o guessing). * * @param name is the name of the transformation in the current namespace * and version context. * @param namespace is the namespace that the transformation resides in. * @param version is a version number. * * @see Definition */ public Transformation( String namespace, String name, String version ) { super(namespace,name,version); this.m_argumentList = new ArrayList(); this.m_declareMap = new TreeMap(); this.m_profileList = new ArrayList(); this.m_localMap = new TreeMap(); this.m_callList = new ArrayList(); } /** * Accessor: Adds an argument to the list of arguments * * @param vArgument is the argument to append to the command line * arguments. * @exception IndexOutOfBounds if the argument does not fit into the list. * @see Argument */ public void addArgument( Argument vArgument ) throws IndexOutOfBoundsException { this.m_argumentList.add(vArgument); } /** * Accessor: Inserts an argument at an arbitrary place into the list. * Each component in this vector with an index greater or equal to the * specified index is shifted upward to have an index one greater than * the value it had previously. * * @param index is the position to insert an argument * @param vArgument is the argument to append to the command line * arguments. * @exception IndexOutOfBounds if the argument does not fit into the list. * @see #getArgument( int ) * @see #setArgument( int, Argument ) * @see Argument */ public void addArgument( int index, Argument vArgument ) throws IndexOutOfBoundsException { this.m_argumentList.add(index, vArgument); } /** * Accessor: Adds an invocation to the list of calls. * * @param vCall is the invocation to append to the list of calls. * @exception IndexOutOfBounds if the argument does not fit into the list. * @see Call */ public void addCall( Call vCall ) throws IndexOutOfBoundsException { this.m_callList.add(vCall); } /** * Accessor: Inserts an invocation at an arbitrary place into the list. * Each component in this vector with an index greater or equal to the * specified index is shifted upward to have an index one greater than * the value it had previously. * * @param index is the position to insert an invocation * @param vCall is the invocation to append to the list of calls. * @exception IndexOutOfBounds if the argument does not fit into the list. * @see #setCall( int, Call ) * @see #getCall( int ) * @see Call */ public void addCall( int index, Call vCall ) throws IndexOutOfBoundsException { this.m_callList.add(index, vCall); } /** * Accessor: Adds a formal argument declaration to the map of declarations. * * @param vDeclare is the formal argument to add to the declarations. * @see #getDeclare( String ) * @see #setDeclare( Declare ) * @see Declare */ public void addDeclare( Declare vDeclare ) { this.m_declareMap.put( vDeclare.getName(), vDeclare ); } /** * Accessor: Adds a temporary variable declaration to the map of local * variables. * * @param vLocal is the local variable declaration with value. * @see #getLocal( String ) * @see #setLocal( Local ) * @see Local */ public void addLocal( Local vLocal ) { this.m_localMap.put( vLocal.getName(), vLocal ); } /** * Accessor: Appends a profile definition to the list of profiles. * * @param vProfile is the profile to append to remembered profiles. * @exception IndexOutOfBounds if the argument does not fit into the list. * @see Profile */ public void addProfile( Profile vProfile ) throws IndexOutOfBoundsException { this.m_profileList.add(vProfile); } /** * Accessor: Inserts a profile definition at an arbitrary position * into the list of profiles. Each component in this vector with an * index greater or equal to the specified index is shifted upward to * have an index one greater than the value it had previously. * * @param index is the position to insert the definitions into. * @param vProfile is the profile to append to remembered profiles. * @exception IndexOutOfBounds if the argument does not fit into the list. * @see #getProfile( int ) * @see #setProfile( int, Profile ) * @see Profile */ public void addProfile( int index, Profile vProfile ) throws IndexOutOfBoundsException { this.m_profileList.add(index, vProfile); } /** * Accessor: Provides an iterator for the <code>Argument</code> list. * * @return the iterator for the <code>Argument</code> list. * @see Argument * @see java.util.Enumeration * @deprecated Use the new Collection based interfaces */ public Enumeration enumerateArgument() { return Collections.enumeration(this.m_argumentList); } /** * Accessor: Provides an iterator for the <code>Call</code> list. * * @return the iterator for the <code>Call</code> list. * @see Call * @see java.util.Enumeration * @deprecated Use the new Collection based interfaces */ public Enumeration enumerateCall() { return Collections.enumeration(this.m_callList); } /** * Accessor: Provides an iterator for the <code>Declare</code> map. * * @return the iterator for the <code>Declare</code> list. * @see Declare * @see java.util.Enumeration * @deprecated Use the new Collection based interfaces */ public Enumeration enumerateDeclare() { return Collections.enumeration(this.m_declareMap.values()); } /** * Accessor: Provides an iterator for the local variables. * * @return the iterator over all locally declared variables. * @see Local * @see java.util.Enumeration * @deprecated Use the new Collection based interfaces */ public Enumeration enumerateLocal() { return Collections.enumeration(this.m_localMap.values()); } /** * Accessor: Provides an iterator for the <code>Profile</code> list. * * @return the iterator for the <code>Profile</code> list. * @see Profile * @see java.util.Enumeration * @deprecated Use the new Collection based interfaces */ public Enumeration enumerateProfile() { return Collections.enumeration(this.m_profileList); } /** * Predicate: Determines, if this is a simple TR (as opposed to compound). * @return true, if this a simple transformation. */ public boolean isSimple() { return this.m_callList.size() == 0; } /** * Accessor: Obtains an <code>Argument</code> at an arbitrary position. * * @param index is the place to look up the element at. * @return the argument at the specified place. * @throws IndexOutOfBoundsException if the referenced position does * not exist. * @see Argument */ public Argument getArgument(int index) throws IndexOutOfBoundsException { //-- check bounds for index if ((index < 0) || (index >= this.m_argumentList.size())) { throw new IndexOutOfBoundsException(); } return (Argument) this.m_argumentList.get(index); } /** * Accessor: Obtains the complete commandline arguments. This array is * a copy to avoid write-through modifications. * * @return an array with all commandline arguments inside. * @see #setArgument( Argument[] ) * @see Argument * @deprecated Use the new Collection based interfaces */ public Argument[] getArgument() { int size = this.m_argumentList.size(); Argument[] mArray = new Argument[size]; System.arraycopy( this.m_argumentList.toArray(new Argument[0]), 0, mArray, 0, size ); return mArray; } /** * Accessor: Obtains the count of items in the argument list. * * @return the number of arguments in the commandline argument list. * @see Argument */ public int getArgumentCount() { return this.m_argumentList.size(); } /** * Accessor: Obtains the complete commandline arguments. The resulting * list is read-only. * * @return an array with all commandline arguments inside. * @see #setArgument( Collection ) * @see Argument */ public java.util.List getArgumentList() { return Collections.unmodifiableList(this.m_argumentList); } /** * Gets the separating string between multiple {@link Argument} * elements. * * @return The current state of the separator. The text may be null. * @see #setArgumentSeparator(String) */ public String getArgumentSeparator() { return this.m_argumentSeparator; } /** * Accessor: Obtains an <code>Call</code> at an arbitrary position. * * @param index is the place to look up the element at. * @return the call at the specified place. * @throws IndexOutOfBoundsException if the referenced position does * not exist. * @see #addCall( int, Call ) * @see #setCall( int, Call ) * @see Call */ public Call getCall(int index) throws IndexOutOfBoundsException { //-- check bounds for index if ((index < 0) || (index >= this.m_callList.size())) { throw new IndexOutOfBoundsException(); } return (Call) this.m_callList.get(index); } //-- Call getCall(int) /** * Accessor: Obtains the invocation list. This * array is a copy of the original to avoid write-through modifications. * * @return an array with all calls inside. * @see Call * @deprecated Use the new Collection based interfaces */ public Call[] getCall() { int size = this.m_callList.size(); Call[] mArray = new Call[size]; System.arraycopy( this.m_callList.toArray( new Call[0] ), 0, mArray, 0, size ); return mArray; } /** * Accessor: Obtains the count of items in the call list. * * @return the number of calls in the call list. * @see Call */ public int getCallCount() { return this.m_callList.size(); } /** * Accessor: Obtains the invocation list. * @return a read-only list with all calls inside. * @see #setCall( Collection ) * @see Call */ public java.util.List getCallList() { return Collections.unmodifiableList( this.m_callList ); } /** * Accessor: Obtains the declaration of a formal argument as referenced * by its variable name. * * @param name is the symbolic index and variable name to obtain the * declaration for. * @return the <code>Declare</code> object referenced by the name. May * return <code>null</code>, if there is no such object. * @see #addDeclare( Declare ) * @see #setDeclare( Declare ) * @see Declare */ public Declare getDeclare(String name) { return (Declare) this.m_declareMap.get(name); } /** * Accessor: Obtain all known formal arguments. Note that the array * will be arbitrarily sorted, depending on Java's hash function. * * @return a list of all formal arguments. * @see Declare * @see #setDeclare( Declare[] ) * @deprecated Use the new Collection based interfaces */ public Declare[] getDeclare() { int size = this.m_declareMap.size(); Declare[] mArray = new Declare[size]; this.m_declareMap.values().toArray(mArray); return mArray; } /** * Accessor: Counts the number of formal arguments known to this * transformation. * * @return the formal argument count */ public int getDeclareCount() { return this.m_declareMap.size(); } /** * Accessor: Obtain all known formal arguments. Note that the list * will be arbitrarily sorted, depending on Java's hash function. * It is also a read-only list to avoid modifications outside the API. * * @return a list of all formal arguments. * @see #setDeclare( Collection ) * @see Declare */ public java.util.List getDeclareList() { return Collections.unmodifiableList( new ArrayList(this.m_declareMap.values()) ); } /** * Accessor: Obtains all known formal arguments. The map is a read-only * map to avoid modifications outside the API. * * @return a map with all formal arguments. * @see #setDeclare( Map ) * @see Declare */ public java.util.Map getDeclareMap() { return Collections.unmodifiableMap( this.m_declareMap ); } /** * Accessor: Obtains the declaration of a temporary variable as * referenced by its name. * * @param name is the variable name to obtain the declaration for. * @return the <code>Local</code> object referenced by the name. May * return <code>null</code>, if there is no such object. * @see #addLocal( Local ) * @see #setLocal( Local ) * @see Local */ public Local getLocal(String name) { return (Local) this.m_localMap.get(name); } /** * Accessor: Obtain all known temporary variables. Note that the array * will be arbitrarily sorted, depending on Java's hash function. * * @return a list of all temporary variables. * @see #setLocal( Local[] ) * @see Local * @deprecated Use the new Collection based interfaces */ public Local[] getLocal() { int size = this.m_localMap.size(); Local[] mArray = new Local[size]; this.m_localMap.values().toArray(mArray); return mArray; } /** * Accessor: Counts the number of temporary variables known to this * transformation. * * @return the temporary variable count */ public int getLocalCount() { return this.m_localMap.size(); } /** * Accessor: Obtains all known temporary variables. Note that the list * will be arbitrarily sorted, depending on Java's hash function. It * is also a read-only list to avoid modifications outside the API. * * @return a list of all formal arguments. * @see #setLocal( Collection ) * @see Local */ public java.util.List getLocalList() { return Collections.unmodifiableList( new ArrayList(this.m_localMap.values()) ); } /** * Accessor: Obtains all known temporary variables. The map is a * read-only map to avoid modifications outside the API. * * @return a map with all formal arguments. * @see #setLocal( Map ) * @see Local */ public java.util.Map getLocalMap() { return Collections.unmodifiableMap( this.m_localMap ); } /** * Accessor: Obtains an <code>Profile</code> at an arbitrary position. * * @param index is the place to look up the element at. * @exception IndexOutOfBoundsException if the referenced position * does not exist. * @see #addProfile( int, Profile ) * @see #setProfile( int, Profile ) * @see Profile */ public Profile getProfile(int index) throws IndexOutOfBoundsException { //-- check bounds for index if ((index < 0) || (index >= this.m_profileList.size())) { throw new IndexOutOfBoundsException(); } return (Profile) this.m_profileList.get(index); } /** * Accessor: Obtain a copy of the list of all <code>Profile</code> * specifications. * * @return a collection containing the scheduler specific environment * options for the job. * @see #setProfile( Profile[] ) * @see Profile * @deprecated Use the new Collection based interfaces */ public Profile[] getProfile() { int size = this.m_profileList.size(); Profile[] mProfile = new Profile[size]; System.arraycopy( this.m_profileList.toArray(new Profile[0]), 0, mProfile, 0, size ); return mProfile; } /** * Accessor: Counts the number of profile specifications known to this job. * * @return the number of profiles * @see Profile */ public int getProfileCount() { return this.m_profileList.size(); } /** * Accessor: Obtain a read-only copy of the list of all * <code>Profile</code> specifications. * * @return a collection containing the scheduler specific environment * options for the job. * @see #setProfile( Collection ) * @see Profile */ public java.util.List getProfileList() { return Collections.unmodifiableList(this.m_profileList); } /** * Accessor: Provides an iterator for the <code>Argument</code> list. * * @return the iterator for the <code>Argument</code> list. * @see Argument */ public Iterator iterateArgument() { return this.m_argumentList.iterator(); } /** * Accessor: Provides an iterator for the <code>Call</code> list. * * @return the iterator for the <code>Call</code> list. * @see Call */ public Iterator iterateCall() { return this.m_callList.iterator(); } /** * Accessor: Provides an iterator for the <code>Declare</code> map. * * @return the iterator for the <code>Declare</code> list. * @see Declare */ public Iterator iterateDeclare() { return this.m_declareMap.values().iterator(); } /** * Accessor: Provides an iterator for local variables. * * @return the iterator over all local variables. * @see Declare */ public Iterator iterateLocal() { return this.m_localMap.values().iterator(); } /** * Accessor: Provides an iterator for the <code>Profile</code> list. * * @return the iterator for the <code>Profile</code> list. * @see Profile */ public Iterator iterateProfile() { return this.m_profileList.iterator(); } /** * Accessor: Provides a list iterator for the <code>Argument</code> list. * * @return the iterator for the <code>Argument</code> list. * @see Argument */ public ListIterator listIterateArgument() { return this.m_argumentList.listIterator(); } /** * Accessor: Provides a list iterator for the <code>Call</code> list. * * @return the iterator for the <code>Call</code> list. * @see Call */ public ListIterator listIterateCall() { return this.m_callList.listIterator(); } /** * Accessor: Provides a list iterator for the <code>Profile</code> list. * * @return the iterator for the <code>Profile</code> list. * @see Profile */ public ListIterator listIterateProfile() { return this.m_profileList.listIterator(); } /** * Accessor: Provides a list iterator for the <code>Argument</code> list. * * @return the iterator for the <code>Argument</code> list. * @param start is the start index * @see Argument */ public ListIterator listIterateArgument( int start ) { return this.m_argumentList.listIterator(start); } /** * Accessor: Provides a list iterator for the <code>Call</code> list. * * @return the iterator for the <code>Call</code> list. * @param start is the start index * @see Call */ public ListIterator listIterateCall( int start ) { return this.m_callList.listIterator(start); } /** * Accessor: Provides a list iterator for the <code>Profile</code> list. * * @return the iterator for the <code>Profile</code> list. * @param start is the start index * @see Profile */ public ListIterator listIterateProfile( int start ) { return this.m_profileList.listIterator(start); } /** * Accessor: Removes all commandline arguments. * @see Argument */ public void removeAllArgument() { this.m_argumentList.clear(); } /** * Accessor: Removes all calls. * @see Call */ public void removeAllCall() { this.m_callList.clear(); } /** * Accessor: Removes all formal arguments. * @see Declare */ public void removeAllDeclare() { this.m_declareMap.clear(); } /** * Accessor: Removes all temporary variables. * @see Local */ public void removeAllLocal() { this.m_localMap.clear(); } /** * Accessor: Removes all profile declarations. * @see Profile */ public void removeAllProfile() { this.m_profileList.clear(); } /** * Accessor: Removes a commandline argument fragment from the * commandline. Each component in this vector with an index greater or * equal to the specified index is shifted downward to have an index * one smaller than the value it had previously. The size of this * vector is decreased by 1. * * @param index is the position to remove the argument fragment from. * @return the removed Argument. * @exception ArrayIndexOutOfBoundsException if the index was invalid. * @see Argument */ public Argument removeArgument(int index) { return (Argument) this.m_argumentList.remove(index); } /** * Accessor: Removes a single call fragment from the list of calls. * Each component in this vector with an index greater or equal to the * specified index is shifted downward to have an index one smaller * than the value it had previously. The size of this vector is * decreased by 1. * * @param index is the position to remove the call fragment from. * @return the removed Call. * @exception ArrayIndexOutOfBoundsException if the index was invalid. * @see Call */ public Call removeCall(int index) { return (Call) this.m_callList.remove(index); } /** * Accessor: Removes a formal argument. * * @param name is the name of the argument to remove * @return the removed formal argument. * @see Declare */ public Declare removeDeclare(String name) { return (Declare) this.m_declareMap.remove(name); } /** * Accessor: Removes a temporary variable. * * @param name is the name of the temporary variable to remove * @return the removed variable. * @see Local */ public Local removeLocal(String name) { return (Local) this.m_localMap.remove(name); } /** * Accessor: Removes a profile. Each component in this vector with an * index greater or equal to the specified index is shifted downward * to have an index one smaller than the value it had previously. The * size of this vector is decreased by 1. * * @param index is the position to remove the profile from. * @return the removed Profile. * @exception ArrayIndexOutOfBoundsException if the index was invalid. * @see Profile */ public Profile removeProfile(int index) { return (Profile) this.m_profileList.remove(index); } /** * Accessor: Overwrites an commandline argument fragment with a new one. * * @param index is the position to overwrite the element at * @param vArgument is the new commandline argument. * @exception IndexOutOfBoundsException if the position does not exist. * @see Argument */ public void setArgument(int index, Argument vArgument) throws IndexOutOfBoundsException { //-- check bounds for index if ((index < 0) || (index >= this.m_argumentList.size())) { throw new IndexOutOfBoundsException(); } this.m_argumentList.set(index, vArgument); } /** * Accessor: Replace the commandline arguments with a new commandline * argument. * * @param argumentArray is the new commandline argument array. * @see Argument * @deprecated Use the new Collection based interfaces */ public void setArgument(Argument[] argumentArray) { this.m_argumentList.clear(); this.m_argumentList.addAll( Arrays.asList(argumentArray) ); } /** * Accessor: Replace the commandline arguments with a new commandline * argument. * * @param arguments is the new commandline argument array. * @see Argument */ public void setArgument(java.util.Collection arguments) { this.m_argumentList.clear(); this.m_argumentList.addAll(arguments); } /** * Overwrites the internal separator string between neighbouring * {@link Argument} elements with new content. * * @param separator is the new string separating neighbouring arguments. * @see #getArgumentSeparator() **/ public void setArgumentSeparator( String separator ) { this.m_argumentSeparator = separator; } /** * Accessor: Overwrites a call with a new one. * * @param index is the position to overwrite the element at * @param vCall is the new call. * @exception IndexOutOfBoundsException if the position does not exist. * @see #addCall( int, Call ) * @see #getCall( int ) * @see Call */ public void setCall(int index, Call vCall) throws IndexOutOfBoundsException { //-- check bounds for index if ((index < 0) || (index >= this.m_callList.size())) { throw new IndexOutOfBoundsException(); } this.m_callList.set(index, vCall); } /** * Accessor: Replace the calls with a new call list. * * @param callArray is the new call array. * @see Call * @deprecated Use the new Collection based interfaces */ public void setCall(Call[] callArray) { this.m_callList.clear(); this.m_callList.addAll( Arrays.asList(callArray) ); } /** * Accessor: Replace the calls with a new call list. * * @param calls is the new call array. * @see Call */ public void setCall( Collection calls ) { this.m_callList.clear(); this.m_callList.addAll(calls); } /** * Accessor: Insert or replace a declaration with a new version. * * @param vDeclare is the declaration to insert or replace. * @see Declare * @see java.util.Hashtable#put( Object, Object ) */ public void setDeclare(Declare vDeclare) { this.m_declareMap.put(vDeclare.getName(),vDeclare); } /** * Accessor: Replace all declarations by a new set of declarations. * This method effectively exchanges all formal arguments of a job. * * @param declareArray is the new set of declarations. * @see Declare * @deprecated Use the new Collection based interfaces */ public void setDeclare(Declare[] declareArray) { //-- copy array this.m_declareMap.clear(); for (int i = 0; i < declareArray.length; i++) { this.m_declareMap.put(declareArray[i].getName(),declareArray[i]); } } /** * Accessor: Replace all declarations by a new set of declarations. * This method effectively exchanges all formal arguments of a job. * * @param declares is the new set of declarations. * @see Declare */ public void setDeclare( Collection declares ) { this.m_declareMap.clear(); for ( Iterator i=declares.iterator(); i.hasNext(); ) { Declare d = (Declare) i.next(); this.m_declareMap.put(d.getName(), d); } } /** * Accessor: Replace all declarations by a new set of declarations. * This method effectively exchanges all formal arguments of a job. * * @param declares is the new set of declarations. * @see Declare */ public void setDeclare( Map declares ) { this.m_declareMap.clear(); this.m_declareMap.putAll(declares); } /** * Accessor: Inserts or replaces a temporary variable with a new * version. * * @param vLocal is the temporary variable to insert or replace. * @see Local * @see java.util.Hashtable#put( Object, Object ) */ public void setLocal(Local vLocal) { this.m_localMap.put(vLocal.getName(),vLocal); } /** * Accessor: Replaces all declarations by a new set of declarations. * This method effectively exchanges all temporary variables. * * @param localArray is the new set of local variable declarations. * @see Local * @deprecated Use the new Collection based interfaces */ public void setLocal(Local[] localArray) { //-- copy array this.m_localMap.clear(); for (int i = 0; i < localArray.length; i++) { this.m_localMap.put(localArray[i].getName(),localArray[i]); } } /** * Accessor: Replaces all declarations by a new set of declarations. * This method effectively exchanges all temporary variables. * * @param locals is the new set of temporary variable declarations. * @see Local */ public void setLocal( Collection locals ) { this.m_localMap.clear(); for ( Iterator i=locals.iterator(); i.hasNext(); ) { Local d = (Local) i.next(); this.m_localMap.put(d.getName(), d); } } /** * Accessor: Replace all declarations by a new set of declarations. * This method effectively exchanges all temporary variables. * * @param locals is the new set of declarations. * @see Local */ public void setLocal( Map locals ) { this.m_localMap.clear(); this.m_localMap.putAll(locals); } /** * Accessor: Overwrites a profile with a new profile * * @param index is the position to overwrite the profile at. * @param vProfile is the new profile to use in overwriting. * @exception IndexOutOfBoundsException if the position does not exist. * @see Profile */ public void setProfile(int index, Profile vProfile) throws IndexOutOfBoundsException { //-- check bounds for index if ((index < 0) || (index >= this.m_profileList.size())) { throw new IndexOutOfBoundsException(); } this.m_profileList.set(index, vProfile); } /** * Accessor: Replace the internal profiles with a new list. * * @param profileArray is the new list of profiles to use for the job. * @see Profile * @deprecated Use the new Collection based interfaces */ public void setProfile( Profile[] profileArray ) { this.m_profileList.clear(); this.m_profileList.addAll( Arrays.asList(profileArray) ); } /** * Accessor: Replace the internal profiles with a new list. * * @param profiles is the new list of profiles to use for the job. * @see Profile */ public void setProfile( java.util.Collection profiles ) { this.m_profileList.clear(); this.m_profileList.addAll( profiles ); } /** * Constructs dynamically a short descriptive, hopefully unique * identifier for this transformation. * * @return a string describing the transformation * @see Object#hashCode() */ public String identify() { // short and long ID are identical for transformations. return super.shortID(); } /** * Dumps the content of the given element into a string. This function * traverses all sibling classes as necessary and converts the * data into textual output. */ public void toString( Writer stream ) throws IOException { String newline = System.getProperty( "line.separator", "\r\n" ); stream.write( "TR " ); stream.write( this.identify() ); stream.write( '(' ); // write formal args if ( this.m_declareMap.size() > 0 ) { stream.write( newline ); for ( Iterator i=this.m_declareMap.values().iterator(); i.hasNext(); ) { stream.write('\t'); ((Declare) i.next()).toString(stream); if ( i.hasNext() ) stream.write("," + newline); } } stream.write( " )" ); stream.write( newline ); stream.write( '{' ); stream.write( newline ); if ( this.isSimple() ) { for ( Iterator i=this.m_argumentList.iterator(); i.hasNext(); ) { stream.write( " " ); ((Argument) i.next()).toString(stream); stream.write( ';' ); stream.write(newline); } } else { if ( this.m_localMap.size() > 0 ) { for ( Iterator i=this.m_localMap.values().iterator(); i.hasNext(); ) { stream.write( " " ); ((Local) i.next()).toString(stream); stream.write( ';' ); stream.write(newline); } stream.write(newline); } for ( Iterator i=this.m_callList.iterator(); i.hasNext(); ) { stream.write( " " ); ((Call) i.next()).toString(stream); stream.write( ';' ); stream.write(newline); } } for ( Iterator i=this.m_profileList.iterator(); i.hasNext(); ) { stream.write( " " ); ((Profile) i.next()).toString(stream); stream.write( ';' ); stream.write(newline); } stream.write( '}' ); stream.write(newline); } /** * Dump the state of the current element as XML output. This function * traverses all sibling classes as necessary, and converts the data * into pretty-printed XML output. The stream interface should be able * to handle large output efficiently, if you use a buffered writer. * * @param stream is a stream opened and ready for writing. This can also * be a string stream for efficient output. * @param indent is a <code>String</code> of spaces used for pretty * printing. The initial amount of spaces should be an empty string. * The parameter is used internally for the recursive traversal. * If a <code>null</code> value is specified, no indentation nor * linefeeds will be generated. * @param namespace is the XML schema namespace prefix. If neither * empty nor null, each element will be prefixed with this prefix, * and the root element will map the XML namespace. * @exception IOException if something fishy happens to the stream. */ public void toXML( Writer stream, String indent, String namespace ) throws IOException { String newline = System.getProperty( "line.separator", "\r\n" ); String tag = ( namespace != null && namespace.length() > 0 ) ? namespace + ":transformation" : "transformation"; if ( indent != null && indent.length() > 0 ) stream.write( indent ); stream.write( '<' ); stream.write( tag ); super.toXML(stream); // add argument separator, if it is not a single space. // FIXME: This attribute can only appear in simple TR! if ( this.m_argumentSeparator == null || ! this.m_argumentSeparator.equals(" ") ) { stream.write( " argumentSeparator=\""); if ( this.m_argumentSeparator != null ) stream.write( quote(this.m_argumentSeparator,true) ); stream.write('"'); } if ( this.m_declareMap.size() + this.m_argumentList.size() + this.m_callList.size() + this.m_profileList.size() == 0 ) { // empty transformation, no fargs, no body // FIXME: A compound TR must not be empty! stream.write( "/>" ); } else { // done with opening tag stream.write( '>' ); if ( indent != null ) stream.write( newline ); String newindent = indent==null ? null : indent + " "; for ( Iterator i=this.m_declareMap.values().iterator(); i.hasNext(); ) { ((Declare) i.next()).toXML( stream, newindent, namespace ); } if ( this.isSimple() ) { for ( Iterator i=this.m_argumentList.iterator(); i.hasNext(); ) { ((Argument) i.next()).toXML( stream, newindent, namespace ); } } else { for ( Iterator i=this.m_localMap.values().iterator(); i.hasNext(); ) { ((Local) i.next()).toXML( stream, newindent, namespace ); } // a compound TR must have at least one call! for ( Iterator i=this.m_callList.iterator(); i.hasNext(); ) { ((Call) i.next()).toXML( stream, newindent, namespace ); } } for ( Iterator i=this.m_profileList.iterator(); i.hasNext(); ) { ((Profile) i.next()).toXML( stream, newindent, namespace ); } // close tag if ( indent != null && indent.length() > 0 ) stream.write( indent ); stream.write( "</" ); stream.write( tag ); stream.write( '>' ); } if ( indent != null ) stream.write( newline ); } }