/**
* 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 edu.isi.pegasus.planner.dax;
import edu.isi.pegasus.common.logging.LogManager;
import edu.isi.pegasus.common.util.XMLWriter;
import edu.isi.pegasus.common.util.Separator;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* This class is the container for any File object, either the RC section, or uses
* @author gmehta
* @version $Revision$
*/
public class File extends CatalogType {
/**
* The linkages that a file can be of
*/
public static enum LINK {
INPUT, input, OUTPUT, output, INOUT, inout, CHECKPOINT, checkpoint
};
/**
* Three Transfer modes supported, Transfer this file, don't transfer or stageout as well as optional. Dont mark transfer or absence as a failure
*/
public static enum TRANSFER {
TRUE, FALSE, OPTIONAL
}
/**
* The namespace on a file. This is used for Executables only
*/
protected String mNamespace;
/**
* The logical name of the file.
*/
protected String mName;
/**
* The logical version of the file. This is used for executables only.
*/
protected String mVersion;
/*
* The Linkage of the file. (Input, Output, or INOUT)
*/
protected LINK mLink;
/**
* Is the file optional
*/
protected boolean mOptional = false;
/**
* Should the file be registered in the replica catalog
*/
protected boolean mRegister = true;
/**
* Should the file be transferred on generation.
*/
protected TRANSFER mTransfer = TRANSFER.TRUE;
/**
* Is the file an executable.
*/
protected boolean mExecutable = false;
/**
* File size of the file no units required
*/
protected String mSize = "";
/**
* Create new file object
* @param name The name of the file
*/
public File(String name) {
mName = name;
}
/**
* Create new file object
* @param name The name of the file
* @param link The linkage of the file
*/
public File(String name, LINK link) {
mName = name;
mLink = link;
}
/**
* Copy constructor
* @param f File
*/
public File(File f) {
this(f, f.getLink());
}
/**
* Copy constructor, but change the linkage of the file.
* @param f File
* @param link Link
*/
public File(File f, LINK link) {
this(f.getNamespace(), f.getName(), f.getVersion(), link);
this.mOptional = f.getOptional();
this.mRegister = f.getRegister();
this.mTransfer = f.getTransfer();
this.mExecutable = f.getExecutable();
this.mSize = f.getSize();
this.mMetadata = new LinkedHashSet<MetaData>( f.mMetadata);
}
/**
* Create new File object
* @param namespace
* @param name
* @param version
*/
public File(String namespace, String name, String version) {
this( namespace, name, version, null );
}
/**
* Create a new file object
* @param namespace The namespace of the file
* @param name The name of the file
* @param version The version of the file
* @param link The linkage of the file.
*/
public File(String namespace, String name, String version, LINK link) {
super();
mNamespace = namespace;
mName = name;
mVersion = version;
mLink = link;
}
/**
* Get the name of the file
* @return
*/
public String getName() {
return mName;
}
/**
* Get the namespace of the file
* @return
*/
public String getNamespace() {
return mNamespace;
}
/**
* Get the version of the file
* @return
*/
public String getVersion() {
return mVersion;
}
/**
* Get the linkage of the file.
* @return
*/
public LINK getLink() {
return mLink;
}
/**
* Set the file linkage
* @param link
* @return
* @see LINK
*/
public File setLink(LINK link) {
mLink = link;
return this;
}
/**
* Set the optional flag on the file. Default is false
* @param optionalflag
* @return
*/
public File setOptional(boolean optionalflag) {
mOptional = optionalflag;
return this;
}
/**
* Check the optional flag of the file
* @return
*/
public boolean getOptional() {
return mOptional;
}
/**
* Set the register flag of the file. Default is true
* @param registerflag
* @return
*/
public File setRegister(boolean registerflag) {
mRegister = registerflag;
return this;
}
/**
* Get the register flag of this file.
* @return
*/
public boolean getRegister() {
return mRegister;
}
/**
* Set the transfer type of the file
* @param transferflag
* @return
* @see TRANSFER
*/
public File setTransfer(TRANSFER transferflag) {
mTransfer = transferflag;
return this;
}
/**
* Get the transfer type of the file
* @return
*/
public TRANSFER getTransfer() {
return mTransfer;
}
/**
* Mark the file as executable. Default is false
* @param executable
* @return
*/
public File setExecutable(boolean executable) {
mExecutable = executable;
return this;
}
/**
* Mark the file as executable. Default is false
* @return
*/
public File setExecutable() {
mExecutable = true;
return this;
}
/**
* Check if the file is an executable
* @return
*/
public boolean getExecutable() {
return mExecutable;
}
/**
* Set the size of the file.
* @param size
* @return
*/
public File setSize(String size) {
if (size != null) {
mSize = size;
}
return this;
}
/**
* Return the size of the file
* @return empty string if no size defined, otherwise returns the size
*/
public String getSize(){
return mSize;
}
public boolean isFile(){
return true;
}
/**
* Check if this File is equal to Object o
* @param o
* @return
*/
public boolean equals(Object o) {
if (o instanceof File) {
File f = (File) o;
return Separator.combine(mNamespace, mName, mVersion).equalsIgnoreCase(Separator.combine(f.mNamespace, f.mName, f.mVersion));
}
return false;
}
/**
* HashCode of this File
* @return
*/
public int hashCode() {
return Separator.combine(mNamespace, mName, mVersion).hashCode();
}
/**
* Return a clone of this File
* @return
*/
public File clone() {
File f = new File(mNamespace, mName, mVersion, mLink);
this.mOptional = f.getOptional();
this.mRegister = f.getRegister();
this.mTransfer = f.getTransfer();
this.mExecutable = f.getExecutable();
this.mSize = f.getSize();
this.mMetadata = f.getMetaData();
return f;
}
/**
* Write the file object
* @param writer
*/
public void toXML(XMLWriter writer) {
toXML(writer, 0, "file");
}
/**
* Write the file object, with indent level N
* @param writer
* @param indent
*/
public void toXML(XMLWriter writer, int indent) {
toXML(writer, indent, "file");
}
/**
* Write the file object as XML but render it as the elementname
* @param writer
* @param indent
* @param elementname
*/
public void toXML(XMLWriter writer, int indent, String elementname) {
if (elementname.equalsIgnoreCase("stdin")) {
//used in job element
writer.startElement("stdin", indent);
writer.writeAttribute("name", mName);
writer.endElement();
} else if (elementname.equalsIgnoreCase("stdout")) {
//used in job element
writer.startElement("stdout", indent);
writer.writeAttribute("name", mName);
writer.endElement();
} else if (elementname.equalsIgnoreCase("stderr")) {
//used in job element
writer.startElement("stderr", indent);
writer.writeAttribute("name", mName);
writer.endElement();
} else if (elementname.equalsIgnoreCase("argument")) {
//used in job's argument element
writer.startElement("file", indent);
writer.writeAttribute("name", mName);
writer.noLine();
writer.endElement();
} else if (elementname.equalsIgnoreCase("uses")) {
// used by job, dax, dag and transformation elements
writer.startElement("uses", indent);
if (mNamespace != null && !mNamespace.isEmpty()) {
writer.writeAttribute("namespace", mNamespace);
}
writer.writeAttribute("name", mName);
if (mVersion != null && !mVersion.isEmpty()) {
writer.writeAttribute("version", mVersion);
}
if (mLink != null) {
writer.writeAttribute("link", mLink.toString().toLowerCase());
//transfer flag for input files should be ignored
if (!( mLink == LINK.INPUT || mLink == LINK.input )){
writer.writeAttribute("transfer", mTransfer.toString().toLowerCase());
writer.writeAttribute("register", Boolean.toString(mRegister));
}
}
if (mOptional) {
writer.writeAttribute("optional", "true");
}
if (mExecutable) {
writer.writeAttribute("executable", "true");
}
if (mSize != null && !mSize.isEmpty() ) {
writer.writeAttribute("size", mSize);
}
if( mMetadata.isEmpty() ){
writer.endElement();
}
else{
//call CatalogType's writer method to generate the profile, metadata and pfn elements
super.toXML(writer, indent);
writer.endElement(indent);
}
} else if (elementname.equalsIgnoreCase("file")) {
//Used by the file element at the top of the dax
if (mPFNs.isEmpty() && mMetadata.isEmpty()) {
mLogger.log("The file element for " + mName + " must have atleast 1 pfn or 1 metadata entry. Skipping empty file element", LogManager.WARNING_MESSAGE_LEVEL);
} else {
writer.startElement("file", indent);
writer.writeAttribute("name", mName);
//call CatalogType's writer method to generate the profile, metadata and pfn elements
super.toXML(writer, indent);
writer.endElement(indent);
}
}
}
}