/**
 * 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.10.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.model.data.movement;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * Data Movement Interfaces
 * 
 * dataMovementInterfaceId: The Data Movement Interface has to be previously registered and referenced here.
 * 
 * priorityOrder:
 *  For resources with multiple interfaces, the priority order should be selected.
 *   Lower the numerical number, higher the priority
 * 
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class DataMovementInterface implements org.apache.thrift.TBase<DataMovementInterface, DataMovementInterface._Fields>, java.io.Serializable, Cloneable, Comparable<DataMovementInterface> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("DataMovementInterface");

  private static final org.apache.thrift.protocol.TField DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField DATA_MOVEMENT_PROTOCOL_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementProtocol", org.apache.thrift.protocol.TType.I32, (short)2);
  private static final org.apache.thrift.protocol.TField PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("priorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);
  private static final org.apache.thrift.protocol.TField CREATION_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("creationTime", org.apache.thrift.protocol.TType.I64, (short)4);
  private static final org.apache.thrift.protocol.TField UPDATE_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("updateTime", org.apache.thrift.protocol.TType.I64, (short)5);
  private static final org.apache.thrift.protocol.TField STORAGE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("storageResourceId", org.apache.thrift.protocol.TType.STRING, (short)6);

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

  private java.lang.String dataMovementInterfaceId; // required
  private DataMovementProtocol dataMovementProtocol; // required
  private int priorityOrder; // required
  private long creationTime; // optional
  private long updateTime; // optional
  private java.lang.String storageResourceId; // 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 {
    DATA_MOVEMENT_INTERFACE_ID((short)1, "dataMovementInterfaceId"),
    /**
     * 
     * @see DataMovementProtocol
     */
    DATA_MOVEMENT_PROTOCOL((short)2, "dataMovementProtocol"),
    PRIORITY_ORDER((short)3, "priorityOrder"),
    CREATION_TIME((short)4, "creationTime"),
    UPDATE_TIME((short)5, "updateTime"),
    STORAGE_RESOURCE_ID((short)6, "storageResourceId");

    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.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // DATA_MOVEMENT_INTERFACE_ID
          return DATA_MOVEMENT_INTERFACE_ID;
        case 2: // DATA_MOVEMENT_PROTOCOL
          return DATA_MOVEMENT_PROTOCOL;
        case 3: // PRIORITY_ORDER
          return PRIORITY_ORDER;
        case 4: // CREATION_TIME
          return CREATION_TIME;
        case 5: // UPDATE_TIME
          return UPDATE_TIME;
        case 6: // STORAGE_RESOURCE_ID
          return STORAGE_RESOURCE_ID;
        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.
     */
    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;
    }

    public short getThriftFieldId() {
      return _thriftId;
    }

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

  // isset id assignments
  private static final int __PRIORITYORDER_ISSET_ID = 0;
  private static final int __CREATIONTIME_ISSET_ID = 1;
  private static final int __UPDATETIME_ISSET_ID = 2;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.CREATION_TIME,_Fields.UPDATE_TIME,_Fields.STORAGE_RESOURCE_ID};
  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.DATA_MOVEMENT_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.DATA_MOVEMENT_PROTOCOL, new org.apache.thrift.meta_data.FieldMetaData("dataMovementProtocol", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, DataMovementProtocol.class)));
    tmpMap.put(_Fields.PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("priorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.CREATION_TIME, new org.apache.thrift.meta_data.FieldMetaData("creationTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.UPDATE_TIME, new org.apache.thrift.meta_data.FieldMetaData("updateTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.STORAGE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("storageResourceId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(DataMovementInterface.class, metaDataMap);
  }

  public DataMovementInterface() {
    this.priorityOrder = 0;

  }

  public DataMovementInterface(
    java.lang.String dataMovementInterfaceId,
    DataMovementProtocol dataMovementProtocol,
    int priorityOrder)
  {
    this();
    this.dataMovementInterfaceId = dataMovementInterfaceId;
    this.dataMovementProtocol = dataMovementProtocol;
    this.priorityOrder = priorityOrder;
    setPriorityOrderIsSet(true);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public DataMovementInterface(DataMovementInterface other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetDataMovementInterfaceId()) {
      this.dataMovementInterfaceId = other.dataMovementInterfaceId;
    }
    if (other.isSetDataMovementProtocol()) {
      this.dataMovementProtocol = other.dataMovementProtocol;
    }
    this.priorityOrder = other.priorityOrder;
    this.creationTime = other.creationTime;
    this.updateTime = other.updateTime;
    if (other.isSetStorageResourceId()) {
      this.storageResourceId = other.storageResourceId;
    }
  }

  public DataMovementInterface deepCopy() {
    return new DataMovementInterface(this);
  }

  @Override
  public void clear() {
    this.dataMovementInterfaceId = null;
    this.dataMovementProtocol = null;
    this.priorityOrder = 0;

    setCreationTimeIsSet(false);
    this.creationTime = 0;
    setUpdateTimeIsSet(false);
    this.updateTime = 0;
    this.storageResourceId = null;
  }

  public java.lang.String getDataMovementInterfaceId() {
    return this.dataMovementInterfaceId;
  }

  public void setDataMovementInterfaceId(java.lang.String dataMovementInterfaceId) {
    this.dataMovementInterfaceId = dataMovementInterfaceId;
  }

  public void unsetDataMovementInterfaceId() {
    this.dataMovementInterfaceId = null;
  }

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

  public void setDataMovementInterfaceIdIsSet(boolean value) {
    if (!value) {
      this.dataMovementInterfaceId = null;
    }
  }

  /**
   * 
   * @see DataMovementProtocol
   */
  public DataMovementProtocol getDataMovementProtocol() {
    return this.dataMovementProtocol;
  }

  /**
   * 
   * @see DataMovementProtocol
   */
  public void setDataMovementProtocol(DataMovementProtocol dataMovementProtocol) {
    this.dataMovementProtocol = dataMovementProtocol;
  }

  public void unsetDataMovementProtocol() {
    this.dataMovementProtocol = null;
  }

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

  public void setDataMovementProtocolIsSet(boolean value) {
    if (!value) {
      this.dataMovementProtocol = null;
    }
  }

  public int getPriorityOrder() {
    return this.priorityOrder;
  }

  public void setPriorityOrder(int priorityOrder) {
    this.priorityOrder = priorityOrder;
    setPriorityOrderIsSet(true);
  }

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

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

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

  public long getCreationTime() {
    return this.creationTime;
  }

  public void setCreationTime(long creationTime) {
    this.creationTime = creationTime;
    setCreationTimeIsSet(true);
  }

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

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

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

  public long getUpdateTime() {
    return this.updateTime;
  }

  public void setUpdateTime(long updateTime) {
    this.updateTime = updateTime;
    setUpdateTimeIsSet(true);
  }

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

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

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

  public java.lang.String getStorageResourceId() {
    return this.storageResourceId;
  }

  public void setStorageResourceId(java.lang.String storageResourceId) {
    this.storageResourceId = storageResourceId;
  }

  public void unsetStorageResourceId() {
    this.storageResourceId = null;
  }

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

  public void setStorageResourceIdIsSet(boolean value) {
    if (!value) {
      this.storageResourceId = null;
    }
  }

  public void setFieldValue(_Fields field, java.lang.Object value) {
    switch (field) {
    case DATA_MOVEMENT_INTERFACE_ID:
      if (value == null) {
        unsetDataMovementInterfaceId();
      } else {
        setDataMovementInterfaceId((java.lang.String)value);
      }
      break;

    case DATA_MOVEMENT_PROTOCOL:
      if (value == null) {
        unsetDataMovementProtocol();
      } else {
        setDataMovementProtocol((DataMovementProtocol)value);
      }
      break;

    case PRIORITY_ORDER:
      if (value == null) {
        unsetPriorityOrder();
      } else {
        setPriorityOrder((java.lang.Integer)value);
      }
      break;

    case CREATION_TIME:
      if (value == null) {
        unsetCreationTime();
      } else {
        setCreationTime((java.lang.Long)value);
      }
      break;

    case UPDATE_TIME:
      if (value == null) {
        unsetUpdateTime();
      } else {
        setUpdateTime((java.lang.Long)value);
      }
      break;

    case STORAGE_RESOURCE_ID:
      if (value == null) {
        unsetStorageResourceId();
      } else {
        setStorageResourceId((java.lang.String)value);
      }
      break;

    }
  }

  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case DATA_MOVEMENT_INTERFACE_ID:
      return getDataMovementInterfaceId();

    case DATA_MOVEMENT_PROTOCOL:
      return getDataMovementProtocol();

    case PRIORITY_ORDER:
      return getPriorityOrder();

    case CREATION_TIME:
      return getCreationTime();

    case UPDATE_TIME:
      return getUpdateTime();

    case STORAGE_RESOURCE_ID:
      return getStorageResourceId();

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

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

    switch (field) {
    case DATA_MOVEMENT_INTERFACE_ID:
      return isSetDataMovementInterfaceId();
    case DATA_MOVEMENT_PROTOCOL:
      return isSetDataMovementProtocol();
    case PRIORITY_ORDER:
      return isSetPriorityOrder();
    case CREATION_TIME:
      return isSetCreationTime();
    case UPDATE_TIME:
      return isSetUpdateTime();
    case STORAGE_RESOURCE_ID:
      return isSetStorageResourceId();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_dataMovementInterfaceId = true && this.isSetDataMovementInterfaceId();
    boolean that_present_dataMovementInterfaceId = true && that.isSetDataMovementInterfaceId();
    if (this_present_dataMovementInterfaceId || that_present_dataMovementInterfaceId) {
      if (!(this_present_dataMovementInterfaceId && that_present_dataMovementInterfaceId))
        return false;
      if (!this.dataMovementInterfaceId.equals(that.dataMovementInterfaceId))
        return false;
    }

    boolean this_present_dataMovementProtocol = true && this.isSetDataMovementProtocol();
    boolean that_present_dataMovementProtocol = true && that.isSetDataMovementProtocol();
    if (this_present_dataMovementProtocol || that_present_dataMovementProtocol) {
      if (!(this_present_dataMovementProtocol && that_present_dataMovementProtocol))
        return false;
      if (!this.dataMovementProtocol.equals(that.dataMovementProtocol))
        return false;
    }

    boolean this_present_priorityOrder = true;
    boolean that_present_priorityOrder = true;
    if (this_present_priorityOrder || that_present_priorityOrder) {
      if (!(this_present_priorityOrder && that_present_priorityOrder))
        return false;
      if (this.priorityOrder != that.priorityOrder)
        return false;
    }

    boolean this_present_creationTime = true && this.isSetCreationTime();
    boolean that_present_creationTime = true && that.isSetCreationTime();
    if (this_present_creationTime || that_present_creationTime) {
      if (!(this_present_creationTime && that_present_creationTime))
        return false;
      if (this.creationTime != that.creationTime)
        return false;
    }

    boolean this_present_updateTime = true && this.isSetUpdateTime();
    boolean that_present_updateTime = true && that.isSetUpdateTime();
    if (this_present_updateTime || that_present_updateTime) {
      if (!(this_present_updateTime && that_present_updateTime))
        return false;
      if (this.updateTime != that.updateTime)
        return false;
    }

    boolean this_present_storageResourceId = true && this.isSetStorageResourceId();
    boolean that_present_storageResourceId = true && that.isSetStorageResourceId();
    if (this_present_storageResourceId || that_present_storageResourceId) {
      if (!(this_present_storageResourceId && that_present_storageResourceId))
        return false;
      if (!this.storageResourceId.equals(that.storageResourceId))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetDataMovementInterfaceId()) ? 131071 : 524287);
    if (isSetDataMovementInterfaceId())
      hashCode = hashCode * 8191 + dataMovementInterfaceId.hashCode();

    hashCode = hashCode * 8191 + ((isSetDataMovementProtocol()) ? 131071 : 524287);
    if (isSetDataMovementProtocol())
      hashCode = hashCode * 8191 + dataMovementProtocol.getValue();

    hashCode = hashCode * 8191 + priorityOrder;

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

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

    hashCode = hashCode * 8191 + ((isSetStorageResourceId()) ? 131071 : 524287);
    if (isSetStorageResourceId())
      hashCode = hashCode * 8191 + storageResourceId.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetDataMovementInterfaceId()).compareTo(other.isSetDataMovementInterfaceId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDataMovementInterfaceId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementInterfaceId, other.dataMovementInterfaceId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetDataMovementProtocol()).compareTo(other.isSetDataMovementProtocol());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDataMovementProtocol()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementProtocol, other.dataMovementProtocol);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetPriorityOrder()).compareTo(other.isSetPriorityOrder());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPriorityOrder()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priorityOrder, other.priorityOrder);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCreationTime()).compareTo(other.isSetCreationTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCreationTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.creationTime, other.creationTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetUpdateTime()).compareTo(other.isSetUpdateTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUpdateTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updateTime, other.updateTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetStorageResourceId()).compareTo(other.isSetStorageResourceId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStorageResourceId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storageResourceId, other.storageResourceId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

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

  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("DataMovementInterface(");
    boolean first = true;

    sb.append("dataMovementInterfaceId:");
    if (this.dataMovementInterfaceId == null) {
      sb.append("null");
    } else {
      sb.append(this.dataMovementInterfaceId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("dataMovementProtocol:");
    if (this.dataMovementProtocol == null) {
      sb.append("null");
    } else {
      sb.append(this.dataMovementProtocol);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("priorityOrder:");
    sb.append(this.priorityOrder);
    first = false;
    if (isSetCreationTime()) {
      if (!first) sb.append(", ");
      sb.append("creationTime:");
      sb.append(this.creationTime);
      first = false;
    }
    if (isSetUpdateTime()) {
      if (!first) sb.append(", ");
      sb.append("updateTime:");
      sb.append(this.updateTime);
      first = false;
    }
    if (isSetStorageResourceId()) {
      if (!first) sb.append(", ");
      sb.append("storageResourceId:");
      if (this.storageResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.storageResourceId);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

    // check for sub-struct validity
  }

  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 DataMovementInterfaceStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public DataMovementInterfaceStandardScheme getScheme() {
      return new DataMovementInterfaceStandardScheme();
    }
  }

  private static class DataMovementInterfaceStandardScheme extends org.apache.thrift.scheme.StandardScheme<DataMovementInterface> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, DataMovementInterface 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: // DATA_MOVEMENT_INTERFACE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.dataMovementInterfaceId = iprot.readString();
              struct.setDataMovementInterfaceIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // DATA_MOVEMENT_PROTOCOL
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.dataMovementProtocol = org.apache.airavata.model.data.movement.DataMovementProtocol.findByValue(iprot.readI32());
              struct.setDataMovementProtocolIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // PRIORITY_ORDER
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.priorityOrder = iprot.readI32();
              struct.setPriorityOrderIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // CREATION_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.creationTime = iprot.readI64();
              struct.setCreationTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // UPDATE_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.updateTime = iprot.readI64();
              struct.setUpdateTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // STORAGE_RESOURCE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.storageResourceId = iprot.readString();
              struct.setStorageResourceIdIsSet(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();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.dataMovementInterfaceId != null) {
        oprot.writeFieldBegin(DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC);
        oprot.writeString(struct.dataMovementInterfaceId);
        oprot.writeFieldEnd();
      }
      if (struct.dataMovementProtocol != null) {
        oprot.writeFieldBegin(DATA_MOVEMENT_PROTOCOL_FIELD_DESC);
        oprot.writeI32(struct.dataMovementProtocol.getValue());
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(PRIORITY_ORDER_FIELD_DESC);
      oprot.writeI32(struct.priorityOrder);
      oprot.writeFieldEnd();
      if (struct.isSetCreationTime()) {
        oprot.writeFieldBegin(CREATION_TIME_FIELD_DESC);
        oprot.writeI64(struct.creationTime);
        oprot.writeFieldEnd();
      }
      if (struct.isSetUpdateTime()) {
        oprot.writeFieldBegin(UPDATE_TIME_FIELD_DESC);
        oprot.writeI64(struct.updateTime);
        oprot.writeFieldEnd();
      }
      if (struct.storageResourceId != null) {
        if (struct.isSetStorageResourceId()) {
          oprot.writeFieldBegin(STORAGE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.storageResourceId);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class DataMovementInterfaceTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public DataMovementInterfaceTupleScheme getScheme() {
      return new DataMovementInterfaceTupleScheme();
    }
  }

  private static class DataMovementInterfaceTupleScheme extends org.apache.thrift.scheme.TupleScheme<DataMovementInterface> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, DataMovementInterface struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.dataMovementInterfaceId);
      oprot.writeI32(struct.dataMovementProtocol.getValue());
      oprot.writeI32(struct.priorityOrder);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetCreationTime()) {
        optionals.set(0);
      }
      if (struct.isSetUpdateTime()) {
        optionals.set(1);
      }
      if (struct.isSetStorageResourceId()) {
        optionals.set(2);
      }
      oprot.writeBitSet(optionals, 3);
      if (struct.isSetCreationTime()) {
        oprot.writeI64(struct.creationTime);
      }
      if (struct.isSetUpdateTime()) {
        oprot.writeI64(struct.updateTime);
      }
      if (struct.isSetStorageResourceId()) {
        oprot.writeString(struct.storageResourceId);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, DataMovementInterface struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.dataMovementInterfaceId = iprot.readString();
      struct.setDataMovementInterfaceIdIsSet(true);
      struct.dataMovementProtocol = org.apache.airavata.model.data.movement.DataMovementProtocol.findByValue(iprot.readI32());
      struct.setDataMovementProtocolIsSet(true);
      struct.priorityOrder = iprot.readI32();
      struct.setPriorityOrderIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(3);
      if (incoming.get(0)) {
        struct.creationTime = iprot.readI64();
        struct.setCreationTimeIsSet(true);
      }
      if (incoming.get(1)) {
        struct.updateTime = iprot.readI64();
        struct.setUpdateTimeIsSet(true);
      }
      if (incoming.get(2)) {
        struct.storageResourceId = iprot.readString();
        struct.setStorageResourceIdIsSet(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();
  }
}

