0001: /*
0002: * This file or a portion of this file is licensed under the terms of
0003: * the Globus Toolkit Public License, found in file ../GTPL, or at
0004: * http://www.globus.org/toolkit/download/license.html. This notice must
0005: * appear in redistributions of this file, with or without modification.
0006: *
0007: * Redistributions of this Software, with or without modification, must
0008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
0009: * some other similar material which is provided with the Software (if
0010: * any).
0011: *
0012: * Copyright 1999-2004 University of Chicago and The University of
0013: * Southern California. All rights reserved.
0014: */
0015:
0016: package org.griphyn.vdl.classes;
0017:
0018: import org.griphyn.vdl.classes.*;
0019: import java.util.*;
0020: import java.io.IOException;
0021: import java.io.Writer;
0022: import java.io.Serializable;
0023:
0024: /**
0025: * <code>Transformation</code> is an implementation of an abstract VDL
0026: * <code>Definition</code>. A transformation describes the immutable
0027: * template of an input, processing, and output (IPO) application. The
0028: * environment is part of the capture. The template can be parametrized
0029: * using formal arguments, which are part of the transformation
0030: * definition. Think of a transformation as something similar to a C
0031: * function definition. Mutable parts are hidden in the arguments, and
0032: * instantiated in <code>Derivation</code>.<p>
0033: *
0034: * FIXME: The mixing of compounds with simple transformations within
0035: * the same class instead of hierarchy needs some serious redesigning.
0036: * Unfortunately, this entails a redesign of just about everything...
0037: *
0038: * @author Jens-S. Vöckler
0039: * @author Yong Zhao
0040: * @version $Revision: 50 $
0041: *
0042: * @see Definition
0043: * @see Definitions
0044: * @see Derivation
0045: */
0046: public class Transformation extends Definition // thus implements VDL
0047: implements Serializable {
0048: /**
0049: * Captures the argument name indexed map of formal arguments. Each
0050: * element is of type {@link Declare} with an optional default value
0051: * of type {@link Value}.
0052: *
0053: * @see Declare
0054: */
0055: private TreeMap m_declareMap;
0056:
0057: /**
0058: * The profile list encapsulates scheduler specific data in a
0059: * generic structure.
0060: *
0061: * @see Profile
0062: */
0063: private ArrayList m_profileList;
0064:
0065: /**
0066: * The argument list describes the command line arguments as sum of
0067: * substrings. Each element is an {@link Argument}, and can be
0068: * optionally addressed by a name.
0069: *
0070: * @see Argument
0071: */
0072: private ArrayList m_argumentList;
0073:
0074: /**
0075: * All arguments are, for ease-of-use, separated by a single
0076: * space. If this is not wanted, the user can overwrite the
0077: * separator, including setting it to the empty string and null.
0078: */
0079: private String m_argumentSeparator = " ";
0080:
0081: /**
0082: * Each compound transformation may declare local variables.
0083: */
0084: private TreeMap m_localMap;
0085:
0086: /**
0087: * Each entry in the call list describes an invocation of another
0088: * transformation, complete with actual arguments etc.
0089: *
0090: * @see Call
0091: */
0092: private ArrayList m_callList;
0093:
0094: /**
0095: * Type accessor for quick distinction between definitions.
0096: * @return the value of {@link Definition#TRANSFORMATION}
0097: */
0098: public int getType() {
0099: return Definition.TRANSFORMATION;
0100: }
0101:
0102: /**
0103: * Default ctor: This ctor will frequently be used by the SAX parser
0104: * to create a hollow instance. Note that a transformation can be named.
0105: */
0106: public Transformation() {
0107: super ();
0108: this .m_argumentList = new ArrayList();
0109: this .m_declareMap = new TreeMap();
0110: this .m_profileList = new ArrayList();
0111: this .m_localMap = new TreeMap();
0112: this .m_callList = new ArrayList();
0113: }
0114:
0115: /**
0116: * Minimum c'tor: Any transformation should be named.
0117: *
0118: * @param name is the name of the transformation in the current namespace
0119: * and version context.
0120: * @see Definition
0121: */
0122: public Transformation(String name) {
0123: super (name);
0124: this .m_argumentList = new ArrayList();
0125: this .m_declareMap = new TreeMap();
0126: this .m_profileList = new ArrayList();
0127: this .m_localMap = new TreeMap();
0128: this .m_callList = new ArrayList();
0129: }
0130:
0131: /**
0132: * Standard ctor: This will name a transformation with the complete
0133: * tripel necessary to access it correctly (w/o guessing).
0134: *
0135: * @param name is the name of the transformation in the current namespace
0136: * and version context.
0137: * @param namespace is the namespace that the transformation resides in.
0138: * @param version is a version number.
0139: *
0140: * @see Definition
0141: */
0142: public Transformation(String namespace, String name, String version) {
0143: super (namespace, name, version);
0144: this .m_argumentList = new ArrayList();
0145: this .m_declareMap = new TreeMap();
0146: this .m_profileList = new ArrayList();
0147: this .m_localMap = new TreeMap();
0148: this .m_callList = new ArrayList();
0149: }
0150:
0151: /**
0152: * Accessor: Adds an argument to the list of arguments
0153: *
0154: * @param vArgument is the argument to append to the command line
0155: * arguments.
0156: * @exception IndexOutOfBounds if the argument does not fit into the list.
0157: * @see Argument
0158: */
0159: public void addArgument(Argument vArgument)
0160: throws IndexOutOfBoundsException {
0161: this .m_argumentList.add(vArgument);
0162: }
0163:
0164: /**
0165: * Accessor: Inserts an argument at an arbitrary place into the list.
0166: * Each component in this vector with an index greater or equal to the
0167: * specified index is shifted upward to have an index one greater than
0168: * the value it had previously.
0169: *
0170: * @param index is the position to insert an argument
0171: * @param vArgument is the argument to append to the command line
0172: * arguments.
0173: * @exception IndexOutOfBounds if the argument does not fit into the list.
0174: * @see #getArgument( int )
0175: * @see #setArgument( int, Argument )
0176: * @see Argument
0177: */
0178: public void addArgument(int index, Argument vArgument)
0179: throws IndexOutOfBoundsException {
0180: this .m_argumentList.add(index, vArgument);
0181: }
0182:
0183: /**
0184: * Accessor: Adds an invocation to the list of calls.
0185: *
0186: * @param vCall is the invocation to append to the list of calls.
0187: * @exception IndexOutOfBounds if the argument does not fit into the list.
0188: * @see Call
0189: */
0190: public void addCall(Call vCall) throws IndexOutOfBoundsException {
0191: this .m_callList.add(vCall);
0192: }
0193:
0194: /**
0195: * Accessor: Inserts an invocation at an arbitrary place into the list.
0196: * Each component in this vector with an index greater or equal to the
0197: * specified index is shifted upward to have an index one greater than
0198: * the value it had previously.
0199: *
0200: * @param index is the position to insert an invocation
0201: * @param vCall is the invocation to append to the list of calls.
0202: * @exception IndexOutOfBounds if the argument does not fit into the list.
0203: * @see #setCall( int, Call )
0204: * @see #getCall( int )
0205: * @see Call
0206: */
0207: public void addCall(int index, Call vCall)
0208: throws IndexOutOfBoundsException {
0209: this .m_callList.add(index, vCall);
0210: }
0211:
0212: /**
0213: * Accessor: Adds a formal argument declaration to the map of declarations.
0214: *
0215: * @param vDeclare is the formal argument to add to the declarations.
0216: * @see #getDeclare( String )
0217: * @see #setDeclare( Declare )
0218: * @see Declare
0219: */
0220: public void addDeclare(Declare vDeclare) {
0221: this .m_declareMap.put(vDeclare.getName(), vDeclare);
0222: }
0223:
0224: /**
0225: * Accessor: Adds a temporary variable declaration to the map of local
0226: * variables.
0227: *
0228: * @param vLocal is the local variable declaration with value.
0229: * @see #getLocal( String )
0230: * @see #setLocal( Local )
0231: * @see Local
0232: */
0233: public void addLocal(Local vLocal) {
0234: this .m_localMap.put(vLocal.getName(), vLocal);
0235: }
0236:
0237: /**
0238: * Accessor: Appends a profile definition to the list of profiles.
0239: *
0240: * @param vProfile is the profile to append to remembered profiles.
0241: * @exception IndexOutOfBounds if the argument does not fit into the list.
0242: * @see Profile
0243: */
0244: public void addProfile(Profile vProfile)
0245: throws IndexOutOfBoundsException {
0246: this .m_profileList.add(vProfile);
0247: }
0248:
0249: /**
0250: * Accessor: Inserts a profile definition at an arbitrary position
0251: * into the list of profiles. Each component in this vector with an
0252: * index greater or equal to the specified index is shifted upward to
0253: * have an index one greater than the value it had previously.
0254: *
0255: * @param index is the position to insert the definitions into.
0256: * @param vProfile is the profile to append to remembered profiles.
0257: * @exception IndexOutOfBounds if the argument does not fit into the list.
0258: * @see #getProfile( int )
0259: * @see #setProfile( int, Profile )
0260: * @see Profile
0261: */
0262: public void addProfile(int index, Profile vProfile)
0263: throws IndexOutOfBoundsException {
0264: this .m_profileList.add(index, vProfile);
0265: }
0266:
0267: /**
0268: * Accessor: Provides an iterator for the <code>Argument</code> list.
0269: *
0270: * @return the iterator for the <code>Argument</code> list.
0271: * @see Argument
0272: * @see java.util.Enumeration
0273: * @deprecated Use the new Collection based interfaces
0274: */
0275: public Enumeration enumerateArgument() {
0276: return Collections.enumeration(this .m_argumentList);
0277: }
0278:
0279: /**
0280: * Accessor: Provides an iterator for the <code>Call</code> list.
0281: *
0282: * @return the iterator for the <code>Call</code> list.
0283: * @see Call
0284: * @see java.util.Enumeration
0285: * @deprecated Use the new Collection based interfaces
0286: */
0287: public Enumeration enumerateCall() {
0288: return Collections.enumeration(this .m_callList);
0289: }
0290:
0291: /**
0292: * Accessor: Provides an iterator for the <code>Declare</code> map.
0293: *
0294: * @return the iterator for the <code>Declare</code> list.
0295: * @see Declare
0296: * @see java.util.Enumeration
0297: * @deprecated Use the new Collection based interfaces
0298: */
0299: public Enumeration enumerateDeclare() {
0300: return Collections.enumeration(this .m_declareMap.values());
0301: }
0302:
0303: /**
0304: * Accessor: Provides an iterator for the local variables.
0305: *
0306: * @return the iterator over all locally declared variables.
0307: * @see Local
0308: * @see java.util.Enumeration
0309: * @deprecated Use the new Collection based interfaces
0310: */
0311: public Enumeration enumerateLocal() {
0312: return Collections.enumeration(this .m_localMap.values());
0313: }
0314:
0315: /**
0316: * Accessor: Provides an iterator for the <code>Profile</code> list.
0317: *
0318: * @return the iterator for the <code>Profile</code> list.
0319: * @see Profile
0320: * @see java.util.Enumeration
0321: * @deprecated Use the new Collection based interfaces
0322: */
0323: public Enumeration enumerateProfile() {
0324: return Collections.enumeration(this .m_profileList);
0325: }
0326:
0327: /**
0328: * Predicate: Determines, if this is a simple TR (as opposed to compound).
0329: * @return true, if this a simple transformation.
0330: */
0331: public boolean isSimple() {
0332: return this .m_callList.size() == 0;
0333: }
0334:
0335: /**
0336: * Accessor: Obtains an <code>Argument</code> at an arbitrary position.
0337: *
0338: * @param index is the place to look up the element at.
0339: * @return the argument at the specified place.
0340: * @throws IndexOutOfBoundsException if the referenced position does
0341: * not exist.
0342: * @see Argument
0343: */
0344: public Argument getArgument(int index)
0345: throws IndexOutOfBoundsException {
0346: //-- check bounds for index
0347: if ((index < 0) || (index >= this .m_argumentList.size())) {
0348: throw new IndexOutOfBoundsException();
0349: }
0350:
0351: return (Argument) this .m_argumentList.get(index);
0352: }
0353:
0354: /**
0355: * Accessor: Obtains the complete commandline arguments. This array is
0356: * a copy to avoid write-through modifications.
0357: *
0358: * @return an array with all commandline arguments inside.
0359: * @see #setArgument( Argument[] )
0360: * @see Argument
0361: * @deprecated Use the new Collection based interfaces
0362: */
0363: public Argument[] getArgument() {
0364: int size = this .m_argumentList.size();
0365: Argument[] mArray = new Argument[size];
0366: System.arraycopy(this .m_argumentList.toArray(new Argument[0]),
0367: 0, mArray, 0, size);
0368: return mArray;
0369: }
0370:
0371: /**
0372: * Accessor: Obtains the count of items in the argument list.
0373: *
0374: * @return the number of arguments in the commandline argument list.
0375: * @see Argument
0376: */
0377: public int getArgumentCount() {
0378: return this .m_argumentList.size();
0379: }
0380:
0381: /**
0382: * Accessor: Obtains the complete commandline arguments. The resulting
0383: * list is read-only.
0384: *
0385: * @return an array with all commandline arguments inside.
0386: * @see #setArgument( Collection )
0387: * @see Argument
0388: */
0389: public java.util.List getArgumentList() {
0390: return Collections.unmodifiableList(this .m_argumentList);
0391: }
0392:
0393: /**
0394: * Gets the separating string between multiple {@link Argument}
0395: * elements.
0396: *
0397: * @return The current state of the separator. The text may be null.
0398: * @see #setArgumentSeparator(String)
0399: */
0400: public String getArgumentSeparator() {
0401: return this .m_argumentSeparator;
0402: }
0403:
0404: /**
0405: * Accessor: Obtains an <code>Call</code> at an arbitrary position.
0406: *
0407: * @param index is the place to look up the element at.
0408: * @return the call at the specified place.
0409: * @throws IndexOutOfBoundsException if the referenced position does
0410: * not exist.
0411: * @see #addCall( int, Call )
0412: * @see #setCall( int, Call )
0413: * @see Call
0414: */
0415: public Call getCall(int index) throws IndexOutOfBoundsException {
0416: //-- check bounds for index
0417: if ((index < 0) || (index >= this .m_callList.size())) {
0418: throw new IndexOutOfBoundsException();
0419: }
0420:
0421: return (Call) this .m_callList.get(index);
0422: } //-- Call getCall(int)
0423:
0424: /**
0425: * Accessor: Obtains the invocation list. This
0426: * array is a copy of the original to avoid write-through modifications.
0427: *
0428: * @return an array with all calls inside.
0429: * @see Call
0430: * @deprecated Use the new Collection based interfaces
0431: */
0432: public Call[] getCall() {
0433: int size = this .m_callList.size();
0434: Call[] mArray = new Call[size];
0435: System.arraycopy(this .m_callList.toArray(new Call[0]), 0,
0436: mArray, 0, size);
0437: return mArray;
0438: }
0439:
0440: /**
0441: * Accessor: Obtains the count of items in the call list.
0442: *
0443: * @return the number of calls in the call list.
0444: * @see Call
0445: */
0446: public int getCallCount() {
0447: return this .m_callList.size();
0448: }
0449:
0450: /**
0451: * Accessor: Obtains the invocation list.
0452: * @return a read-only list with all calls inside.
0453: * @see #setCall( Collection )
0454: * @see Call
0455: */
0456: public java.util.List getCallList() {
0457: return Collections.unmodifiableList(this .m_callList);
0458: }
0459:
0460: /**
0461: * Accessor: Obtains the declaration of a formal argument as referenced
0462: * by its variable name.
0463: *
0464: * @param name is the symbolic index and variable name to obtain the
0465: * declaration for.
0466: * @return the <code>Declare</code> object referenced by the name. May
0467: * return <code>null</code>, if there is no such object.
0468: * @see #addDeclare( Declare )
0469: * @see #setDeclare( Declare )
0470: * @see Declare
0471: */
0472: public Declare getDeclare(String name) {
0473: return (Declare) this .m_declareMap.get(name);
0474: }
0475:
0476: /**
0477: * Accessor: Obtain all known formal arguments. Note that the array
0478: * will be arbitrarily sorted, depending on Java's hash function.
0479: *
0480: * @return a list of all formal arguments.
0481: * @see Declare
0482: * @see #setDeclare( Declare[] )
0483: * @deprecated Use the new Collection based interfaces
0484: */
0485: public Declare[] getDeclare() {
0486: int size = this .m_declareMap.size();
0487: Declare[] mArray = new Declare[size];
0488: this .m_declareMap.values().toArray(mArray);
0489: return mArray;
0490: }
0491:
0492: /**
0493: * Accessor: Counts the number of formal arguments known to this
0494: * transformation.
0495: *
0496: * @return the formal argument count
0497: */
0498: public int getDeclareCount() {
0499: return this .m_declareMap.size();
0500: }
0501:
0502: /**
0503: * Accessor: Obtain all known formal arguments. Note that the list
0504: * will be arbitrarily sorted, depending on Java's hash function.
0505: * It is also a read-only list to avoid modifications outside the API.
0506: *
0507: * @return a list of all formal arguments.
0508: * @see #setDeclare( Collection )
0509: * @see Declare
0510: */
0511: public java.util.List getDeclareList() {
0512: return Collections.unmodifiableList(new ArrayList(
0513: this .m_declareMap.values()));
0514: }
0515:
0516: /**
0517: * Accessor: Obtains all known formal arguments. The map is a read-only
0518: * map to avoid modifications outside the API.
0519: *
0520: * @return a map with all formal arguments.
0521: * @see #setDeclare( Map )
0522: * @see Declare
0523: */
0524: public java.util.Map getDeclareMap() {
0525: return Collections.unmodifiableMap(this .m_declareMap);
0526: }
0527:
0528: /**
0529: * Accessor: Obtains the declaration of a temporary variable as
0530: * referenced by its name.
0531: *
0532: * @param name is the variable name to obtain the declaration for.
0533: * @return the <code>Local</code> object referenced by the name. May
0534: * return <code>null</code>, if there is no such object.
0535: * @see #addLocal( Local )
0536: * @see #setLocal( Local )
0537: * @see Local
0538: */
0539: public Local getLocal(String name) {
0540: return (Local) this .m_localMap.get(name);
0541: }
0542:
0543: /**
0544: * Accessor: Obtain all known temporary variables. Note that the array
0545: * will be arbitrarily sorted, depending on Java's hash function.
0546: *
0547: * @return a list of all temporary variables.
0548: * @see #setLocal( Local[] )
0549: * @see Local
0550: * @deprecated Use the new Collection based interfaces
0551: */
0552: public Local[] getLocal() {
0553: int size = this .m_localMap.size();
0554: Local[] mArray = new Local[size];
0555: this .m_localMap.values().toArray(mArray);
0556: return mArray;
0557: }
0558:
0559: /**
0560: * Accessor: Counts the number of temporary variables known to this
0561: * transformation.
0562: *
0563: * @return the temporary variable count
0564: */
0565: public int getLocalCount() {
0566: return this .m_localMap.size();
0567: }
0568:
0569: /**
0570: * Accessor: Obtains all known temporary variables. Note that the list
0571: * will be arbitrarily sorted, depending on Java's hash function. It
0572: * is also a read-only list to avoid modifications outside the API.
0573: *
0574: * @return a list of all formal arguments.
0575: * @see #setLocal( Collection )
0576: * @see Local
0577: */
0578: public java.util.List getLocalList() {
0579: return Collections.unmodifiableList(new ArrayList(
0580: this .m_localMap.values()));
0581: }
0582:
0583: /**
0584: * Accessor: Obtains all known temporary variables. The map is a
0585: * read-only map to avoid modifications outside the API.
0586: *
0587: * @return a map with all formal arguments.
0588: * @see #setLocal( Map )
0589: * @see Local
0590: */
0591: public java.util.Map getLocalMap() {
0592: return Collections.unmodifiableMap(this .m_localMap);
0593: }
0594:
0595: /**
0596: * Accessor: Obtains an <code>Profile</code> at an arbitrary position.
0597: *
0598: * @param index is the place to look up the element at.
0599: * @exception IndexOutOfBoundsException if the referenced position
0600: * does not exist.
0601: * @see #addProfile( int, Profile )
0602: * @see #setProfile( int, Profile )
0603: * @see Profile
0604: */
0605: public Profile getProfile(int index)
0606: throws IndexOutOfBoundsException {
0607: //-- check bounds for index
0608: if ((index < 0) || (index >= this .m_profileList.size())) {
0609: throw new IndexOutOfBoundsException();
0610: }
0611:
0612: return (Profile) this .m_profileList.get(index);
0613: }
0614:
0615: /**
0616: * Accessor: Obtain a copy of the list of all <code>Profile</code>
0617: * specifications.
0618: *
0619: * @return a collection containing the scheduler specific environment
0620: * options for the job.
0621: * @see #setProfile( Profile[] )
0622: * @see Profile
0623: * @deprecated Use the new Collection based interfaces
0624: */
0625: public Profile[] getProfile() {
0626: int size = this .m_profileList.size();
0627: Profile[] mProfile = new Profile[size];
0628: System.arraycopy(this .m_profileList.toArray(new Profile[0]), 0,
0629: mProfile, 0, size);
0630: return mProfile;
0631: }
0632:
0633: /**
0634: * Accessor: Counts the number of profile specifications known to this job.
0635: *
0636: * @return the number of profiles
0637: * @see Profile
0638: */
0639: public int getProfileCount() {
0640: return this .m_profileList.size();
0641: }
0642:
0643: /**
0644: * Accessor: Obtain a read-only copy of the list of all
0645: * <code>Profile</code> specifications.
0646: *
0647: * @return a collection containing the scheduler specific environment
0648: * options for the job.
0649: * @see #setProfile( Collection )
0650: * @see Profile
0651: */
0652: public java.util.List getProfileList() {
0653: return Collections.unmodifiableList(this .m_profileList);
0654: }
0655:
0656: /**
0657: * Accessor: Provides an iterator for the <code>Argument</code> list.
0658: *
0659: * @return the iterator for the <code>Argument</code> list.
0660: * @see Argument
0661: */
0662: public Iterator iterateArgument() {
0663: return this .m_argumentList.iterator();
0664: }
0665:
0666: /**
0667: * Accessor: Provides an iterator for the <code>Call</code> list.
0668: *
0669: * @return the iterator for the <code>Call</code> list.
0670: * @see Call
0671: */
0672: public Iterator iterateCall() {
0673: return this .m_callList.iterator();
0674: }
0675:
0676: /**
0677: * Accessor: Provides an iterator for the <code>Declare</code> map.
0678: *
0679: * @return the iterator for the <code>Declare</code> list.
0680: * @see Declare
0681: */
0682: public Iterator iterateDeclare() {
0683: return this .m_declareMap.values().iterator();
0684: }
0685:
0686: /**
0687: * Accessor: Provides an iterator for local variables.
0688: *
0689: * @return the iterator over all local variables.
0690: * @see Declare
0691: */
0692: public Iterator iterateLocal() {
0693: return this .m_localMap.values().iterator();
0694: }
0695:
0696: /**
0697: * Accessor: Provides an iterator for the <code>Profile</code> list.
0698: *
0699: * @return the iterator for the <code>Profile</code> list.
0700: * @see Profile
0701: */
0702: public Iterator iterateProfile() {
0703: return this .m_profileList.iterator();
0704: }
0705:
0706: /**
0707: * Accessor: Provides a list iterator for the <code>Argument</code> list.
0708: *
0709: * @return the iterator for the <code>Argument</code> list.
0710: * @see Argument
0711: */
0712: public ListIterator listIterateArgument() {
0713: return this .m_argumentList.listIterator();
0714: }
0715:
0716: /**
0717: * Accessor: Provides a list iterator for the <code>Call</code> list.
0718: *
0719: * @return the iterator for the <code>Call</code> list.
0720: * @see Call
0721: */
0722: public ListIterator listIterateCall() {
0723: return this .m_callList.listIterator();
0724: }
0725:
0726: /**
0727: * Accessor: Provides a list iterator for the <code>Profile</code> list.
0728: *
0729: * @return the iterator for the <code>Profile</code> list.
0730: * @see Profile
0731: */
0732: public ListIterator listIterateProfile() {
0733: return this .m_profileList.listIterator();
0734: }
0735:
0736: /**
0737: * Accessor: Provides a list iterator for the <code>Argument</code> list.
0738: *
0739: * @return the iterator for the <code>Argument</code> list.
0740: * @param start is the start index
0741: * @see Argument
0742: */
0743: public ListIterator listIterateArgument(int start) {
0744: return this .m_argumentList.listIterator(start);
0745: }
0746:
0747: /**
0748: * Accessor: Provides a list iterator for the <code>Call</code> list.
0749: *
0750: * @return the iterator for the <code>Call</code> list.
0751: * @param start is the start index
0752: * @see Call
0753: */
0754: public ListIterator listIterateCall(int start) {
0755: return this .m_callList.listIterator(start);
0756: }
0757:
0758: /**
0759: * Accessor: Provides a list iterator for the <code>Profile</code> list.
0760: *
0761: * @return the iterator for the <code>Profile</code> list.
0762: * @param start is the start index
0763: * @see Profile
0764: */
0765: public ListIterator listIterateProfile(int start) {
0766: return this .m_profileList.listIterator(start);
0767: }
0768:
0769: /**
0770: * Accessor: Removes all commandline arguments.
0771: * @see Argument
0772: */
0773: public void removeAllArgument() {
0774: this .m_argumentList.clear();
0775: }
0776:
0777: /**
0778: * Accessor: Removes all calls.
0779: * @see Call
0780: */
0781: public void removeAllCall() {
0782: this .m_callList.clear();
0783: }
0784:
0785: /**
0786: * Accessor: Removes all formal arguments.
0787: * @see Declare
0788: */
0789: public void removeAllDeclare() {
0790: this .m_declareMap.clear();
0791: }
0792:
0793: /**
0794: * Accessor: Removes all temporary variables.
0795: * @see Local
0796: */
0797: public void removeAllLocal() {
0798: this .m_localMap.clear();
0799: }
0800:
0801: /**
0802: * Accessor: Removes all profile declarations.
0803: * @see Profile
0804: */
0805: public void removeAllProfile() {
0806: this .m_profileList.clear();
0807: }
0808:
0809: /**
0810: * Accessor: Removes a commandline argument fragment from the
0811: * commandline. Each component in this vector with an index greater or
0812: * equal to the specified index is shifted downward to have an index
0813: * one smaller than the value it had previously. The size of this
0814: * vector is decreased by 1.
0815: *
0816: * @param index is the position to remove the argument fragment from.
0817: * @return the removed Argument.
0818: * @exception ArrayIndexOutOfBoundsException if the index was invalid.
0819: * @see Argument
0820: */
0821: public Argument removeArgument(int index) {
0822: return (Argument) this .m_argumentList.remove(index);
0823: }
0824:
0825: /**
0826: * Accessor: Removes a single call fragment from the list of calls.
0827: * Each component in this vector with an index greater or equal to the
0828: * specified index is shifted downward to have an index one smaller
0829: * than the value it had previously. The size of this vector is
0830: * decreased by 1.
0831: *
0832: * @param index is the position to remove the call fragment from.
0833: * @return the removed Call.
0834: * @exception ArrayIndexOutOfBoundsException if the index was invalid.
0835: * @see Call
0836: */
0837: public Call removeCall(int index) {
0838: return (Call) this .m_callList.remove(index);
0839: }
0840:
0841: /**
0842: * Accessor: Removes a formal argument.
0843: *
0844: * @param name is the name of the argument to remove
0845: * @return the removed formal argument.
0846: * @see Declare
0847: */
0848: public Declare removeDeclare(String name) {
0849: return (Declare) this .m_declareMap.remove(name);
0850: }
0851:
0852: /**
0853: * Accessor: Removes a temporary variable.
0854: *
0855: * @param name is the name of the temporary variable to remove
0856: * @return the removed variable.
0857: * @see Local
0858: */
0859: public Local removeLocal(String name) {
0860: return (Local) this .m_localMap.remove(name);
0861: }
0862:
0863: /**
0864: * Accessor: Removes a profile. Each component in this vector with an
0865: * index greater or equal to the specified index is shifted downward
0866: * to have an index one smaller than the value it had previously. The
0867: * size of this vector is decreased by 1.
0868: *
0869: * @param index is the position to remove the profile from.
0870: * @return the removed Profile.
0871: * @exception ArrayIndexOutOfBoundsException if the index was invalid.
0872: * @see Profile
0873: */
0874: public Profile removeProfile(int index) {
0875: return (Profile) this .m_profileList.remove(index);
0876: }
0877:
0878: /**
0879: * Accessor: Overwrites an commandline argument fragment with a new one.
0880: *
0881: * @param index is the position to overwrite the element at
0882: * @param vArgument is the new commandline argument.
0883: * @exception IndexOutOfBoundsException if the position does not exist.
0884: * @see Argument
0885: */
0886: public void setArgument(int index, Argument vArgument)
0887: throws IndexOutOfBoundsException {
0888: //-- check bounds for index
0889: if ((index < 0) || (index >= this .m_argumentList.size())) {
0890: throw new IndexOutOfBoundsException();
0891: }
0892: this .m_argumentList.set(index, vArgument);
0893: }
0894:
0895: /**
0896: * Accessor: Replace the commandline arguments with a new commandline
0897: * argument.
0898: *
0899: * @param argumentArray is the new commandline argument array.
0900: * @see Argument
0901: * @deprecated Use the new Collection based interfaces
0902: */
0903: public void setArgument(Argument[] argumentArray) {
0904: this .m_argumentList.clear();
0905: this .m_argumentList.addAll(Arrays.asList(argumentArray));
0906: }
0907:
0908: /**
0909: * Accessor: Replace the commandline arguments with a new commandline
0910: * argument.
0911: *
0912: * @param arguments is the new commandline argument array.
0913: * @see Argument
0914: */
0915: public void setArgument(java.util.Collection arguments) {
0916: this .m_argumentList.clear();
0917: this .m_argumentList.addAll(arguments);
0918: }
0919:
0920: /**
0921: * Overwrites the internal separator string between neighbouring
0922: * {@link Argument} elements with new content.
0923: *
0924: * @param separator is the new string separating neighbouring arguments.
0925: * @see #getArgumentSeparator()
0926: **/
0927: public void setArgumentSeparator(String separator) {
0928: this .m_argumentSeparator = separator;
0929: }
0930:
0931: /**
0932: * Accessor: Overwrites a call with a new one.
0933: *
0934: * @param index is the position to overwrite the element at
0935: * @param vCall is the new call.
0936: * @exception IndexOutOfBoundsException if the position does not exist.
0937: * @see #addCall( int, Call )
0938: * @see #getCall( int )
0939: * @see Call
0940: */
0941: public void setCall(int index, Call vCall)
0942: throws IndexOutOfBoundsException {
0943: //-- check bounds for index
0944: if ((index < 0) || (index >= this .m_callList.size())) {
0945: throw new IndexOutOfBoundsException();
0946: }
0947: this .m_callList.set(index, vCall);
0948: }
0949:
0950: /**
0951: * Accessor: Replace the calls with a new call list.
0952: *
0953: * @param callArray is the new call array.
0954: * @see Call
0955: * @deprecated Use the new Collection based interfaces
0956: */
0957: public void setCall(Call[] callArray) {
0958: this .m_callList.clear();
0959: this .m_callList.addAll(Arrays.asList(callArray));
0960: }
0961:
0962: /**
0963: * Accessor: Replace the calls with a new call list.
0964: *
0965: * @param calls is the new call array.
0966: * @see Call
0967: */
0968: public void setCall(Collection calls) {
0969: this .m_callList.clear();
0970: this .m_callList.addAll(calls);
0971: }
0972:
0973: /**
0974: * Accessor: Insert or replace a declaration with a new version.
0975: *
0976: * @param vDeclare is the declaration to insert or replace.
0977: * @see Declare
0978: * @see java.util.Hashtable#put( Object, Object )
0979: */
0980: public void setDeclare(Declare vDeclare) {
0981: this .m_declareMap.put(vDeclare.getName(), vDeclare);
0982: }
0983:
0984: /**
0985: * Accessor: Replace all declarations by a new set of declarations.
0986: * This method effectively exchanges all formal arguments of a job.
0987: *
0988: * @param declareArray is the new set of declarations.
0989: * @see Declare
0990: * @deprecated Use the new Collection based interfaces
0991: */
0992: public void setDeclare(Declare[] declareArray) {
0993: //-- copy array
0994: this .m_declareMap.clear();
0995: for (int i = 0; i < declareArray.length; i++) {
0996: this .m_declareMap.put(declareArray[i].getName(),
0997: declareArray[i]);
0998: }
0999: }
1000:
1001: /**
1002: * Accessor: Replace all declarations by a new set of declarations.
1003: * This method effectively exchanges all formal arguments of a job.
1004: *
1005: * @param declares is the new set of declarations.
1006: * @see Declare
1007: */
1008: public void setDeclare(Collection declares) {
1009: this .m_declareMap.clear();
1010: for (Iterator i = declares.iterator(); i.hasNext();) {
1011: Declare d = (Declare) i.next();
1012: this .m_declareMap.put(d.getName(), d);
1013: }
1014: }
1015:
1016: /**
1017: * Accessor: Replace all declarations by a new set of declarations.
1018: * This method effectively exchanges all formal arguments of a job.
1019: *
1020: * @param declares is the new set of declarations.
1021: * @see Declare
1022: */
1023: public void setDeclare(Map declares) {
1024: this .m_declareMap.clear();
1025: this .m_declareMap.putAll(declares);
1026: }
1027:
1028: /**
1029: * Accessor: Inserts or replaces a temporary variable with a new
1030: * version.
1031: *
1032: * @param vLocal is the temporary variable to insert or replace.
1033: * @see Local
1034: * @see java.util.Hashtable#put( Object, Object )
1035: */
1036: public void setLocal(Local vLocal) {
1037: this .m_localMap.put(vLocal.getName(), vLocal);
1038: }
1039:
1040: /**
1041: * Accessor: Replaces all declarations by a new set of declarations.
1042: * This method effectively exchanges all temporary variables.
1043: *
1044: * @param localArray is the new set of local variable declarations.
1045: * @see Local
1046: * @deprecated Use the new Collection based interfaces
1047: */
1048: public void setLocal(Local[] localArray) {
1049: //-- copy array
1050: this .m_localMap.clear();
1051: for (int i = 0; i < localArray.length; i++) {
1052: this .m_localMap.put(localArray[i].getName(), localArray[i]);
1053: }
1054: }
1055:
1056: /**
1057: * Accessor: Replaces all declarations by a new set of declarations.
1058: * This method effectively exchanges all temporary variables.
1059: *
1060: * @param locals is the new set of temporary variable declarations.
1061: * @see Local
1062: */
1063: public void setLocal(Collection locals) {
1064: this .m_localMap.clear();
1065: for (Iterator i = locals.iterator(); i.hasNext();) {
1066: Local d = (Local) i.next();
1067: this .m_localMap.put(d.getName(), d);
1068: }
1069: }
1070:
1071: /**
1072: * Accessor: Replace all declarations by a new set of declarations.
1073: * This method effectively exchanges all temporary variables.
1074: *
1075: * @param locals is the new set of declarations.
1076: * @see Local
1077: */
1078: public void setLocal(Map locals) {
1079: this .m_localMap.clear();
1080: this .m_localMap.putAll(locals);
1081: }
1082:
1083: /**
1084: * Accessor: Overwrites a profile with a new profile
1085: *
1086: * @param index is the position to overwrite the profile at.
1087: * @param vProfile is the new profile to use in overwriting.
1088: * @exception IndexOutOfBoundsException if the position does not exist.
1089: * @see Profile
1090: */
1091: public void setProfile(int index, Profile vProfile)
1092: throws IndexOutOfBoundsException {
1093: //-- check bounds for index
1094: if ((index < 0) || (index >= this .m_profileList.size())) {
1095: throw new IndexOutOfBoundsException();
1096: }
1097: this .m_profileList.set(index, vProfile);
1098: }
1099:
1100: /**
1101: * Accessor: Replace the internal profiles with a new list.
1102: *
1103: * @param profileArray is the new list of profiles to use for the job.
1104: * @see Profile
1105: * @deprecated Use the new Collection based interfaces
1106: */
1107: public void setProfile(Profile[] profileArray) {
1108: this .m_profileList.clear();
1109: this .m_profileList.addAll(Arrays.asList(profileArray));
1110: }
1111:
1112: /**
1113: * Accessor: Replace the internal profiles with a new list.
1114: *
1115: * @param profiles is the new list of profiles to use for the job.
1116: * @see Profile
1117: */
1118: public void setProfile(java.util.Collection profiles) {
1119: this .m_profileList.clear();
1120: this .m_profileList.addAll(profiles);
1121: }
1122:
1123: /**
1124: * Constructs dynamically a short descriptive, hopefully unique
1125: * identifier for this transformation.
1126: *
1127: * @return a string describing the transformation
1128: * @see Object#hashCode()
1129: */
1130: public String identify() {
1131: // short and long ID are identical for transformations.
1132: return super .shortID();
1133: }
1134:
1135: /**
1136: * Dumps the content of the given element into a string. This function
1137: * traverses all sibling classes as necessary and converts the
1138: * data into textual output.
1139: */
1140: public void toString(Writer stream) throws IOException {
1141: String newline = System.getProperty("line.separator", "\r\n");
1142:
1143: stream.write("TR ");
1144: stream.write(this .identify());
1145: stream.write('(');
1146:
1147: // write formal args
1148: if (this .m_declareMap.size() > 0) {
1149: stream.write(newline);
1150: for (Iterator i = this .m_declareMap.values().iterator(); i
1151: .hasNext();) {
1152: stream.write('\t');
1153: ((Declare) i.next()).toString(stream);
1154: if (i.hasNext())
1155: stream.write("," + newline);
1156: }
1157: }
1158:
1159: stream.write(" )");
1160: stream.write(newline);
1161: stream.write('{');
1162: stream.write(newline);
1163:
1164: if (this .isSimple()) {
1165: for (Iterator i = this .m_argumentList.iterator(); i
1166: .hasNext();) {
1167: stream.write(" ");
1168: ((Argument) i.next()).toString(stream);
1169: stream.write(';');
1170: stream.write(newline);
1171: }
1172: } else {
1173: if (this .m_localMap.size() > 0) {
1174: for (Iterator i = this .m_localMap.values().iterator(); i
1175: .hasNext();) {
1176: stream.write(" ");
1177: ((Local) i.next()).toString(stream);
1178: stream.write(';');
1179: stream.write(newline);
1180: }
1181: stream.write(newline);
1182: }
1183:
1184: for (Iterator i = this .m_callList.iterator(); i.hasNext();) {
1185: stream.write(" ");
1186: ((Call) i.next()).toString(stream);
1187: stream.write(';');
1188: stream.write(newline);
1189: }
1190: }
1191:
1192: for (Iterator i = this .m_profileList.iterator(); i.hasNext();) {
1193: stream.write(" ");
1194: ((Profile) i.next()).toString(stream);
1195: stream.write(';');
1196: stream.write(newline);
1197: }
1198:
1199: stream.write('}');
1200: stream.write(newline);
1201: }
1202:
1203: /**
1204: * Dump the state of the current element as XML output. This function
1205: * traverses all sibling classes as necessary, and converts the data
1206: * into pretty-printed XML output. The stream interface should be able
1207: * to handle large output efficiently, if you use a buffered writer.
1208: *
1209: * @param stream is a stream opened and ready for writing. This can also
1210: * be a string stream for efficient output.
1211: * @param indent is a <code>String</code> of spaces used for pretty
1212: * printing. The initial amount of spaces should be an empty string.
1213: * The parameter is used internally for the recursive traversal.
1214: * If a <code>null</code> value is specified, no indentation nor
1215: * linefeeds will be generated.
1216: * @param namespace is the XML schema namespace prefix. If neither
1217: * empty nor null, each element will be prefixed with this prefix,
1218: * and the root element will map the XML namespace.
1219: * @exception IOException if something fishy happens to the stream.
1220: */
1221: public void toXML(Writer stream, String indent, String namespace)
1222: throws IOException {
1223: String newline = System.getProperty("line.separator", "\r\n");
1224: String tag = (namespace != null && namespace.length() > 0) ? namespace
1225: + ":transformation"
1226: : "transformation";
1227:
1228: if (indent != null && indent.length() > 0)
1229: stream.write(indent);
1230: stream.write('<');
1231: stream.write(tag);
1232: super .toXML(stream);
1233:
1234: // add argument separator, if it is not a single space.
1235: // FIXME: This attribute can only appear in simple TR!
1236: if (this .m_argumentSeparator == null
1237: || !this .m_argumentSeparator.equals(" ")) {
1238: stream.write(" argumentSeparator=\"");
1239: if (this .m_argumentSeparator != null)
1240: stream.write(quote(this .m_argumentSeparator, true));
1241: stream.write('"');
1242: }
1243:
1244: if (this .m_declareMap.size() + this .m_argumentList.size()
1245: + this .m_callList.size() + this .m_profileList.size() == 0) {
1246: // empty transformation, no fargs, no body
1247: // FIXME: A compound TR must not be empty!
1248: stream.write("/>");
1249: } else {
1250: // done with opening tag
1251: stream.write('>');
1252: if (indent != null)
1253: stream.write(newline);
1254:
1255: String newindent = indent == null ? null : indent + " ";
1256: for (Iterator i = this .m_declareMap.values().iterator(); i
1257: .hasNext();) {
1258: ((Declare) i.next())
1259: .toXML(stream, newindent, namespace);
1260: }
1261:
1262: if (this .isSimple()) {
1263: for (Iterator i = this .m_argumentList.iterator(); i
1264: .hasNext();) {
1265: ((Argument) i.next()).toXML(stream, newindent,
1266: namespace);
1267: }
1268: } else {
1269: for (Iterator i = this .m_localMap.values().iterator(); i
1270: .hasNext();) {
1271: ((Local) i.next()).toXML(stream, newindent,
1272: namespace);
1273: }
1274:
1275: // a compound TR must have at least one call!
1276: for (Iterator i = this .m_callList.iterator(); i
1277: .hasNext();) {
1278: ((Call) i.next()).toXML(stream, newindent,
1279: namespace);
1280: }
1281: }
1282:
1283: for (Iterator i = this .m_profileList.iterator(); i
1284: .hasNext();) {
1285: ((Profile) i.next())
1286: .toXML(stream, newindent, namespace);
1287: }
1288:
1289: // close tag
1290: if (indent != null && indent.length() > 0)
1291: stream.write(indent);
1292: stream.write("</");
1293: stream.write(tag);
1294: stream.write('>');
1295: }
1296: if (indent != null)
1297: stream.write(newline);
1298: }
1299: }
|