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: package org.griphyn.vdl.classes;
0016:
0017: import org.griphyn.vdl.classes.*;
0018: import java.util.*;
0019: import java.io.Writer;
0020: import java.io.IOException;
0021: import java.io.Serializable;
0022:
0023: /**
0024: * This class captures the logical filename and its linkage. Also,
0025: * some static methods allow to use the linkage constants outside
0026: * the class.
0027: *
0028: * <code>LFN</code> extends the <code>Leaf</code> class by adding
0029: * a filename and linkage type.
0030: *
0031: * @author Jens-S. Vöckler
0032: * @author Yong Zhao
0033: * @version $Revision: 460 $
0034: *
0035: * @see Leaf
0036: * @see Text
0037: * @see Use
0038: *
0039: * @see Value
0040: * @see Scalar
0041: * @see List
0042: */
0043: public class LFN extends Leaf implements Cloneable, Serializable {
0044: /**
0045: * Linkage type: no linkage, usually used for constants etc.
0046: * It can also be used to indicate that the linkage is unknown.
0047: * The NONE linkage does not participate in DAG construction.
0048: */
0049: public static final int NONE = 0;
0050:
0051: /**
0052: * Linkage type: input file.
0053: */
0054: public static final int INPUT = 1;
0055:
0056: /**
0057: * Linkage type: output file.
0058: */
0059: public static final int OUTPUT = 2;
0060:
0061: /**
0062: * Linkage type: file is used as input and output. Please note that
0063: * this linkage does not allow for DAG linking.
0064: */
0065: public static final int INOUT = 3;
0066:
0067: /**
0068: * The filename is the logical name of the file. With the help of
0069: * the replica location service (RLS), the physical filename is
0070: * determined by the concrete planner.
0071: */
0072: private String m_filename;
0073:
0074: /**
0075: * The linkage type of the logical file aids the linkage process.
0076: */
0077: private int m_link = LFN.NONE;
0078:
0079: /**
0080: * Predicate to determine, if an integer is within the valid range for
0081: * linkage types.
0082: *
0083: * @param x is the integer to test for in-intervall.
0084: * @return true, if the integer satisfies {@link LFN#NONE}
0085: * ≤ x ≤ {@link LFN#INOUT}, false otherwise.
0086: */
0087: public static boolean isInRange(int x) {
0088: return ((x >= LFN.NONE) && (x <= LFN.INOUT));
0089: }
0090:
0091: /**
0092: * Converts an integer into the symbolic linkage type represented by
0093: * the constant.
0094: *
0095: * @param x is the integer with the linkage type to symbolically convert
0096: * @return a string with the symbolic linkage name, or null, if the
0097: * constant is out of range.
0098: */
0099: public static String toString(int x) {
0100: switch (x) {
0101: case LFN.NONE:
0102: return "none";
0103: case LFN.INPUT:
0104: return "input";
0105: case LFN.OUTPUT:
0106: return "output";
0107: case LFN.INOUT:
0108: return "inout";
0109: default:
0110: return null;
0111: }
0112: }
0113:
0114: /**
0115: * Marks a filename for registration in a replica catalog. If marked
0116: * with true, the replica registration will not take place. This is
0117: * useful for transient or non-important results. Regular, tracked
0118: * files are marked with false.
0119: *
0120: * @see #m_dontTransfer
0121: * @see #m_temporary
0122: */
0123: private boolean m_dontRegister = false;
0124:
0125: /**
0126: * Transfer mode: The transfer of the file to the result collector
0127: * is mandatory. Failure to transfer the file will make the workflow
0128: * fail.
0129: */
0130: public static final int XFER_MANDATORY = 0; // false
0131:
0132: /**
0133: * Transfer mode: The transfer of the file to the result collector
0134: * is optional. Failure to transfer the file will <b>not</b> abort
0135: * the workflow.
0136: */
0137: public static final int XFER_OPTIONAL = 1;
0138:
0139: /**
0140: * Transfer mode: The file will not be transferred to the result
0141: * collector.
0142: */
0143: public static final int XFER_NOT = 2; // true
0144:
0145: /**
0146: * Predicate to determine, if an integer is within the valid range for
0147: * transfer modes.
0148: *
0149: * @param x is the integer to test for in-intervall.
0150: * @return true, if the integer satisfies {@link LFN#XFER_MANDATORY}
0151: * ≤ x ≤ {@link LFN#XFER_NOT}, false otherwise.
0152: */
0153: public static boolean transferInRange(int x) {
0154: return ((x >= LFN.XFER_MANDATORY) && (x <= LFN.XFER_NOT));
0155: }
0156:
0157: /**
0158: * Converts an integer into the symbolic transfer mode represented by
0159: * the constant.
0160: *
0161: * @param x is the integer with the linkage type to symbolically convert
0162: * @return a string with the symbolic linkage name, or null, if the
0163: * constant is out of range.
0164: */
0165: public static String transferString(int x) {
0166: switch (x) {
0167: case LFN.XFER_MANDATORY:
0168: return "true";
0169: case LFN.XFER_OPTIONAL:
0170: return "optional";
0171: case LFN.XFER_NOT:
0172: return "false";
0173: default:
0174: return null;
0175: }
0176: }
0177:
0178: /**
0179: * Type of File: Denotes a data file. They are generally looked up in a replica
0180: * catalog.
0181: */
0182: public static final int TYPE_DATA = 0;
0183:
0184: /**
0185: * Type of File: Denotes an executable file. They are generally looked up in a
0186: * transformation catalog.
0187: */
0188: public static final int TYPE_EXECUTABLE = 1;
0189:
0190: /**
0191: * Type of File: Denotes a pattern. They are generally looked up in a
0192: * pattern catalog.
0193: */
0194: public static final int TYPE_PATTERN = 2;
0195:
0196: /**
0197: * Predicate to determine, if an integer is within the valid range for
0198: * type
0199: *
0200: * @param x is the integer to test for in-intervall.
0201: * @return true, if the integer satisfies {@link LFN#TYPE_DATA}
0202: * ≤ x ≤ {@link LFN#TYPE_PATTERN}, false otherwise.
0203: */
0204: public static boolean typeInRange(int x) {
0205: return ((x >= LFN.TYPE_DATA) && (x <= LFN.TYPE_PATTERN));
0206: }
0207:
0208: /**
0209: * Converts an integer into the symbolic type mode represented by
0210: * the constant.
0211: *
0212: * @param x is the integer with the linkage type to symbolically convert
0213: * @return a string with the symbolic linkage name, or null, if the
0214: * constant is out of range.
0215: */
0216: public static String typeString(int x) {
0217: switch (x) {
0218: case TYPE_DATA:
0219: return "data";
0220: case TYPE_EXECUTABLE:
0221: return "executable";
0222: case TYPE_PATTERN:
0223: return "pattern";
0224: default:
0225: return null;
0226: }
0227: }
0228:
0229: /**
0230: * Converts a String into the corresponding integer value.
0231: *
0232: * @param x is the String to symbolically convert
0233: * @return an integer with the value or -1 if not valid.
0234: */
0235: public static int typeInt(String x) {
0236: int result = -1;
0237: if (x == null) {
0238: return result;
0239: }
0240:
0241: if (x.equalsIgnoreCase("data")) {
0242: result = TYPE_DATA;
0243: } else if (x.equalsIgnoreCase("executable")) {
0244: result = TYPE_EXECUTABLE;
0245: } else if (x.equalsIgnoreCase("pattern")) {
0246: result = TYPE_PATTERN;
0247: }
0248: return result;
0249: }
0250:
0251: /**
0252: * Marks a filename for transfer to the result collector. If marked
0253: * with true, the file is usually a temporary file, and will not be
0254: * transferred to the output collector. Inter-pool transfers may still
0255: * happen in multi-pool mode. Regular, tracked files are marked with
0256: * false. Optional transfers have a special mark.
0257: *
0258: * @see #m_dontRegister
0259: * @see #m_temporary
0260: */
0261: private int m_dontTransfer = XFER_MANDATORY;
0262:
0263: /**
0264: * If a filename is marked transient, the higher level planners might
0265: * have some notion where to place it, or how to name it. Lower level
0266: * planners are not necessarily required to follow this hint.
0267: *
0268: * @see #m_dontRegister
0269: * @see #m_dontTransfer
0270: */
0271: private String m_temporary = null;
0272:
0273: /**
0274: * If a filename is marked as optional, it's non-existence must not
0275: * stop a workflow. Regular files, however, are not optional.
0276: */
0277: private boolean m_optional = false;
0278:
0279: /**
0280: * The type of the filename, whether it refers to a data, pattern or executable.
0281: */
0282: private int m_type = TYPE_DATA;
0283:
0284: /**
0285: * Creates and returns a copy of this object.
0286: * @return a new instance.
0287: */
0288: public Object clone() {
0289: return new LFN(this .m_filename, this .m_link, this .m_temporary,
0290: this .m_dontRegister, this .m_dontTransfer,
0291: this .m_optional);
0292: }
0293:
0294: /**
0295: * ctor.
0296: */
0297: public LFN() {
0298: super ();
0299: }
0300:
0301: /**
0302: * Default ctor: create an instance with a logical filename. The linkage
0303: * defaults to {@link LFN#NONE}.
0304: *
0305: * @param filename is the logical filename to store.
0306: */
0307: public LFN(String filename) {
0308: super ();
0309: this .m_filename = filename;
0310: this .m_dontRegister = false;
0311: this .m_dontTransfer = XFER_MANDATORY;
0312: }
0313:
0314: /**
0315: * ctor: create a file with a name and linkage.
0316: *
0317: * @param filename is the logical filename to store.
0318: * @param link is the linkage of the file to remember.
0319: * @throws IllegalArgumentException if the linkage does not match the
0320: * legal range.
0321: */
0322: public LFN(String filename, int link)
0323: throws IllegalArgumentException {
0324: super ();
0325: this .m_filename = filename;
0326: this .m_dontRegister = false;
0327: this .m_dontTransfer = XFER_MANDATORY;
0328: if (LFN.isInRange(link))
0329: this .m_link = link;
0330: else
0331: throw new IllegalArgumentException();
0332: }
0333:
0334: /**
0335: * ctor: create a possibly transient file with a name, linkage and hint.
0336: *
0337: * @param filename is the logical filename to store.
0338: * @param link is the linkage of the file to remember.
0339: * @param hint is an expression for a temporary filename choice.
0340: * If it is not null, the files will neither be marked for registration
0341: * nor for transfer to the output collector.
0342: * @throws IllegalArgumentException if the linkage does not match the
0343: * legal range.
0344: */
0345: public LFN(String filename, int link, String hint)
0346: throws IllegalArgumentException {
0347: super ();
0348: this .m_filename = filename;
0349: if ((this .m_temporary = hint) == null) {
0350: this .m_dontRegister = false;
0351: this .m_dontTransfer = XFER_MANDATORY;
0352: } else {
0353: this .m_dontRegister = true;
0354: this .m_dontTransfer = XFER_NOT;
0355: }
0356:
0357: if (LFN.isInRange(link))
0358: this .m_link = link;
0359: else
0360: throw new IllegalArgumentException();
0361: }
0362:
0363: /**
0364: * ctor: Creates a filename given almost all specs. This is a backward
0365: * compatible constructor, as it lacks access to the optional transfer
0366: * attribute.
0367: *
0368: * @param filename is the logical filename to store.
0369: * @param link is the linkage of the file to remember.
0370: * @param hint is an expression for a temporary filename choice.
0371: * @param dontRegister whether to to register with a replica catalog.
0372: * @param dontTransfer whether to transfer the file to the collector.
0373: * @throws IllegalArgumentException if the linkage does not match the
0374: * legal range, or the transfer mode does not match its legal range.
0375: * @since 1.21
0376: *
0377: * @deprecated
0378: */
0379: public LFN(String filename, int link, String hint,
0380: boolean dontRegister, int dontTransfer)
0381: throws IllegalArgumentException {
0382: super ();
0383: this .m_filename = filename;
0384: this .m_temporary = hint;
0385: this .m_dontRegister = dontRegister;
0386: if (LFN.transferInRange(dontTransfer))
0387: this .m_dontTransfer = dontTransfer;
0388: else
0389: throw new IllegalArgumentException("Illegal transfer mode");
0390:
0391: if (LFN.isInRange(link))
0392: this .m_link = link;
0393: else
0394: throw new IllegalArgumentException("Illegal linkage type");
0395: }
0396:
0397: /**
0398: * ctor: Creates a filename given almost all specs. This is a backward
0399: * compatible constructor, as it lacks access to the optional transfer
0400: * attribute.
0401: *
0402: * @param filename is the logical filename to store.
0403: * @param link is the linkage of the file to remember.
0404: * @param hint is an expression for a temporary filename choice.
0405: * @param dontRegister whether to to register with a replica catalog.
0406: * @param dontTransfer whether to transfer the file to the collector.
0407: * @param optional whether the file is optional or required.
0408: * @throws IllegalArgumentException if the linkage does not match the
0409: * legal range, or the transfer mode does not match its legal range.
0410: * @since 1.23
0411: *
0412: * @deprecated
0413: */
0414: public LFN(String filename, int link, String hint,
0415: boolean dontRegister, int dontTransfer, boolean optional)
0416: throws IllegalArgumentException {
0417: super ();
0418: this .m_filename = filename;
0419: this .m_temporary = hint;
0420: this .m_dontRegister = dontRegister;
0421: this .m_optional = optional;
0422: if (LFN.transferInRange(dontTransfer))
0423: this .m_dontTransfer = dontTransfer;
0424: else
0425: throw new IllegalArgumentException("Illegal transfer mode");
0426: if (LFN.isInRange(link))
0427: this .m_link = link;
0428: else
0429: throw new IllegalArgumentException("Illegal linkage type");
0430: }
0431:
0432: //The new constructors that need to be added later, after the deprecation
0433: //ends for the above constructors. Karan Oct 24, 2007
0434: /**
0435: * ctor: Creates a filename given almost all specs. This is a backward
0436: * compatible constructor, as it lacks access to the optional transfer
0437: * attribute.
0438: *
0439: * @param filename is the logical filename to store.
0440: * @param link is the linkage of the file to remember.
0441: * @param hint is an expression for a temporary filename choice.
0442: * @param register whether to to register with a replica catalog.
0443: * @param transfer whether to transfer the file to the collector.
0444: * @throws IllegalArgumentException if the linkage does not match the
0445: * legal range, or the transfer mode does not match its legal range.
0446: */
0447: // public LFN( String filename, int link, String hint,
0448: // boolean register, int transfer )
0449: // throws IllegalArgumentException
0450: // {
0451: // super();
0452: // this.m_filename = filename;
0453: // this.m_temporary = hint;
0454: // this.m_dontRegister = !register;
0455: // if ( LFN.transferInRange( transfer ) )
0456: // this.m_dontTransfer = transfer;
0457: // else
0458: // throw new IllegalArgumentException("Illegal transfer mode");
0459: //
0460: // if ( LFN.isInRange(link) )
0461: // this.m_link = link;
0462: // else
0463: // throw new IllegalArgumentException("Illegal linkage type");
0464: // }
0465: /**
0466: * ctor: Creates a filename given almost all specs. This is a backward
0467: * compatible constructor, as it lacks access to the optional transfer
0468: * attribute.
0469: *
0470: * @param filename is the logical filename to store.
0471: * @param link is the linkage of the file to remember.
0472: * @param hint is an expression for a temporary filename choice.
0473: * @param register whether to to register with a replica catalog.
0474: * @param transfer whether to transfer the file to the collector.
0475: * @param optional whether the file is optional or required.
0476: * @throws IllegalArgumentException if the linkage does not match the
0477: * legal range, or the transfer mode does not match its legal range.
0478: */
0479: // public LFN( String filename, int link, String hint,
0480: // boolean register, int transfer, boolean optional )
0481: // throws IllegalArgumentException
0482: // {
0483: // super();
0484: // this.m_filename = filename;
0485: // this.m_temporary = hint;
0486: // this.m_dontRegister = !register;
0487: // this.m_optional = optional;
0488: // if ( LFN.transferInRange( transfer ) )
0489: // this.m_dontTransfer = transfer;
0490: // else
0491: // throw new IllegalArgumentException("Illegal transfer mode");
0492: // if ( LFN.isInRange(link) )
0493: // this.m_link = link;
0494: // else
0495: // throw new IllegalArgumentException("Illegal linkage type");
0496: // }
0497:
0498: /**
0499: * ctor: Creates a filename given almost all specs. This is a backward
0500: * compatible constructor, as it lacks access to the optional transfer
0501: * attribute.
0502: *
0503: * @param filename is the logical filename to store.
0504: * @param link is the linkage of the file to remember.
0505: * @param hint is an expression for a temporary filename choice.
0506: * @param dontRegister whether to to register with a replica catalog.
0507: * @param dontTransfer whether to transfer the file to the collector.
0508: * @param optional whether the file is optional or required.
0509: * @param type whether the file is data|executable|pattern
0510: *
0511: * @throws IllegalArgumentException if the linkage does not match the
0512: * legal range, or the transfer mode does not match its legal range.
0513: * @since 1.23
0514: */
0515: public LFN(String filename, int link, String hint,
0516: boolean dontRegister, int dontTransfer, boolean optional,
0517: int type) throws IllegalArgumentException {
0518: this (filename, link, hint, dontRegister, dontTransfer, optional);
0519:
0520: if (LFN.typeInRange(type))
0521: this .m_type = type;
0522: else
0523: throw new IllegalArgumentException("Illegal File type");
0524: }
0525:
0526: // /**
0527: // * @deprecated Use the finer control of {@link #getDontRegister}
0528: // * and {@link #getDontTransfer}.
0529: // *
0530: // * @return true, if the current filename instance points to
0531: // * a transient (dontRegister, dontTransfer) file. False for all other
0532: // * cases.
0533: // */
0534: // public boolean getIsTransient()
0535: // {
0536: // return ( this.m_dontRegister && this.m_dontTransfer );
0537: // }
0538:
0539: /**
0540: * Accessor: Obtains the linkage type from the object.
0541: *
0542: * @return the linkage type of the current object. Note that
0543: * <code>LFN</code> objects <i>default</i> to no linkage.
0544: * @see #setLink(int)
0545: */
0546: public int getLink() {
0547: return this .m_link;
0548: }
0549:
0550: /**
0551: * Accessor: Obtains the logical filename of the object.
0552: *
0553: * @return the logical filename.
0554: * @see #setFilename( java.lang.String )
0555: */
0556: public String getFilename() {
0557: return this .m_filename;
0558: }
0559:
0560: /**
0561: * Accessor: Obtains the predicate on registring with a replica
0562: * catalog.
0563: *
0564: * @return true if the file will be registered with a replica catalog.
0565: *
0566: * @see #setRegister( boolean )
0567: *
0568: * @since 2.1
0569: */
0570: public boolean getRegister() {
0571: return !this .m_dontRegister;
0572: }
0573:
0574: /**
0575: * Accessor: Returns the predicate on the type of the LFN
0576: *
0577: * @return the type of LFN
0578: *
0579: *
0580: * @see #setType( int )
0581: *
0582: * @since 2.1
0583: */
0584: public int getType() {
0585: return this .m_type;
0586: }
0587:
0588: /**
0589: * Accessor: Obtains the predicate on registring with a replica
0590: * catalog.
0591: *
0592: * @return false if the file will be registered with a replica catalog.
0593: * @see #setRegister( boolean )
0594: * @see #getRegister()
0595: * @deprecated
0596: * @since 1.21
0597: */
0598: public boolean getDontRegister() {
0599: return this .m_dontRegister;
0600: }
0601:
0602: /**
0603: * Accessor: Obtains the transfering mode.
0604: *
0605: * @return true if the file will be tranferred to an output collector.
0606: *
0607: * @see #setTransfer( int )
0608: *
0609: * @since 2.1
0610: */
0611: public int getTransfer() {
0612: return this .m_dontTransfer;
0613: }
0614:
0615: /**
0616: * Accessor: Obtains the transfering mode.
0617: *
0618: * @return false if the file will be tranferred to an output collector.
0619: *
0620: * @deprecated
0621: *
0622: * @see #getTransfer()
0623: * @see #setTransfer( int )
0624: *
0625: * @since 1.21
0626: */
0627: public int getDontTransfer() {
0628: return this .m_dontTransfer;
0629: }
0630:
0631: /**
0632: * Acessor: Obtains the optionality of the file.
0633: *
0634: * @return false, if the file is required, or true, if it is optional.
0635: * @see #setOptional( boolean )
0636: * @since 1.23
0637: */
0638: public boolean getOptional() {
0639: return this .m_optional;
0640: }
0641:
0642: /**
0643: * Accessor: Obtains the file name suggestion for a transient file.
0644: * If a filename is marked transient, the higher level planners might
0645: * have some notion where to place it, or how to name it. Lower level
0646: * planners are not necessarily required to follow this hint.
0647: *
0648: * @return the transient name suggestion of the file. The current
0649: * settings will always be returned, regardless of the transiency
0650: * state of the file.
0651: * @see #setTemporary(String)
0652: */
0653: public String getTemporary() {
0654: return this .m_temporary;
0655: }
0656:
0657: // /**
0658: // * @deprecated Use the finer control of {@link #setDontRegister} and
0659: // * {@link #setDontTranfer} for transiency control.
0660: // *
0661: // * @param transient is the transience state of this filename instance.
0662: // * dontRegister and dontTransfer will both be set to the value of
0663: // * transient.
0664: // *
0665: // * @see #getIsTransient()
0666: // */
0667: // public void setIsTransient( boolean isTransient )
0668: // { this.m_dontRegister = this.m_dontTransfer = isTransient; }
0669:
0670: /**
0671: * Accessor: Sets the linkage type.
0672: *
0673: * @param link is the new linkage type to use. Please note that it
0674: * must match the range of legal values.
0675: * @throws IllegalArgumentException if the range is beyong legal values.
0676: * @see #getLink()
0677: */
0678: public void setLink(int link) throws IllegalArgumentException {
0679: if (LFN.isInRange(link))
0680: this .m_link = link;
0681: else
0682: throw new IllegalArgumentException();
0683: }
0684:
0685: /**
0686: * Accessor: Sets the filename
0687: *
0688: * @param fn is the new logical filename.
0689: * @see #getFilename()
0690: */
0691: public void setFilename(String fn) {
0692: this .m_filename = fn;
0693: }
0694:
0695: /**
0696: * Accessor: Sets the predicate on registring with a replica catalog.
0697: *
0698: * @param register is true, if the file should be registered with a
0699: * replica catalog.
0700: *
0701: *
0702: * @see #getRegister( )
0703: *
0704: * @since 2.1
0705: */
0706: public void setRegister(boolean register) {
0707: this .m_dontRegister = !register;
0708: }
0709:
0710: /**
0711: * Accessor: Sets the predicate on the type of the LFN
0712: *
0713: * @param type the type of LFN
0714: *
0715: *
0716: * @see #getType( )
0717: *
0718: * @since 2.1
0719: */
0720: public void setType(int type) {
0721: if (typeInRange(type)) {
0722: this .m_type = type;
0723: } else {
0724: throw new IllegalArgumentException("Invalid LFN type "
0725: + type);
0726: }
0727: }
0728:
0729: /**
0730: * Accessor: Sets the predicate on registring with a replica catalog.
0731: *
0732: * @param dontRegister is false, if the file should be registered with a
0733: * replica catalog.
0734: * @see #getDontRegister()
0735: * @since 1.21
0736: * @deprecated
0737: *
0738: * @see #setRegister( boolean )
0739: * @see #getRegister( boolean )
0740: */
0741: public void setDontRegister(boolean dontRegister) {
0742: this .m_dontRegister = dontRegister;
0743: }
0744:
0745: /**
0746: * Accessor: Sets the transfer mode.
0747: *
0748: * @param transfer the transfer flag
0749: *
0750: * @exception IllegalArgumentException if the transfer mode is outside
0751: * its legal range.
0752: * @see #getTransfer( )
0753: * @see LFN#XFER_MANDATORY
0754: * @see LFN#XFER_OPTIONAL
0755: * @see LFN#XFER_NOT
0756: *
0757: * @since 2.1
0758: */
0759: public void setTransfer(int transfer)
0760: throws IllegalArgumentException {
0761: if (LFN.transferInRange(transfer))
0762: this .m_dontTransfer = transfer;
0763: else
0764: throw new IllegalArgumentException();
0765: }
0766:
0767: /**
0768: * Accessor: Sets the transfer mode.
0769: *
0770: * @param dontTransfer is false, if the file should be transferred to
0771: * the output collector.
0772: * @exception IllegalArgumentException if the transfer mode is outside
0773: * its legal range.
0774: *
0775: * @deprecated
0776: *
0777: * @see #getDontTransfer( )
0778: * @see LFN#XFER_MANDATORY
0779: * @see LFN#XFER_OPTIONAL
0780: * @see LFN#XFER_NOT
0781: * @since 1.21
0782: */
0783: public void setDontTransfer(int dontTransfer)
0784: throws IllegalArgumentException {
0785: if (LFN.transferInRange(dontTransfer))
0786: this .m_dontTransfer = dontTransfer;
0787: else
0788: throw new IllegalArgumentException();
0789: }
0790:
0791: /**
0792: * Acessor: Sets the optionality of the file.
0793: *
0794: * @param optional false, if the file is required, or true, if it is
0795: * optional.
0796: * @see #getOptional()
0797: * @since 1.23
0798: */
0799: public void setOptional(boolean optional) {
0800: this .m_optional = optional;
0801: }
0802:
0803: /**
0804: * Accessor: Sets a file name suggestion for a transient file. If a
0805: * filename is marked transient, the higher level planners might have
0806: * some notion where to place it, or how to name it. Lower level
0807: * planners are not necessarily required to follow this hint.
0808: *
0809: * @param name is a transient name suggestion for this filename instance.
0810: * No automatic marking of transiency will be done!
0811: * @see #getTemporary()
0812: */
0813: public void setTemporary(String name) {
0814: this .m_temporary = name;
0815: }
0816:
0817: /**
0818: * Predicate to determine, if the output can be abbreviated. Filenames
0819: * can be abbreviated, if one of these two conditions are met: The
0820: * hint is <code>null</code> and dontRegister is false and
0821: * dontTransfer is mandatory, or the hint exists, and dontRegister
0822: * is true and dontTransfer is no transfer.
0823: *
0824: * @param temp is the temporary hint
0825: * @param dr is the value of dontRegister
0826: * @param dt is the value of dontTransfer
0827: * @param opt is whether a given file is optional or not
0828: * @return true, if the filename can use abbreviated mode
0829: *
0830: */
0831: public static boolean abbreviatable(String temp, boolean dr,
0832: int dt, boolean opt) {
0833: if (opt)
0834: return false;
0835: else
0836: return ((temp == null && !dr && dt == LFN.XFER_MANDATORY) || (temp != null
0837: && dr && dt == LFN.XFER_NOT));
0838: }
0839:
0840: /**
0841: * Convenience function to call the static test, if a filename can
0842: * use the abbreviated notation.
0843: *
0844: * @return true, if abbreviatable notation is possible.
0845: * @see #abbreviatable( String, boolean, int, boolean )
0846: */
0847: private boolean abbreviatable() {
0848: return LFN.abbreviatable(this .m_temporary, this .m_dontRegister,
0849: this .m_dontTransfer, this .m_optional);
0850: }
0851:
0852: /**
0853: * Convert the logical filename and linkage into something human readable.
0854: * The output is also slightly nudged towards machine parsability.
0855: *
0856: * @return a textual description of the element and its attributes.
0857: */
0858: public String toString() {
0859: // slight over-allocation is without harm
0860: StringBuffer result = new StringBuffer(
0861: this .m_filename.length() + 32);
0862:
0863: result.append("@{");
0864: result.append(LFN.toString(this .m_link));
0865: result.append(":\"");
0866: result.append(escape(this .m_filename));
0867: if (this .m_temporary != null) {
0868: result.append("\":\"");
0869: result.append(escape(this .m_temporary));
0870: }
0871: result.append('"');
0872:
0873: if (!abbreviatable()) {
0874: // new mode, generate appendices
0875: result.append('|');
0876: if (this .m_optional)
0877: result.append('o');
0878: if (!this .m_dontRegister)
0879: result.append('r');
0880: if (this .m_dontTransfer != LFN.XFER_NOT)
0881: result
0882: .append(this .m_dontTransfer == LFN.XFER_OPTIONAL ? 'T'
0883: : 't');
0884: }
0885: result.append('}');
0886: return result.toString();
0887: }
0888:
0889: /**
0890: * Prints the current content onto the stream.
0891: *
0892: * @param stream is a stream opened and ready for writing. This can also
0893: * be a string stream for efficient output.
0894: * @throws IOException if something happens to the stream.
0895: */
0896: public void toString(Writer stream) throws IOException {
0897: stream.write("@{");
0898: stream.write(LFN.toString(this .m_link));
0899: stream.write(":\"");
0900: stream.write(escape(this .m_filename)); // risk NullPointerException
0901: if (this .m_temporary != null) {
0902: stream.write("\":\"");
0903: stream.write(escape(this .m_temporary));
0904: }
0905: stream.write('"');
0906:
0907: if (!abbreviatable()) {
0908: // new mode, generate appendices
0909: stream.write('|');
0910: if (this .m_optional)
0911: stream.write('o');
0912: if (!this .m_dontRegister)
0913: stream.write('r');
0914: if (this .m_dontTransfer != LFN.XFER_NOT)
0915: stream
0916: .write(this .m_dontTransfer == LFN.XFER_OPTIONAL ? 'T'
0917: : 't');
0918: }
0919:
0920: stream.write("}");
0921: }
0922:
0923: /**
0924: * Dumps the state of the current element as XML output. This method
0925: * converts the data into pretty-printed XML output meant for machine
0926: * consumption.
0927: *
0928: * @param indent is a <code>String</code> of spaces used for pretty
0929: * printing. The initial amount of spaces should be an empty string.
0930: *
0931: * @return a String which contains the state of the current class
0932: * and its siblings using XML. Note that these strings might become large.
0933: */
0934: public String toXML(String indent) {
0935: // slight over-allocation is without harm
0936: StringBuffer result = new StringBuffer(128);
0937:
0938: if (indent != null)
0939: result.append(indent);
0940: result.append("<lfn file=\"").append(
0941: quote(this .m_filename, true));
0942: result.append("\" link=\"").append(LFN.toString(this .m_link));
0943: result.append("\" register=\"").append(
0944: Boolean.toString(!this .m_dontRegister));
0945: result.append("\" transfer=\"").append(
0946: LFN.transferString(this .m_dontTransfer));
0947: result.append("\" optional=\"").append(
0948: Boolean.toString(this .m_optional));
0949:
0950: result.append("\" type=\"").append(LFN.typeString(this .m_type));
0951: if (this .m_temporary != null) {
0952: result.append("\" temporaryHint=\"");
0953: result.append(quote(this .m_temporary, true));
0954: }
0955: result.append("\"/>");
0956: if (indent != null)
0957: result.append(System.getProperty("line.separator", "\r\n"));
0958:
0959: return result.toString();
0960: }
0961:
0962: /**
0963: * Dump the state of the current element as XML output. This function
0964: * traverses all sibling classes as necessary, and converts the data
0965: * into pretty-printed XML output. The stream interface should be able
0966: * to handle large output efficiently, if you use a buffered writer.
0967: *
0968: * @param stream is a stream opened and ready for writing. This can also
0969: * be a string stream for efficient output.
0970: * @param indent is a <code>String</code> of spaces used for pretty
0971: * printing. The initial amount of spaces should be an empty string.
0972: * The parameter is used internally for the recursive traversal.
0973: * @param namespace is the XML schema namespace prefix. If neither
0974: * empty nor null, each element will be prefixed with this prefix,
0975: * and the root element will map the XML namespace.
0976: * @exception IOException if something fishy happens to the stream.
0977: */
0978: public void toXML(Writer stream, String indent, String namespace)
0979: throws IOException {
0980: if (indent != null && indent.length() > 0)
0981: stream.write(indent);
0982: stream.write('<');
0983: if (namespace != null && namespace.length() > 0) {
0984: stream.write(namespace);
0985: stream.write(':');
0986: }
0987: stream.write("lfn");
0988: writeAttribute(stream, " file=\"", this .m_filename);
0989: writeAttribute(stream, " link=\"", LFN.toString(this .m_link));
0990: writeAttribute(stream, " register=\"", Boolean
0991: .toString(!this .m_dontRegister));
0992: writeAttribute(stream, " transfer=\"", LFN
0993: .transferString(this .m_dontTransfer));
0994: writeAttribute(stream, " optional=\"", Boolean
0995: .toString(this .m_optional));
0996: writeAttribute(stream, " type=\"", LFN.typeString(this .m_type));
0997:
0998: // null-safe
0999: writeAttribute(stream, " temporaryHint=\"", this .m_temporary);
1000: stream.write("/>");
1001: if (indent != null)
1002: stream.write(System.getProperty("line.separator", "\r\n"));
1003: }
1004: }
|