001: /*
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */
015: package org.griphyn.cPlanner.classes;
016:
017: import org.griphyn.cPlanner.common.PegRandom;
018:
019: import java.io.File;
020: import java.util.ArrayList;
021: import java.util.BitSet;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026:
027: /**
028: * This is a container for the storing the transfers that are required in
029: * between sites. It refers to one lfn, but can contains more than one source
030: * and destination urls. All the source url's are presumed to be identical.
031: * The destination urls, can in effect be used to refer to TFN's for a lfn on
032: * different pools.
033: *
034: * @author Karan Vahi
035: * @author Gaurang Mehta
036: * @version $Revision: 372 $
037: *
038: */
039: public class FileTransfer extends PegasusFile {
040:
041: /**
042: * The logical name of the asssociated VDS super node, with which the file
043: * is associated. The name of the job can be of the job that generates that
044: * file(while doing interpool or transferring output files to output pool)
045: * or of a job for which the file is an input(getting an input file from the
046: * Replica Services).
047: */
048: private String mJob;
049:
050: /**
051: * The map containing all the source urls keyed by the pool id/name.
052: * Corresponding to each pool, a list of url's is stored that contain
053: * the URL's for that pool. All url's not associated with a pool, are
054: * associated with a undefined pool.
055: */
056: private Map mSourceMap;
057:
058: /**
059: * The map containing all the destination urls keyed by the pool id/name.
060: * Corresponding to each pool, a list of url's is stored that contain
061: * the URL's for that pool. All url's not associated with a pool, are
062: * associated with a undefined pool.
063: */
064: private Map mDestMap;
065:
066: /**
067: * Default constructor.
068: */
069: public FileTransfer() {
070: super ();
071: mJob = new String();
072: mFlags = new BitSet(NO_OF_TRANSIENT_FLAGS);
073: mSourceMap = new HashMap();
074: mDestMap = new HashMap();
075: }
076:
077: /**
078: * The overloaded constructor.
079: *
080: * @param pf <code>PegasusFile</code> object containing the transiency
081: * attributes, and the logical name of the file.
082: */
083: public FileTransfer(PegasusFile pf) {
084: this .mLogicalFile = pf.mLogicalFile;
085: this .mTransferFlag = pf.mTransferFlag;
086: this .mFlags = pf.getFlags();
087: this .mType = pf.getType();
088: this .mJob = new String();
089: this .mSourceMap = new HashMap();
090: this .mDestMap = new HashMap();
091:
092: }
093:
094: /**
095: * The overloaded constructor.
096: *
097: * @param lfn The logical name of the file that has to be transferred.
098: * @param job The name of the job with which the transfer is
099: * associated with.
100: */
101: public FileTransfer(String lfn, String job) {
102: super (lfn);
103: mJob = job;
104: mSourceMap = new HashMap();
105: mDestMap = new HashMap();
106: mFlags = new BitSet(NO_OF_TRANSIENT_FLAGS);
107: }
108:
109: /**
110: * The overloaded constructor.
111: *
112: * @param lfn The logical name of the file that has to be transferred.
113: * @param job The name of the job with which the transfer is
114: * associated with.
115: * @param flags the BitSet flags.
116: */
117: public FileTransfer(String lfn, String job, BitSet flags) {
118:
119: mLogicalFile = lfn;
120: mJob = job;
121: mSourceMap = new HashMap();
122: mDestMap = new HashMap();
123: mFlags = (BitSet) flags.clone();
124: }
125:
126: /**
127: * It returns the name of the main/compute job making up the VDS supernode
128: * with which this transfer is related.
129: *
130: * @return the name of associated job
131: */
132: public String getJobName() {
133: return this .mJob;
134: }
135:
136: /**
137: * Adds a source URL for the transfer.
138: *
139: * @param nv the NameValue object containing the name of the site as the key
140: * and URL as the value.
141: */
142: public void addSource(NameValue nv) {
143: this .addSource(nv.getKey(), nv.getValue());
144: }
145:
146: /**
147: * Adds a source URL for the transfer.
148: *
149: * @param pool the pool from which the source file is being transferred.
150: * @param url the source url.
151: */
152: public void addSource(String pool, String url) {
153: List l = null;
154: if (mSourceMap.containsKey(pool)) {
155: //add the url to the existing list
156: l = (List) mSourceMap.get(pool);
157: //add the entry to the list
158: l.add(url);
159: } else {
160: //add a new list
161: l = new ArrayList(3);
162: l.add(url);
163: mSourceMap.put(pool, l);
164: }
165: }
166:
167: /**
168: * Adds a destination URL for the transfer.
169: *
170: * @param nv the NameValue object containing the name of the site as the key
171: * and URL as the value.
172: */
173: public void addDestination(NameValue nv) {
174: this .addDestination(nv.getKey(), nv.getValue());
175: }
176:
177: /**
178: * Adds a destination URL for the transfer.
179: *
180: * @param pool the pool to which the destination file is being transferred.
181: * @param url the destination url.
182: */
183: public void addDestination(String pool, String url) {
184: List l = null;
185: if (mDestMap.containsKey(pool)) {
186: //add the url to the existing list
187: l = (List) mDestMap.get(pool);
188: //add the entry to the list
189: l.add(url);
190: } else {
191: //add a new list
192: l = new ArrayList(3);
193: l.add(url);
194: mDestMap.put(pool, l);
195: }
196:
197: }
198:
199: /**
200: * Returns a single source url associated with the transfer.
201: * The source url returned is first entry from the key set of the
202: * underlying map.
203: *
204: * @return NameValue where the name would be the pool on which the URL is
205: * and value the URL.
206: * null if no urls are assoiciated with the object.
207: */
208: public NameValue getSourceURL() {
209: return getSourceURL(false);
210: }
211:
212: /**
213: * Returns a single source url associated with the transfer.
214: * If random is set to false, thensource url returned is first entry from
215: * the key set of the underlying map.
216: *
217: * @param random boolean indicating if a random entry needs to be picked.
218: *
219: * @return NameValue where the name would be the pool on which the URL is
220: * and value the URL.
221: * null if no urls are assoiciated with the object.
222: */
223: public NameValue getSourceURL(boolean random) {
224: return getURL(mSourceMap, random);
225: }
226:
227: /**
228: * Returns a single destination url associated with the transfer.
229: * The destination url returned is first entry from the key set of the
230: * underlying map.
231: *
232: * @return NameValue where the name would be the pool on which the URL is
233: * and value the URL.
234: * null if no urls are assoiciated with the object.
235: */
236: public NameValue getDestURL() {
237: return getDestURL(false);
238: }
239:
240: /**
241: * Returns a single destination url associated with the transfer.
242: * If random is set to false, then dest url returned is first entry from
243: * the key set of the underlying map.
244: *
245: * @param random boolean indicating if a random entry needs to be picked.
246:
247: *
248: * @return NameValue where the name would be the pool on which the URL is
249: * and value the URL.
250: * null if no urls are assoiciated with the object.
251: */
252: public NameValue getDestURL(boolean random) {
253: return getURL(mDestMap, random);
254: }
255:
256: /**
257: * Removes a single source url associated with the transfer.
258: * The source url removed is first entry from the key set of the
259: * underlying map.
260: *
261: * @return NameValue where the name would be the pool on which the URL is
262: * and value the URL.
263: * null if no urls are assoiciated with the object.
264: */
265: public NameValue removeSourceURL() {
266: return removeURL(mSourceMap);
267: }
268:
269: /**
270: * Removes a single destination url associated with the transfer.
271: * The destination url removed is first entry from the key set of the
272: * underlying map.
273: *
274: * @return NameValue where the name would be the pool on which the URL is
275: * and value the URL.
276: * null if no urls are assoiciated with the object.
277: */
278: public NameValue removeDestURL() {
279: return removeURL(mDestMap);
280: }
281:
282: /**
283: * Returns a boolean indicating if a file that is being staged is an
284: * executable or not (i.e is a data file).
285: *
286: * @return boolean indicating whether a file is executable or not.
287: */
288: public boolean isTransferringExecutableFile() {
289: return (this .mType == this .EXECUTABLE_FILE);
290: }
291:
292: /**
293: * Returns a single url from the map passed. If the random parameter is set,
294: * then a random url is returned from the values for the first site.
295: *
296: * Fix Me: Random set to true, shud also lead to randomness on the sites.
297: *
298: * @param m the map containing the url's
299: * @param random boolean indicating that a random url to be picked up.
300: *
301: * @return NameValue where the name would be the pool on which the URL is
302: * and value the URL.
303: * null if no urls are assoiciated with the object.
304: */
305: private NameValue getURL(Map m, boolean random) {
306: if (m == null || m.keySet().isEmpty()) {
307: return null;
308: }
309:
310: //Return the first url from the EntrySet
311: Iterator it = m.entrySet().iterator();
312: Map.Entry entry = (Map.Entry) it.next();
313: List urls = (List) entry.getValue();
314: String site = (String) entry.getKey();
315:
316: return (random) ?
317: //pick a random value
318: new NameValue(site, (String) urls.get(PegRandom.getInteger(0,
319: urls.size() - 1)))
320: :
321: //returning the first element. No need for a check as
322: //population of the list is controlled
323: new NameValue(site, (String) (urls.get(0)));
324:
325: }
326:
327: /**
328: * Removes a single url from the map passed.
329: *
330: * @param m the map containing the url's
331: *
332: * @return NameValue where the name would be the pool on which the URL is
333: * and value the URL.
334: * null if no urls are assoiciated with the object.
335: */
336: private NameValue removeURL(Map m) {
337: if (m == null || m.keySet().isEmpty()) {
338: return null;
339: }
340:
341: //Return the first url from the EntrySet
342: Iterator it = m.entrySet().iterator();
343: Map.Entry entry = (Map.Entry) it.next();
344: //remove this entry
345: it.remove();
346: //returning the first element. No need for a check as
347: //population of the list is controlled
348: return new NameValue((String) entry.getKey(),
349: (String) (((List) entry.getValue()).get(0)));
350:
351: }
352:
353: /**
354: * Constructs a URL with the prefix as the poolname enclosed in #.
355: *
356: * @param site the site
357: * @param directory the directory
358: * @param filename the filename
359: *
360: * @return String
361: */
362: private String constructURL(String site, String directory,
363: String filename) {
364: StringBuffer sb = new StringBuffer();
365: sb/*.append("#").append(pool).append("#\n")*/
366: .append(directory).append(File.separatorChar).append(filename);
367:
368: return sb.toString();
369: }
370:
371: /**
372: * Returns a boolean value of whether the source url and the destination
373: * url members of this object match or not.
374: */
375: /*public boolean URLsMatch(){
376: if(mSourceURL.trim().equalsIgnoreCase(mDestURL.trim())){
377: return true;
378: }
379: return false;
380: }*/
381:
382: /**
383: * Returns a clone of the object.
384: *
385: * @return clone of the object.
386: */
387: public Object clone() {
388: FileTransfer ft = new FileTransfer();
389: ft.mLogicalFile = new String(this .mLogicalFile);
390: ft.mFlags = (BitSet) this .mFlags.clone();
391: ft.mTransferFlag = this .mTransferFlag;
392: ft.mJob = new String(this .mJob);
393:
394: //the maps are not cloned underneath
395:
396: return ft;
397: }
398:
399: /**
400: * Determines whether the transfer contained in this container is valid or
401: * not. It is deemed valid if there is at least one source url and one
402: * destination url.
403: *
404: * @return true if valid, else false.
405: */
406: public boolean isValid() {
407: return !(mSourceMap.isEmpty() || mDestMap.isEmpty());
408: }
409:
410: /**
411: * Returns a textual interpretation of the object. The method outputs
412: * in a T2 compatible format. Each FileTransfer object can refer to one
413: * section in the T2 format.
414: *
415: * @return the textual description.
416: */
417: public String toString() {
418: StringBuffer sb = new StringBuffer();
419: String mode = (mTransferFlag == this .TRANSFER_OPTIONAL) ? "optional"
420: : "any";
421:
422: Iterator it = null;
423: Map.Entry entry = null;
424: List l = null;
425:
426: sb.append(mLogicalFile).append(" ").append(mode);
427:
428: //writing out all the sources
429: it = mSourceMap.entrySet().iterator();
430: //sb.append("\n").append(" ");
431: while (it.hasNext()) {
432: entry = (Map.Entry) it.next();
433: //inserting the source pool
434: sb.append("\n").append("#").append(entry.getKey());
435: l = (List) entry.getValue();
436: Iterator it1 = l.iterator();
437: while (it1.hasNext()) {
438: //write out the source url's
439: //each line starts with a single whitespace
440: sb.append("\n").append(" ").append(it1.next());
441: }
442: }
443:
444: //writing out all the destinations
445: it = mDestMap.entrySet().iterator();
446: //sb.append("\n").append(" ");
447: while (it.hasNext()) {
448: entry = (Map.Entry) it.next();
449: //inserting the destination pool
450: sb.append("\n").append("# ").append(entry.getKey());
451: l = (List) entry.getValue();
452: Iterator it1 = l.iterator();
453: while (it1.hasNext()) {
454: //write out the source url's
455: //each line starts with a two whitespaces
456: sb.append("\n").append(" ").append(" ").append(
457: it1.next());
458: }
459: }
460:
461: return sb.toString();
462: }
463:
464: }
|