/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/**
 * Autogenerated by Thrift Compiler (0.18.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.model.task;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.18.1)")
public class DataStagingTaskModel implements org.apache.thrift.TBase<DataStagingTaskModel, DataStagingTaskModel._Fields>, java.io.Serializable, Cloneable, Comparable<DataStagingTaskModel> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("DataStagingTaskModel");

  private static final org.apache.thrift.protocol.TField SOURCE_FIELD_DESC = new org.apache.thrift.protocol.TField("source", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField DESTINATION_FIELD_DESC = new org.apache.thrift.protocol.TField("destination", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.I32, (short)3);
  private static final org.apache.thrift.protocol.TField TRANSFER_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("transferStartTime", org.apache.thrift.protocol.TType.I64, (short)4);
  private static final org.apache.thrift.protocol.TField TRANSFER_END_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("transferEndTime", org.apache.thrift.protocol.TType.I64, (short)5);
  private static final org.apache.thrift.protocol.TField TRANSFER_RATE_FIELD_DESC = new org.apache.thrift.protocol.TField("transferRate", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField PROCESS_INPUT_FIELD_DESC = new org.apache.thrift.protocol.TField("processInput", org.apache.thrift.protocol.TType.STRUCT, (short)7);
  private static final org.apache.thrift.protocol.TField PROCESS_OUTPUT_FIELD_DESC = new org.apache.thrift.protocol.TField("processOutput", org.apache.thrift.protocol.TType.STRUCT, (short)8);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new DataStagingTaskModelStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new DataStagingTaskModelTupleSchemeFactory();

  private @org.apache.thrift.annotation.Nullable java.lang.String source; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String destination; // required
  private @org.apache.thrift.annotation.Nullable DataStageType type; // required
  private long transferStartTime; // optional
  private long transferEndTime; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String transferRate; // optional
  private @org.apache.thrift.annotation.Nullable org.apache.airavata.model.application.io.InputDataObjectType processInput; // optional
  private @org.apache.thrift.annotation.Nullable org.apache.airavata.model.application.io.OutputDataObjectType processOutput; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    SOURCE((short)1, "source"),
    DESTINATION((short)2, "destination"),
    /**
     * 
     * @see DataStageType
     */
    TYPE((short)3, "type"),
    TRANSFER_START_TIME((short)4, "transferStartTime"),
    TRANSFER_END_TIME((short)5, "transferEndTime"),
    TRANSFER_RATE((short)6, "transferRate"),
    PROCESS_INPUT((short)7, "processInput"),
    PROCESS_OUTPUT((short)8, "processOutput");

    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

    static {
      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
        byName.put(field.getFieldName(), field);
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // SOURCE
          return SOURCE;
        case 2: // DESTINATION
          return DESTINATION;
        case 3: // TYPE
          return TYPE;
        case 4: // TRANSFER_START_TIME
          return TRANSFER_START_TIME;
        case 5: // TRANSFER_END_TIME
          return TRANSFER_END_TIME;
        case 6: // TRANSFER_RATE
          return TRANSFER_RATE;
        case 7: // PROCESS_INPUT
          return PROCESS_INPUT;
        case 8: // PROCESS_OUTPUT
          return PROCESS_OUTPUT;
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByName(java.lang.String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final java.lang.String _fieldName;

    _Fields(short thriftId, java.lang.String fieldName) {
      _thriftId = thriftId;
      _fieldName = fieldName;
    }

    @Override
    public short getThriftFieldId() {
      return _thriftId;
    }

    @Override
    public java.lang.String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __TRANSFERSTARTTIME_ISSET_ID = 0;
  private static final int __TRANSFERENDTIME_ISSET_ID = 1;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.TRANSFER_START_TIME,_Fields.TRANSFER_END_TIME,_Fields.TRANSFER_RATE,_Fields.PROCESS_INPUT,_Fields.PROCESS_OUTPUT};
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.SOURCE, new org.apache.thrift.meta_data.FieldMetaData("source", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.DESTINATION, new org.apache.thrift.meta_data.FieldMetaData("destination", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, DataStageType.class)));
    tmpMap.put(_Fields.TRANSFER_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("transferStartTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.TRANSFER_END_TIME, new org.apache.thrift.meta_data.FieldMetaData("transferEndTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.TRANSFER_RATE, new org.apache.thrift.meta_data.FieldMetaData("transferRate", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PROCESS_INPUT, new org.apache.thrift.meta_data.FieldMetaData("processInput", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.application.io.InputDataObjectType.class)));
    tmpMap.put(_Fields.PROCESS_OUTPUT, new org.apache.thrift.meta_data.FieldMetaData("processOutput", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.application.io.OutputDataObjectType.class)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(DataStagingTaskModel.class, metaDataMap);
  }

  public DataStagingTaskModel() {
  }

  public DataStagingTaskModel(
    java.lang.String source,
    java.lang.String destination,
    DataStageType type)
  {
    this();
    this.source = source;
    this.destination = destination;
    this.type = type;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public DataStagingTaskModel(DataStagingTaskModel other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetSource()) {
      this.source = other.source;
    }
    if (other.isSetDestination()) {
      this.destination = other.destination;
    }
    if (other.isSetType()) {
      this.type = other.type;
    }
    this.transferStartTime = other.transferStartTime;
    this.transferEndTime = other.transferEndTime;
    if (other.isSetTransferRate()) {
      this.transferRate = other.transferRate;
    }
    if (other.isSetProcessInput()) {
      this.processInput = new org.apache.airavata.model.application.io.InputDataObjectType(other.processInput);
    }
    if (other.isSetProcessOutput()) {
      this.processOutput = new org.apache.airavata.model.application.io.OutputDataObjectType(other.processOutput);
    }
  }

  @Override
  public DataStagingTaskModel deepCopy() {
    return new DataStagingTaskModel(this);
  }

  @Override
  public void clear() {
    this.source = null;
    this.destination = null;
    this.type = null;
    setTransferStartTimeIsSet(false);
    this.transferStartTime = 0;
    setTransferEndTimeIsSet(false);
    this.transferEndTime = 0;
    this.transferRate = null;
    this.processInput = null;
    this.processOutput = null;
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getSource() {
    return this.source;
  }

  public void setSource(@org.apache.thrift.annotation.Nullable java.lang.String source) {
    this.source = source;
  }

  public void unsetSource() {
    this.source = null;
  }

  /** Returns true if field source is set (has been assigned a value) and false otherwise */
  public boolean isSetSource() {
    return this.source != null;
  }

  public void setSourceIsSet(boolean value) {
    if (!value) {
      this.source = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getDestination() {
    return this.destination;
  }

  public void setDestination(@org.apache.thrift.annotation.Nullable java.lang.String destination) {
    this.destination = destination;
  }

  public void unsetDestination() {
    this.destination = null;
  }

  /** Returns true if field destination is set (has been assigned a value) and false otherwise */
  public boolean isSetDestination() {
    return this.destination != null;
  }

  public void setDestinationIsSet(boolean value) {
    if (!value) {
      this.destination = null;
    }
  }

  /**
   * 
   * @see DataStageType
   */
  @org.apache.thrift.annotation.Nullable
  public DataStageType getType() {
    return this.type;
  }

  /**
   * 
   * @see DataStageType
   */
  public void setType(@org.apache.thrift.annotation.Nullable DataStageType type) {
    this.type = type;
  }

  public void unsetType() {
    this.type = null;
  }

  /** Returns true if field type is set (has been assigned a value) and false otherwise */
  public boolean isSetType() {
    return this.type != null;
  }

  public void setTypeIsSet(boolean value) {
    if (!value) {
      this.type = null;
    }
  }

  public long getTransferStartTime() {
    return this.transferStartTime;
  }

  public void setTransferStartTime(long transferStartTime) {
    this.transferStartTime = transferStartTime;
    setTransferStartTimeIsSet(true);
  }

  public void unsetTransferStartTime() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __TRANSFERSTARTTIME_ISSET_ID);
  }

  /** Returns true if field transferStartTime is set (has been assigned a value) and false otherwise */
  public boolean isSetTransferStartTime() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __TRANSFERSTARTTIME_ISSET_ID);
  }

  public void setTransferStartTimeIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __TRANSFERSTARTTIME_ISSET_ID, value);
  }

  public long getTransferEndTime() {
    return this.transferEndTime;
  }

  public void setTransferEndTime(long transferEndTime) {
    this.transferEndTime = transferEndTime;
    setTransferEndTimeIsSet(true);
  }

  public void unsetTransferEndTime() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __TRANSFERENDTIME_ISSET_ID);
  }

  /** Returns true if field transferEndTime is set (has been assigned a value) and false otherwise */
  public boolean isSetTransferEndTime() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __TRANSFERENDTIME_ISSET_ID);
  }

  public void setTransferEndTimeIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __TRANSFERENDTIME_ISSET_ID, value);
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getTransferRate() {
    return this.transferRate;
  }

  public void setTransferRate(@org.apache.thrift.annotation.Nullable java.lang.String transferRate) {
    this.transferRate = transferRate;
  }

  public void unsetTransferRate() {
    this.transferRate = null;
  }

  /** Returns true if field transferRate is set (has been assigned a value) and false otherwise */
  public boolean isSetTransferRate() {
    return this.transferRate != null;
  }

  public void setTransferRateIsSet(boolean value) {
    if (!value) {
      this.transferRate = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public org.apache.airavata.model.application.io.InputDataObjectType getProcessInput() {
    return this.processInput;
  }

  public void setProcessInput(@org.apache.thrift.annotation.Nullable org.apache.airavata.model.application.io.InputDataObjectType processInput) {
    this.processInput = processInput;
  }

  public void unsetProcessInput() {
    this.processInput = null;
  }

  /** Returns true if field processInput is set (has been assigned a value) and false otherwise */
  public boolean isSetProcessInput() {
    return this.processInput != null;
  }

  public void setProcessInputIsSet(boolean value) {
    if (!value) {
      this.processInput = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public org.apache.airavata.model.application.io.OutputDataObjectType getProcessOutput() {
    return this.processOutput;
  }

  public void setProcessOutput(@org.apache.thrift.annotation.Nullable org.apache.airavata.model.application.io.OutputDataObjectType processOutput) {
    this.processOutput = processOutput;
  }

  public void unsetProcessOutput() {
    this.processOutput = null;
  }

  /** Returns true if field processOutput is set (has been assigned a value) and false otherwise */
  public boolean isSetProcessOutput() {
    return this.processOutput != null;
  }

  public void setProcessOutputIsSet(boolean value) {
    if (!value) {
      this.processOutput = null;
    }
  }

  @Override
  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case SOURCE:
      if (value == null) {
        unsetSource();
      } else {
        setSource((java.lang.String)value);
      }
      break;

    case DESTINATION:
      if (value == null) {
        unsetDestination();
      } else {
        setDestination((java.lang.String)value);
      }
      break;

    case TYPE:
      if (value == null) {
        unsetType();
      } else {
        setType((DataStageType)value);
      }
      break;

    case TRANSFER_START_TIME:
      if (value == null) {
        unsetTransferStartTime();
      } else {
        setTransferStartTime((java.lang.Long)value);
      }
      break;

    case TRANSFER_END_TIME:
      if (value == null) {
        unsetTransferEndTime();
      } else {
        setTransferEndTime((java.lang.Long)value);
      }
      break;

    case TRANSFER_RATE:
      if (value == null) {
        unsetTransferRate();
      } else {
        setTransferRate((java.lang.String)value);
      }
      break;

    case PROCESS_INPUT:
      if (value == null) {
        unsetProcessInput();
      } else {
        setProcessInput((org.apache.airavata.model.application.io.InputDataObjectType)value);
      }
      break;

    case PROCESS_OUTPUT:
      if (value == null) {
        unsetProcessOutput();
      } else {
        setProcessOutput((org.apache.airavata.model.application.io.OutputDataObjectType)value);
      }
      break;

    }
  }

  @org.apache.thrift.annotation.Nullable
  @Override
  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case SOURCE:
      return getSource();

    case DESTINATION:
      return getDestination();

    case TYPE:
      return getType();

    case TRANSFER_START_TIME:
      return getTransferStartTime();

    case TRANSFER_END_TIME:
      return getTransferEndTime();

    case TRANSFER_RATE:
      return getTransferRate();

    case PROCESS_INPUT:
      return getProcessInput();

    case PROCESS_OUTPUT:
      return getProcessOutput();

    }
    throw new java.lang.IllegalStateException();
  }

  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
  @Override
  public boolean isSet(_Fields field) {
    if (field == null) {
      throw new java.lang.IllegalArgumentException();
    }

    switch (field) {
    case SOURCE:
      return isSetSource();
    case DESTINATION:
      return isSetDestination();
    case TYPE:
      return isSetType();
    case TRANSFER_START_TIME:
      return isSetTransferStartTime();
    case TRANSFER_END_TIME:
      return isSetTransferEndTime();
    case TRANSFER_RATE:
      return isSetTransferRate();
    case PROCESS_INPUT:
      return isSetProcessInput();
    case PROCESS_OUTPUT:
      return isSetProcessOutput();
    }
    throw new java.lang.IllegalStateException();
  }

  @Override
  public boolean equals(java.lang.Object that) {
    if (that instanceof DataStagingTaskModel)
      return this.equals((DataStagingTaskModel)that);
    return false;
  }

  public boolean equals(DataStagingTaskModel that) {
    if (that == null)
      return false;
    if (this == that)
      return true;

    boolean this_present_source = true && this.isSetSource();
    boolean that_present_source = true && that.isSetSource();
    if (this_present_source || that_present_source) {
      if (!(this_present_source && that_present_source))
        return false;
      if (!this.source.equals(that.source))
        return false;
    }

    boolean this_present_destination = true && this.isSetDestination();
    boolean that_present_destination = true && that.isSetDestination();
    if (this_present_destination || that_present_destination) {
      if (!(this_present_destination && that_present_destination))
        return false;
      if (!this.destination.equals(that.destination))
        return false;
    }

    boolean this_present_type = true && this.isSetType();
    boolean that_present_type = true && that.isSetType();
    if (this_present_type || that_present_type) {
      if (!(this_present_type && that_present_type))
        return false;
      if (!this.type.equals(that.type))
        return false;
    }

    boolean this_present_transferStartTime = true && this.isSetTransferStartTime();
    boolean that_present_transferStartTime = true && that.isSetTransferStartTime();
    if (this_present_transferStartTime || that_present_transferStartTime) {
      if (!(this_present_transferStartTime && that_present_transferStartTime))
        return false;
      if (this.transferStartTime != that.transferStartTime)
        return false;
    }

    boolean this_present_transferEndTime = true && this.isSetTransferEndTime();
    boolean that_present_transferEndTime = true && that.isSetTransferEndTime();
    if (this_present_transferEndTime || that_present_transferEndTime) {
      if (!(this_present_transferEndTime && that_present_transferEndTime))
        return false;
      if (this.transferEndTime != that.transferEndTime)
        return false;
    }

    boolean this_present_transferRate = true && this.isSetTransferRate();
    boolean that_present_transferRate = true && that.isSetTransferRate();
    if (this_present_transferRate || that_present_transferRate) {
      if (!(this_present_transferRate && that_present_transferRate))
        return false;
      if (!this.transferRate.equals(that.transferRate))
        return false;
    }

    boolean this_present_processInput = true && this.isSetProcessInput();
    boolean that_present_processInput = true && that.isSetProcessInput();
    if (this_present_processInput || that_present_processInput) {
      if (!(this_present_processInput && that_present_processInput))
        return false;
      if (!this.processInput.equals(that.processInput))
        return false;
    }

    boolean this_present_processOutput = true && this.isSetProcessOutput();
    boolean that_present_processOutput = true && that.isSetProcessOutput();
    if (this_present_processOutput || that_present_processOutput) {
      if (!(this_present_processOutput && that_present_processOutput))
        return false;
      if (!this.processOutput.equals(that.processOutput))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    int hashCode = 1;

    hashCode = hashCode * 8191 + ((isSetSource()) ? 131071 : 524287);
    if (isSetSource())
      hashCode = hashCode * 8191 + source.hashCode();

    hashCode = hashCode * 8191 + ((isSetDestination()) ? 131071 : 524287);
    if (isSetDestination())
      hashCode = hashCode * 8191 + destination.hashCode();

    hashCode = hashCode * 8191 + ((isSetType()) ? 131071 : 524287);
    if (isSetType())
      hashCode = hashCode * 8191 + type.getValue();

    hashCode = hashCode * 8191 + ((isSetTransferStartTime()) ? 131071 : 524287);
    if (isSetTransferStartTime())
      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(transferStartTime);

    hashCode = hashCode * 8191 + ((isSetTransferEndTime()) ? 131071 : 524287);
    if (isSetTransferEndTime())
      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(transferEndTime);

    hashCode = hashCode * 8191 + ((isSetTransferRate()) ? 131071 : 524287);
    if (isSetTransferRate())
      hashCode = hashCode * 8191 + transferRate.hashCode();

    hashCode = hashCode * 8191 + ((isSetProcessInput()) ? 131071 : 524287);
    if (isSetProcessInput())
      hashCode = hashCode * 8191 + processInput.hashCode();

    hashCode = hashCode * 8191 + ((isSetProcessOutput()) ? 131071 : 524287);
    if (isSetProcessOutput())
      hashCode = hashCode * 8191 + processOutput.hashCode();

    return hashCode;
  }

  @Override
  public int compareTo(DataStagingTaskModel other) {
    if (!getClass().equals(other.getClass())) {
      return getClass().getName().compareTo(other.getClass().getName());
    }

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.compare(isSetSource(), other.isSetSource());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSource()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.source, other.source);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetDestination(), other.isSetDestination());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDestination()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.destination, other.destination);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetType(), other.isSetType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, other.type);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetTransferStartTime(), other.isSetTransferStartTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTransferStartTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.transferStartTime, other.transferStartTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetTransferEndTime(), other.isSetTransferEndTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTransferEndTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.transferEndTime, other.transferEndTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetTransferRate(), other.isSetTransferRate());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTransferRate()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.transferRate, other.transferRate);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetProcessInput(), other.isSetProcessInput());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProcessInput()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.processInput, other.processInput);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetProcessOutput(), other.isSetProcessOutput());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProcessOutput()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.processOutput, other.processOutput);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  @org.apache.thrift.annotation.Nullable
  @Override
  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  @Override
  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    scheme(iprot).read(iprot, this);
  }

  @Override
  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    scheme(oprot).write(oprot, this);
  }

  @Override
  public java.lang.String toString() {
    java.lang.StringBuilder sb = new java.lang.StringBuilder("DataStagingTaskModel(");
    boolean first = true;

    sb.append("source:");
    if (this.source == null) {
      sb.append("null");
    } else {
      sb.append(this.source);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("destination:");
    if (this.destination == null) {
      sb.append("null");
    } else {
      sb.append(this.destination);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("type:");
    if (this.type == null) {
      sb.append("null");
    } else {
      sb.append(this.type);
    }
    first = false;
    if (isSetTransferStartTime()) {
      if (!first) sb.append(", ");
      sb.append("transferStartTime:");
      sb.append(this.transferStartTime);
      first = false;
    }
    if (isSetTransferEndTime()) {
      if (!first) sb.append(", ");
      sb.append("transferEndTime:");
      sb.append(this.transferEndTime);
      first = false;
    }
    if (isSetTransferRate()) {
      if (!first) sb.append(", ");
      sb.append("transferRate:");
      if (this.transferRate == null) {
        sb.append("null");
      } else {
        sb.append(this.transferRate);
      }
      first = false;
    }
    if (isSetProcessInput()) {
      if (!first) sb.append(", ");
      sb.append("processInput:");
      if (this.processInput == null) {
        sb.append("null");
      } else {
        sb.append(this.processInput);
      }
      first = false;
    }
    if (isSetProcessOutput()) {
      if (!first) sb.append(", ");
      sb.append("processOutput:");
      if (this.processOutput == null) {
        sb.append("null");
      } else {
        sb.append(this.processOutput);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    if (!isSetSource()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'source' is unset! Struct:" + toString());
    }

    if (!isSetDestination()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'destination' is unset! Struct:" + toString());
    }

    if (!isSetType()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'type' is unset! Struct:" + toString());
    }

    // check for sub-struct validity
    if (processInput != null) {
      processInput.validate();
    }
    if (processOutput != null) {
      processOutput.validate();
    }
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
    try {
      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
      __isset_bitfield = 0;
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class DataStagingTaskModelStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    @Override
    public DataStagingTaskModelStandardScheme getScheme() {
      return new DataStagingTaskModelStandardScheme();
    }
  }

  private static class DataStagingTaskModelStandardScheme extends org.apache.thrift.scheme.StandardScheme<DataStagingTaskModel> {

    @Override
    public void read(org.apache.thrift.protocol.TProtocol iprot, DataStagingTaskModel struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // SOURCE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.source = iprot.readString();
              struct.setSourceIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // DESTINATION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.destination = iprot.readString();
              struct.setDestinationIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.type = org.apache.airavata.model.task.DataStageType.findByValue(iprot.readI32());
              struct.setTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // TRANSFER_START_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.transferStartTime = iprot.readI64();
              struct.setTransferStartTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // TRANSFER_END_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.transferEndTime = iprot.readI64();
              struct.setTransferEndTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // TRANSFER_RATE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.transferRate = iprot.readString();
              struct.setTransferRateIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // PROCESS_INPUT
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.processInput = new org.apache.airavata.model.application.io.InputDataObjectType();
              struct.processInput.read(iprot);
              struct.setProcessInputIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // PROCESS_OUTPUT
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.processOutput = new org.apache.airavata.model.application.io.OutputDataObjectType();
              struct.processOutput.read(iprot);
              struct.setProcessOutputIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

    @Override
    public void write(org.apache.thrift.protocol.TProtocol oprot, DataStagingTaskModel struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.source != null) {
        oprot.writeFieldBegin(SOURCE_FIELD_DESC);
        oprot.writeString(struct.source);
        oprot.writeFieldEnd();
      }
      if (struct.destination != null) {
        oprot.writeFieldBegin(DESTINATION_FIELD_DESC);
        oprot.writeString(struct.destination);
        oprot.writeFieldEnd();
      }
      if (struct.type != null) {
        oprot.writeFieldBegin(TYPE_FIELD_DESC);
        oprot.writeI32(struct.type.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.isSetTransferStartTime()) {
        oprot.writeFieldBegin(TRANSFER_START_TIME_FIELD_DESC);
        oprot.writeI64(struct.transferStartTime);
        oprot.writeFieldEnd();
      }
      if (struct.isSetTransferEndTime()) {
        oprot.writeFieldBegin(TRANSFER_END_TIME_FIELD_DESC);
        oprot.writeI64(struct.transferEndTime);
        oprot.writeFieldEnd();
      }
      if (struct.transferRate != null) {
        if (struct.isSetTransferRate()) {
          oprot.writeFieldBegin(TRANSFER_RATE_FIELD_DESC);
          oprot.writeString(struct.transferRate);
          oprot.writeFieldEnd();
        }
      }
      if (struct.processInput != null) {
        if (struct.isSetProcessInput()) {
          oprot.writeFieldBegin(PROCESS_INPUT_FIELD_DESC);
          struct.processInput.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.processOutput != null) {
        if (struct.isSetProcessOutput()) {
          oprot.writeFieldBegin(PROCESS_OUTPUT_FIELD_DESC);
          struct.processOutput.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class DataStagingTaskModelTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    @Override
    public DataStagingTaskModelTupleScheme getScheme() {
      return new DataStagingTaskModelTupleScheme();
    }
  }

  private static class DataStagingTaskModelTupleScheme extends org.apache.thrift.scheme.TupleScheme<DataStagingTaskModel> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, DataStagingTaskModel struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.source);
      oprot.writeString(struct.destination);
      oprot.writeI32(struct.type.getValue());
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetTransferStartTime()) {
        optionals.set(0);
      }
      if (struct.isSetTransferEndTime()) {
        optionals.set(1);
      }
      if (struct.isSetTransferRate()) {
        optionals.set(2);
      }
      if (struct.isSetProcessInput()) {
        optionals.set(3);
      }
      if (struct.isSetProcessOutput()) {
        optionals.set(4);
      }
      oprot.writeBitSet(optionals, 5);
      if (struct.isSetTransferStartTime()) {
        oprot.writeI64(struct.transferStartTime);
      }
      if (struct.isSetTransferEndTime()) {
        oprot.writeI64(struct.transferEndTime);
      }
      if (struct.isSetTransferRate()) {
        oprot.writeString(struct.transferRate);
      }
      if (struct.isSetProcessInput()) {
        struct.processInput.write(oprot);
      }
      if (struct.isSetProcessOutput()) {
        struct.processOutput.write(oprot);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, DataStagingTaskModel struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.source = iprot.readString();
      struct.setSourceIsSet(true);
      struct.destination = iprot.readString();
      struct.setDestinationIsSet(true);
      struct.type = org.apache.airavata.model.task.DataStageType.findByValue(iprot.readI32());
      struct.setTypeIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(5);
      if (incoming.get(0)) {
        struct.transferStartTime = iprot.readI64();
        struct.setTransferStartTimeIsSet(true);
      }
      if (incoming.get(1)) {
        struct.transferEndTime = iprot.readI64();
        struct.setTransferEndTimeIsSet(true);
      }
      if (incoming.get(2)) {
        struct.transferRate = iprot.readString();
        struct.setTransferRateIsSet(true);
      }
      if (incoming.get(3)) {
        struct.processInput = new org.apache.airavata.model.application.io.InputDataObjectType();
        struct.processInput.read(iprot);
        struct.setProcessInputIsSet(true);
      }
      if (incoming.get(4)) {
        struct.processOutput = new org.apache.airavata.model.application.io.OutputDataObjectType();
        struct.processOutput.read(iprot);
        struct.setProcessOutputIsSet(true);
      }
    }
  }

  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
  }
}

