1
/*___INFO__MARK_BEGIN__*/
2
/*************************************************************************
4
* The Contents of this file are made available subject to the terms of
5
* the Sun Industry Standards Source License Version 1.2
7
* Sun Microsystems Inc., March, 2001
10
* Sun Industry Standards Source License Version 1.2
11
* =================================================
12
* The contents of this file are subject to the Sun Industry Standards
13
* Source License Version 1.2 (the "License"); You may not use this file
14
* except in compliance with the License. You may obtain a copy of the
15
* License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
17
* Software provided under this License is provided on an "AS IS" basis,
18
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
19
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
20
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
21
* See the License for the specific provisions governing your rights and
22
* obligations concerning the Software.
24
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
* Copyright: 2001 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
32
package org.ggf.drmaa;
34
import java.io.Serializable;
35
import java.util.ArrayList;
36
import java.util.Arrays;
37
import java.util.Collections;
38
import java.util.HashMap;
39
import java.util.HashSet;
40
import java.util.Iterator;
41
import java.util.List;
43
import java.util.Properties;
47
* This class is a trivial implementation of the JobTemplate interface. This
48
* class can either be used as the base class for a implementation-specific
49
* job template class, or for implementations which do not need more than the
50
* required properties, it can be used as the job template implementation
53
* <p>All non-primitive properties default to <code>null</code>. All boolean
54
* properties default to <code>false</code>. All other primitive properties
55
* default to zero.</p>
57
* <p>The SimpleJobTemplate class is not thread safe. No attempt is made to
58
* prevent setters and getters from interfering with each other or the
59
* toString() method.</p>
61
* @author dan.templeton@sun.com
65
public class SimpleJobTemplate implements JobTemplate, Serializable {
66
private String toString = null;
67
private Set allPropertyNames = null;
68
private boolean modified = true;
70
* Remote command to execute
71
* @see JobTemplate#setRemoteCommand(String)
73
protected String remoteCommand = null;
75
* Input parameters passed as arguments to the job
76
* @see JobTemplate#setArgs(List)
78
protected List args = null;
80
* Job state at submission, either HOLD or ACTIVE
81
* @see JobTemplate#setJobSubmissionState(int)
83
protected int jobSubmissionState = ACTIVE_STATE;
85
* The environment values that define the job's remote environment
86
* @see JobTemplate#setJobEnvironment(Map)
88
protected Map jobEnvironment = null;
90
* The directory where the job is executed.
91
* @see JobTemplate#setWorkingDirectory(String)
93
protected String workingDirectory = null;
95
* An implementation-defined string specifying how to resolve site-specific
96
* resources and/or policies
97
* @see JobTemplate#setJobCategory(String)
99
protected String jobCategory = null;
101
* An implementation-defined string that is passed by the end user to DRMAA
102
* to specify site-specific resources and/or policies
103
* @see JobTemplate#setNativeSpecification(String)
105
protected String nativeSpecification = null;
107
* E-mail addresses used to report the job completion and status
108
* @see JobTemplate#setEmail(Set)
110
protected Set email = null;
112
* Blocks sending e-mail by default, regardless of the DRMS setting
113
* @see JobTemplate#setBlockEmail(boolean)
115
protected boolean blockEmail = false;
117
* The earliest time when the job may be eligible to be run
118
* @see JobTemplate#setStartTime(PartialTimestamp)
120
protected PartialTimestamp startTime = null;
123
* @see JobTemplate#setJobName(String)
125
protected String jobName = null;
127
* The job's standard input stream
128
* @see JobTemplate#setInputPath(String)
130
protected String inputPath = null;
132
* The job's standard output stream
133
* @see JobTemplate#setOutputPath(String)
135
protected String outputPath = null;
137
* The job's standard error stream
138
* @see JobTemplate#setErrorPath(String)
140
protected String errorPath = null;
142
* Whether the error stream should be intermixed with the output stream
143
* @see JobTemplate#setJoinFiles(boolean)
145
protected boolean joinFiles = false;
148
* Create a new instance of a JobTemplate.
150
public SimpleJobTemplate() {
153
public void setRemoteCommand(String remoteCommand) throws DrmaaException {
154
this.remoteCommand = remoteCommand;
158
public String getRemoteCommand() throws DrmaaException {
159
return remoteCommand;
162
public void setArgs(List args) throws DrmaaException {
164
this.args = new ArrayList(args);
172
public List getArgs() throws DrmaaException {
173
List returnValue = null;
176
returnValue = Collections.unmodifiableList(args);
182
public void setJobSubmissionState(int state) throws DrmaaException {
183
if ((state != ACTIVE_STATE) && (state != HOLD_STATE)) {
184
throw new IllegalArgumentException("Invalid state");
187
this.jobSubmissionState = state;
191
public int getJobSubmissionState() throws DrmaaException {
192
return jobSubmissionState;
195
public void setJobEnvironment(Map env) throws DrmaaException {
197
this.jobEnvironment = new HashMap(env);
199
this.jobEnvironment = null;
205
public Map getJobEnvironment() throws DrmaaException {
206
Map returnValue = null;
208
if (jobEnvironment != null) {
209
returnValue = Collections.unmodifiableMap(jobEnvironment);
215
public void setWorkingDirectory(String wd) throws DrmaaException {
216
if (wd.indexOf(HOME_DIRECTORY) > 0) {
217
throw new InvalidAttributeFormatException(HOME_DIRECTORY +
218
" may only appear at the beginning of the path.");
219
} else if (wd.indexOf(WORKING_DIRECTORY) >= 0) {
220
throw new InvalidAttributeFormatException(WORKING_DIRECTORY +
221
" may not be used in the workingDirectory path.");
224
this.workingDirectory = wd;
228
public String getWorkingDirectory() throws DrmaaException {
229
return workingDirectory;
232
public void setJobCategory(String category) throws DrmaaException {
233
this.jobCategory = category;
237
public String getJobCategory() throws DrmaaException {
241
public void setNativeSpecification(String spec) throws DrmaaException {
242
this.nativeSpecification = spec;
246
public String getNativeSpecification() throws DrmaaException {
247
return nativeSpecification;
250
public void setEmail(Set email) throws DrmaaException {
252
this.email = new HashSet(email);
260
public Set getEmail() throws DrmaaException {
261
Set returnValue = null;
264
returnValue = Collections.unmodifiableSet(email);
270
public void setBlockEmail(boolean blockEmail) throws DrmaaException {
271
this.blockEmail = blockEmail;
275
public boolean getBlockEmail() throws DrmaaException {
279
public void setStartTime(PartialTimestamp startTime) throws DrmaaException {
280
if (startTime != null) {
281
if (startTime.getTimeInMillis() < System.currentTimeMillis()) {
282
throw new IllegalArgumentException("Start time is in the past.");
285
this.startTime = startTime;
293
public PartialTimestamp getStartTime() throws DrmaaException {
294
if (startTime != null) {
295
return (PartialTimestamp)startTime.clone();
301
public void setJobName(String name) throws DrmaaException {
306
public String getJobName() throws DrmaaException {
310
public void setInputPath(String inputPath) throws DrmaaException {
311
this.checkPath(inputPath);
312
this.inputPath = inputPath;
316
public String getInputPath() throws DrmaaException {
320
public void setOutputPath(String outputPath) throws DrmaaException {
321
this.checkPath(outputPath);
322
this.outputPath = outputPath;
326
public String getOutputPath() throws DrmaaException {
330
public void setErrorPath(String errorPath) throws DrmaaException {
331
this.checkPath(errorPath);
332
this.errorPath = errorPath;
336
public String getErrorPath() throws DrmaaException {
340
public void setJoinFiles(boolean join) throws DrmaaException {
341
this.joinFiles = join;
345
public boolean getJoinFiles() throws DrmaaException {
349
public void setTransferFiles(FileTransferMode mode) throws DrmaaException {
350
throw new UnsupportedAttributeException("The transferFiles attribute " +
351
"is not supported.");
354
public FileTransferMode getTransferFiles() throws DrmaaException {
355
throw new UnsupportedAttributeException("The transferFiles attribute " +
356
"is not supported.");
359
public void setDeadlineTime(PartialTimestamp deadline)
360
throws DrmaaException {
361
throw new UnsupportedAttributeException("The deadlineTime attribute " +
362
"is not supported.");
365
public PartialTimestamp getDeadlineTime() throws DrmaaException {
366
throw new UnsupportedAttributeException("The deadlineTime attribute " +
367
"is not supported.");
370
public void setHardWallclockTimeLimit(long hardWallclockLimit)
371
throws DrmaaException {
372
throw new UnsupportedAttributeException("The hardWallclockTimeLimit " +
373
"attribute is not supported.");
376
public long getHardWallclockTimeLimit() throws DrmaaException {
377
throw new UnsupportedAttributeException("The hardWallclockTimeLimit " +
378
"attribute is not supported.");
381
public void setSoftWallclockTimeLimit(long softWallclockLimit)
382
throws DrmaaException {
383
throw new UnsupportedAttributeException("The softWallclockTimeLimit " +
384
"attribute is not supported.");
387
public long getSoftWallclockTimeLimit() throws DrmaaException {
388
throw new UnsupportedAttributeException("The softWallclockTimeLimit " +
389
"attribute is not supported.");
392
public void setHardRunDurationLimit(long hardRunLimit)
393
throws DrmaaException {
394
throw new UnsupportedAttributeException("The hardRunDurationLimit " +
395
"attribute is not supported.");
398
public long getHardRunDurationLimit() throws DrmaaException {
399
throw new UnsupportedAttributeException("The hardRunDurationLimit " +
400
"attribute is not supported.");
403
public void setSoftRunDurationLimit(long softRunLimit)
404
throws DrmaaException {
405
throw new UnsupportedAttributeException("The softRunDurationLimit " +
406
"attribute is not supported.");
409
public long getSoftRunDurationLimit() throws DrmaaException {
410
throw new UnsupportedAttributeException("The softRunDurationLimit " +
411
"attribute is not supported.");
414
public Set getAttributeNames() throws DrmaaException {
415
if (allPropertyNames == null) {
416
allPropertyNames = new HashSet();
417
addRequiredNames(allPropertyNames);
418
allPropertyNames.addAll(getOptionalAttributeNames());
421
return allPropertyNames;
424
/** This method returns the names of all optional and implementation-specific
425
* properties supported by this DRMAA implementation. Unless overridden by the
426
* DRMAA implementation, this method returns an empty list.
427
* This method is used by the getAttributeNames() method to construct the full list
428
* of implementation-supported property names.
429
* @return The names of all optional and implementation-specific
430
* properties supported by this DRMAA implementation
431
* @see #getAttributeNames
433
protected Set getOptionalAttributeNames() {
434
return Collections.EMPTY_SET;
437
private static final void addRequiredNames(Set names) {
439
names.add("blockEmail");
441
names.add("errorPath");
442
names.add("inputPath");
443
names.add("jobCategory");
444
names.add("jobEnvironment");
445
names.add("jobName");
446
names.add("jobSubmissionState");
447
names.add("joinFiles");
448
names.add("nativeSpecification");
449
names.add("outputPath");
450
names.add("remoteCommand");
451
names.add("startTime");
452
names.add("workingDirectory");
456
* Checks for a valid path. Throws an InvalidArgumentException is the path
458
* @param path The path to validate
460
private void checkPath(String path) throws IllegalArgumentException {
461
/* On a null path, we just return because null paths are OK. */
466
if (path.indexOf(HOME_DIRECTORY) > 0) {
467
throw new IllegalArgumentException(HOME_DIRECTORY +
468
" may only appear at the beginning of the path.");
471
if (path.indexOf(WORKING_DIRECTORY) > 0) {
472
throw new IllegalArgumentException(WORKING_DIRECTORY +
473
" may only appear at the beginning of the path.");
478
* Calling this method indicates that the job template's properties have
479
* been* modified since the last call to toString(). All setters should
480
* call this method before returning.
482
protected void modified() {
487
* Converts this JobTemplate into a String which contains all property
488
* settings. The generated string is then cached and reused until one of
489
* the property settings is modified.
490
* @return a string containing all property settings
492
public String toString() {
494
boolean error = false;
495
boolean firstProperty = true;
496
StringBuffer out = new StringBuffer();
502
} catch (DrmaaException e) {
503
out.append("{args = <ERROR>}");
504
firstProperty = false;
508
if ((args != null) && (args.size() > 0)) {
509
Iterator i = args.iterator();
510
boolean firstArg = true;
512
out.append("{args = ");
514
while (i.hasNext()) {
522
out.append(i.next());
527
firstProperty = false;
530
if (!firstProperty) {
534
out.append("{blockEmail = ");
537
out.append(Boolean.toString(getBlockEmail()));
538
} catch (DrmaaException e) {
539
out.append("<ERROR>");
545
if (getDeadlineTime() != null) {
546
PartialTimestampFormat ptf = new PartialTimestampFormat();
548
out.append(" {deadlineTime = ");
549
out.append(ptf.format(getDeadlineTime()));
552
} catch (UnsupportedAttributeException e) {
554
} catch (DrmaaException e) {
555
out.append(" {deadlineTime = <ERROR>}");
563
} catch (DrmaaException e) {
564
out.append(" {email = <ERROR>}");
568
if ((email != null) && (email.size() > 0)) {
569
Iterator i = email.iterator();
570
boolean firstEmail = true;
572
out.append(" {email = ");
574
while (i.hasNext()) {
582
out.append(i.next());
590
if (getErrorPath() != null) {
591
out.append(" {errorPath = ");
592
out.append(getErrorPath());
595
} catch (DrmaaException e) {
596
out.append(" {errorPath = <ERROR>}");
601
if (getHardRunDurationLimit() != 0L) {
602
out.append(" {hardRunDurationLimit = ");
603
out.append(getHardRunDurationLimit());
606
} catch (UnsupportedAttributeException e) {
608
} catch (DrmaaException e) {
609
out.append(" {hardRunDurationLimit = <ERROR>}");
614
if (getHardWallclockTimeLimit() != 0L) {
615
out.append(" {hardWallclockTimeLimit = ");
616
out.append(getHardWallclockTimeLimit());
619
} catch (UnsupportedAttributeException e) {
621
} catch (DrmaaException e) {
622
out.append(" {hardWallclockTimeLimit = <ERROR>}");
627
if (getInputPath() != null) {
628
out.append(" {inputPath = ");
629
out.append(getInputPath());
632
} catch (DrmaaException e) {
633
out.append(" {inputPath = <ERROR>}");
638
if (getJobCategory() != null) {
639
out.append(" {jobCategory = ");
640
out.append(getJobCategory());
643
} catch (DrmaaException e) {
644
out.append(" {jobCategory = <ERROR>}");
651
env = getJobEnvironment();
652
} catch (DrmaaException e) {
653
out.append(" {jobEnvironment = <ERROR>}");
657
if ((env != null) && (env.size() > 0)) {
658
Iterator i = env.keySet().iterator();
659
boolean firstEnv = true;
661
out.append(" {jobEnvironment = ");
663
while (i.hasNext()) {
664
String entry = (String)i.next();
673
out.append("\" = \"");
674
out.append(env.get(entry));
682
if (getJobName() != null) {
683
out.append(" {jobName = ");
684
out.append(getJobName());
687
} catch (DrmaaException e) {
688
out.append(" {jobName = <ERROR>}");
692
out.append(" {jobSubmissionState = ");
695
if (getJobSubmissionState() == HOLD_STATE) {
696
out.append("HOLD_STATE}");
698
out.append("ACTIVE_STATE}");
700
} catch (DrmaaException e) {
701
out.append(" {jobSubmissionState = <ERROR>}");
705
out.append(" {joinFiles = ");
708
out.append(Boolean.toString(getJoinFiles()));
709
} catch (DrmaaException e) {
710
out.append(" {joinFiles = <ERROR>}");
717
if (getNativeSpecification() != null) {
718
out.append(" {nativeSpecification = \"");
719
out.append(getNativeSpecification());
722
} catch (DrmaaException e) {
723
out.append(" {nativeSpecification = <ERROR>}");
728
if (getOutputPath() != null) {
729
out.append(" {outputPath = ");
730
out.append(getOutputPath());
733
} catch (DrmaaException e) {
734
out.append(" {outputPath = <ERROR>}");
739
if (getRemoteCommand() != null) {
740
out.append(" {remoteCommand = ");
741
out.append(getRemoteCommand());
744
} catch (DrmaaException e) {
745
out.append(" {remoteCommand = <ERROR>}");
750
if (getSoftRunDurationLimit() != 0L) {
751
out.append(" {softRunDurationLimit = ");
752
out.append(getSoftRunDurationLimit());
755
} catch (UnsupportedAttributeException e) {
757
} catch (DrmaaException e) {
758
out.append(" {softRunDurationLimit = <ERROR>}");
763
if (getSoftWallclockTimeLimit() != 0L) {
764
out.append(" {softWallclockTimeLimit = ");
765
out.append(getSoftWallclockTimeLimit());
768
} catch (UnsupportedAttributeException e) {
770
} catch (DrmaaException e) {
771
out.append(" {softWallclockTimeLimit = <ERROR>}");
776
if (getStartTime() != null) {
777
PartialTimestampFormat ptf = new PartialTimestampFormat();
779
out.append(" {startTime = \"");
780
out.append(ptf.format(getStartTime()));
783
} catch (DrmaaException e) {
784
out.append(" {startTime = <ERROR>}");
789
if (getTransferFiles() != null) {
790
out.append(" {transferFiles = \"");
791
out.append(getTransferFiles().toString());
794
} catch (UnsupportedAttributeException e) {
796
} catch (DrmaaException e) {
797
out.append(" {transferFiles = <ERROR>}");
802
if (getWorkingDirectory() != null) {
803
out.append(" {workingDirectory = ");
804
out.append(getWorkingDirectory());
807
} catch (DrmaaException e) {
808
out.append(" {workingDirectory = <ERROR>}");
812
toString = out.toString();
814
/* If there was an error while getting a property value, we can't
815
* unset the modified flag. Because the errored property getter
816
* might work during a later attempt, we have to leave the modified
817
* flag as true so that we try again on the next call to