/*
*
* Copyright 2007-2008 University Of Southern California
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.griphyn.vdl.dax;
import org.griphyn.vdl.classes.LFN;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
/**
* This class defines the DAX job in an abstract manner.
*
* @author Karan Vahi
*/
public class DAXJob extends Job implements Cloneable{
/**
* The DAX LFN.
*/
private Filename mDAXLFN;
/**
* The DAX PFN. They are separate till the Filename object encompasses
* a PFN object.
*/
private String mPFN;
/**
* The site with which PFN is associated.
*/
private String mSite;
/**
* Overloaded constructor.
*
* @param id the id to be assigned to a job.
* @param daxLFN the lfn to be assigned to the DAX
*/
public DAXJob( String id, String daxLFN ){
this.setID( id );
this.mDAXLFN = new Filename( daxLFN, LFN.INPUT );
this.mDAXLFN.setRegister( false );
this.mDAXLFN.setTransfer( LFN.XFER_MANDATORY );
}
/**
* Sets the PFN for the DAX.
*
* @param pfn
* @param site
*/
public void setDAXPFN( String pfn, String site ){
this.mPFN = pfn;
this.mSite = site;
}
/**
* Dump the state of the current element as XML output. This function
* traverses all sibling classes as necessary, and converts the data
* into pretty-printed XML output. The stream interface should be able
* to handle large output efficiently.
*
* @param stream is a stream opened and ready for writing. This can also
* be a string stream for efficient output.
* @param indent is a <code>String</code> of spaces used for pretty
* printing. The initial amount of spaces should be an empty string.
* The parameter is used internally for the recursive traversal.
* @param namespace is the XML schema namespace prefix. If neither
* empty nor null, each element will be prefixed with this prefix,
* and the root element will map the XML namespace.
*/
public void toXML( Writer stream, String indent, String namespace )
throws IOException{
String newline = System.getProperty( "line.separator", "\r\n" );
String tag = ( namespace != null && namespace.length() > 0 ) ?
namespace + ":dax" : "dax";
String tag2 = ( namespace != null && namespace.length() > 0 ) ?
namespace + ":argument" : "argument";
// open tag
if ( indent != null && indent.length() > 0 ) stream.write( indent );
stream.write( '<' );
stream.write( tag );
writeAttribute( stream, " file=\"", this.mDAXLFN.getFilename() );
writeAttribute( stream, " id=\"", this.getID() );
// misc. attributes like the search tree depth
if ( this.getLevel() != -1 )
writeAttribute( stream, " level=\"", Integer.toString( this.getLevel()) );
// open tag: finish opening tag
stream.write( '>' );
if ( indent != null ) stream.write( newline );
// concat all command line fragments into one big string.
String newindent = indent==null ? null : indent + " ";
if ( this.getArgumentCount() > 0 ) {
if ( newindent != null ) stream.write( newindent );
stream.write( '<' );
stream.write( tag2 );
stream.write( '>' );
for ( Iterator i = this.getArgumentList().iterator(); i.hasNext(); ) {
// casting will print a mixed content string or Filename element
((Leaf) i.next()).shortXML( stream, "", namespace, 0x00 );
}
stream.write( "</" );
stream.write( tag2 );
stream.write( '>' );
if ( indent != null ) stream.write( newline );
}
// profiles to be dumped next
for ( Iterator i=this.getProfileList().iterator(); i.hasNext(); ) {
((Profile) i.next()).toXML( stream, newindent, namespace );
}
// finally any bound stdio descriptor
// FIXME: really need to dump a Filename element!
/* not populating stdin/stdout/stderr/other filenames for now */
/*
if ( this.getStdin() != null )
stream.write( formatFilename( "stdin", newindent, namespace,
this.getStdin(), false) );
if ( this.m_stdout != null )
stream.write( formatFilename( "stdout", newindent, namespace,
this.m_stdout, false) );
if ( this.m_stderr != null )
stream.write( formatFilename( "stderr", newindent, namespace,
this.m_stderr, false) );
// VDL referenced Filenames to be dumped next
for ( Iterator i=this.m_usesList.iterator(); i.hasNext(); ) {
stream.write( formatFilename( "uses", newindent, namespace,
(Filename) i.next(), true) );
}
*/
//write out the DAX file contents
stream.write( this.formatFilename( newindent, namespace, mDAXLFN , mPFN, mSite ) );
// finish job
if ( indent != null && indent.length() > 0 ) stream.write( indent );
stream.write( "</" );
stream.write( tag );
stream.write( '>' );
if ( indent != null ) stream.write( newline );
}
/**
* Helper: Formats the uses tags with the nested PFN tag.
*
* @param indent is the indentation of the element, may be null.
* @param namespace is an optional namespace to use in the tag.
* @param f is an instance of a <code>Filename</code> object.
* @param pfn the pfn for the dax file
* @param site the site attribute for the PFN
*
* @return the XML-formatted attributes without the element tags.
*/
private String formatFilename( String indent, String namespace,
Filename f, String pfn, String site ){
String newline = System.getProperty( "line.separator", "\r\n" );
String tag = "uses";
StringBuffer result = new StringBuffer( 128 );
if ( namespace != null && namespace.length() > 0 )
tag = namespace + ":" + tag;
if ( indent != null && indent.length() > 0 ) result.append( indent );
result.append('<').append(tag);
result.append(" file=\"").append(quote(f.getFilename(),true)).append('"');
result.append(" link=\"").append(LFN.toString(f.getLink())).append('"');
result.append(" register=\"")
.append(Boolean.toString( f.getRegister())).append('"');
result.append(" transfer=\"")
.append(LFN.transferString( f.getTransfer() )).append('"');
result.append(" type=\"")
.append(LFN.typeString( f.getType() )).append('"');
if( f.getOptional() )
result.append( " optional=\"" ).append( f.getOptional() ).append( "\"" );
if ( f.getTemporary() != null )
result.append(" temporaryHint=\"")
.append(quote(f.getTemporary(),true)).append('"');
//add a nested pfn if required.
if( pfn != null ){
result.append( ">" ).append( newline );
String newindent = indent==null ? null : indent + " ";
result.append( newindent );
result.append( "<pfn url=\"" ).append( this.mPFN ).append( "\"" ).
append( " site=\"").append( this.mSite ).append( "\"" ).
append( "/>" );
result.append( newline);
if ( indent != null && indent.length() > 0 ) result.append( indent );
result.append("</" ).append( tag ).append( ">");
}
else{// add newline and done
result.append("/>" );
}
if ( indent != null )
result.append( newline );
return result.toString();
}
/**
* Creates and returns a copy of this object.
*
* @return a new instance, semi-deep copy
*/
public Object clone(){
DAXJob result = (DAXJob) super.clone();
result.setDAXPFN( this.mPFN, this.mSite );
result.mDAXLFN = (Filename)this.mDAXLFN.clone();
return result;
}
}