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

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import javax.annotation.Generated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
/**
 * Application Outputs. The paramters describe how outputs generated by the application.
 * 
 * name:
 *   Name of the parameter.
 * 
 * value:
 *   Value of the parameter.
 * 
 * type:
 *   Data type of the parameter
 * 
 * applicationArguement:
 *   The argument flag sent to the application. Such as -p pressure.
 * 
 * standardInput:
 *   When this value is set, the parameter is sent as standard input rather than a parameter.
 *   Typically this is passed using redirection operator ">".
 * 
 * userFriendlyDescription:
 *   Description to be displayed at the user interface.
 * 
 * metaData:
 *   Any metadat. This is typically ignore by Airavata and is used by gateways for application configuration.
 * 
 */
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
public class OutputDataObjectType implements org.apache.thrift.TBase<OutputDataObjectType, OutputDataObjectType._Fields>, java.io.Serializable, Cloneable, Comparable<OutputDataObjectType> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("OutputDataObjectType");

  private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", 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 APPLICATION_ARGUMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationArgument", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField IS_REQUIRED_FIELD_DESC = new org.apache.thrift.protocol.TField("isRequired", org.apache.thrift.protocol.TType.BOOL, (short)5);
  private static final org.apache.thrift.protocol.TField REQUIRED_TO_ADDED_TO_COMMAND_LINE_FIELD_DESC = new org.apache.thrift.protocol.TField("requiredToAddedToCommandLine", org.apache.thrift.protocol.TType.BOOL, (short)6);
  private static final org.apache.thrift.protocol.TField DATA_MOVEMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovement", org.apache.thrift.protocol.TType.BOOL, (short)7);
  private static final org.apache.thrift.protocol.TField LOCATION_FIELD_DESC = new org.apache.thrift.protocol.TField("location", org.apache.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.thrift.protocol.TField SEARCH_QUERY_FIELD_DESC = new org.apache.thrift.protocol.TField("searchQuery", org.apache.thrift.protocol.TType.STRING, (short)9);
  private static final org.apache.thrift.protocol.TField OUTPUT_STREAMING_FIELD_DESC = new org.apache.thrift.protocol.TField("outputStreaming", org.apache.thrift.protocol.TType.BOOL, (short)10);
  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)11);

  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
  static {
    schemes.put(StandardScheme.class, new OutputDataObjectTypeStandardSchemeFactory());
    schemes.put(TupleScheme.class, new OutputDataObjectTypeTupleSchemeFactory());
  }

  private String name; // required
  private String value; // optional
  private DataType type; // optional
  private String applicationArgument; // optional
  private boolean isRequired; // optional
  private boolean requiredToAddedToCommandLine; // optional
  private boolean dataMovement; // optional
  private String location; // optional
  private String searchQuery; // optional
  private boolean outputStreaming; // optional
  private 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 {
    NAME((short)1, "name"),
    VALUE((short)2, "value"),
    /**
     * 
     * @see DataType
     */
    TYPE((short)3, "type"),
    APPLICATION_ARGUMENT((short)4, "applicationArgument"),
    IS_REQUIRED((short)5, "isRequired"),
    REQUIRED_TO_ADDED_TO_COMMAND_LINE((short)6, "requiredToAddedToCommandLine"),
    DATA_MOVEMENT((short)7, "dataMovement"),
    LOCATION((short)8, "location"),
    SEARCH_QUERY((short)9, "searchQuery"),
    OUTPUT_STREAMING((short)10, "outputStreaming"),
    STORAGE_RESOURCE_ID((short)11, "storageResourceId");

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

    static {
      for (_Fields field : 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: // NAME
          return NAME;
        case 2: // VALUE
          return VALUE;
        case 3: // TYPE
          return TYPE;
        case 4: // APPLICATION_ARGUMENT
          return APPLICATION_ARGUMENT;
        case 5: // IS_REQUIRED
          return IS_REQUIRED;
        case 6: // REQUIRED_TO_ADDED_TO_COMMAND_LINE
          return REQUIRED_TO_ADDED_TO_COMMAND_LINE;
        case 7: // DATA_MOVEMENT
          return DATA_MOVEMENT;
        case 8: // LOCATION
          return LOCATION;
        case 9: // SEARCH_QUERY
          return SEARCH_QUERY;
        case 10: // OUTPUT_STREAMING
          return OUTPUT_STREAMING;
        case 11: // 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 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(String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __ISREQUIRED_ISSET_ID = 0;
  private static final int __REQUIREDTOADDEDTOCOMMANDLINE_ISSET_ID = 1;
  private static final int __DATAMOVEMENT_ISSET_ID = 2;
  private static final int __OUTPUTSTREAMING_ISSET_ID = 3;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.VALUE,_Fields.TYPE,_Fields.APPLICATION_ARGUMENT,_Fields.IS_REQUIRED,_Fields.REQUIRED_TO_ADDED_TO_COMMAND_LINE,_Fields.DATA_MOVEMENT,_Fields.LOCATION,_Fields.SEARCH_QUERY,_Fields.OUTPUT_STREAMING,_Fields.STORAGE_RESOURCE_ID};
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        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.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, DataType.class)));
    tmpMap.put(_Fields.APPLICATION_ARGUMENT, new org.apache.thrift.meta_data.FieldMetaData("applicationArgument", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.IS_REQUIRED, new org.apache.thrift.meta_data.FieldMetaData("isRequired", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.REQUIRED_TO_ADDED_TO_COMMAND_LINE, new org.apache.thrift.meta_data.FieldMetaData("requiredToAddedToCommandLine", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.DATA_MOVEMENT, new org.apache.thrift.meta_data.FieldMetaData("dataMovement", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.LOCATION, new org.apache.thrift.meta_data.FieldMetaData("location", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.SEARCH_QUERY, new org.apache.thrift.meta_data.FieldMetaData("searchQuery", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.OUTPUT_STREAMING, new org.apache.thrift.meta_data.FieldMetaData("outputStreaming", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    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 = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(OutputDataObjectType.class, metaDataMap);
  }

  public OutputDataObjectType() {
  }

  public OutputDataObjectType(
    String name)
  {
    this();
    this.name = name;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public OutputDataObjectType(OutputDataObjectType other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetName()) {
      this.name = other.name;
    }
    if (other.isSetValue()) {
      this.value = other.value;
    }
    if (other.isSetType()) {
      this.type = other.type;
    }
    if (other.isSetApplicationArgument()) {
      this.applicationArgument = other.applicationArgument;
    }
    this.isRequired = other.isRequired;
    this.requiredToAddedToCommandLine = other.requiredToAddedToCommandLine;
    this.dataMovement = other.dataMovement;
    if (other.isSetLocation()) {
      this.location = other.location;
    }
    if (other.isSetSearchQuery()) {
      this.searchQuery = other.searchQuery;
    }
    this.outputStreaming = other.outputStreaming;
    if (other.isSetStorageResourceId()) {
      this.storageResourceId = other.storageResourceId;
    }
  }

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

  @Override
  public void clear() {
    this.name = null;
    this.value = null;
    this.type = null;
    this.applicationArgument = null;
    setIsRequiredIsSet(false);
    this.isRequired = false;
    setRequiredToAddedToCommandLineIsSet(false);
    this.requiredToAddedToCommandLine = false;
    setDataMovementIsSet(false);
    this.dataMovement = false;
    this.location = null;
    this.searchQuery = null;
    setOutputStreamingIsSet(false);
    this.outputStreaming = false;
    this.storageResourceId = null;
  }

  public String getName() {
    return this.name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public void unsetName() {
    this.name = null;
  }

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

  public void setNameIsSet(boolean value) {
    if (!value) {
      this.name = null;
    }
  }

  public String getValue() {
    return this.value;
  }

  public void setValue(String value) {
    this.value = value;
  }

  public void unsetValue() {
    this.value = null;
  }

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

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

  /**
   * 
   * @see DataType
   */
  public DataType getType() {
    return this.type;
  }

  /**
   * 
   * @see DataType
   */
  public void setType(DataType 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 String getApplicationArgument() {
    return this.applicationArgument;
  }

  public void setApplicationArgument(String applicationArgument) {
    this.applicationArgument = applicationArgument;
  }

  public void unsetApplicationArgument() {
    this.applicationArgument = null;
  }

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

  public void setApplicationArgumentIsSet(boolean value) {
    if (!value) {
      this.applicationArgument = null;
    }
  }

  public boolean isIsRequired() {
    return this.isRequired;
  }

  public void setIsRequired(boolean isRequired) {
    this.isRequired = isRequired;
    setIsRequiredIsSet(true);
  }

  public void unsetIsRequired() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ISREQUIRED_ISSET_ID);
  }

  /** Returns true if field isRequired is set (has been assigned a value) and false otherwise */
  public boolean isSetIsRequired() {
    return EncodingUtils.testBit(__isset_bitfield, __ISREQUIRED_ISSET_ID);
  }

  public void setIsRequiredIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ISREQUIRED_ISSET_ID, value);
  }

  public boolean isRequiredToAddedToCommandLine() {
    return this.requiredToAddedToCommandLine;
  }

  public void setRequiredToAddedToCommandLine(boolean requiredToAddedToCommandLine) {
    this.requiredToAddedToCommandLine = requiredToAddedToCommandLine;
    setRequiredToAddedToCommandLineIsSet(true);
  }

  public void unsetRequiredToAddedToCommandLine() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __REQUIREDTOADDEDTOCOMMANDLINE_ISSET_ID);
  }

  /** Returns true if field requiredToAddedToCommandLine is set (has been assigned a value) and false otherwise */
  public boolean isSetRequiredToAddedToCommandLine() {
    return EncodingUtils.testBit(__isset_bitfield, __REQUIREDTOADDEDTOCOMMANDLINE_ISSET_ID);
  }

  public void setRequiredToAddedToCommandLineIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __REQUIREDTOADDEDTOCOMMANDLINE_ISSET_ID, value);
  }

  public boolean isDataMovement() {
    return this.dataMovement;
  }

  public void setDataMovement(boolean dataMovement) {
    this.dataMovement = dataMovement;
    setDataMovementIsSet(true);
  }

  public void unsetDataMovement() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __DATAMOVEMENT_ISSET_ID);
  }

  /** Returns true if field dataMovement is set (has been assigned a value) and false otherwise */
  public boolean isSetDataMovement() {
    return EncodingUtils.testBit(__isset_bitfield, __DATAMOVEMENT_ISSET_ID);
  }

  public void setDataMovementIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __DATAMOVEMENT_ISSET_ID, value);
  }

  public String getLocation() {
    return this.location;
  }

  public void setLocation(String location) {
    this.location = location;
  }

  public void unsetLocation() {
    this.location = null;
  }

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

  public void setLocationIsSet(boolean value) {
    if (!value) {
      this.location = null;
    }
  }

  public String getSearchQuery() {
    return this.searchQuery;
  }

  public void setSearchQuery(String searchQuery) {
    this.searchQuery = searchQuery;
  }

  public void unsetSearchQuery() {
    this.searchQuery = null;
  }

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

  public void setSearchQueryIsSet(boolean value) {
    if (!value) {
      this.searchQuery = null;
    }
  }

  public boolean isOutputStreaming() {
    return this.outputStreaming;
  }

  public void setOutputStreaming(boolean outputStreaming) {
    this.outputStreaming = outputStreaming;
    setOutputStreamingIsSet(true);
  }

  public void unsetOutputStreaming() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OUTPUTSTREAMING_ISSET_ID);
  }

  /** Returns true if field outputStreaming is set (has been assigned a value) and false otherwise */
  public boolean isSetOutputStreaming() {
    return EncodingUtils.testBit(__isset_bitfield, __OUTPUTSTREAMING_ISSET_ID);
  }

  public void setOutputStreamingIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OUTPUTSTREAMING_ISSET_ID, value);
  }

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

  public void setStorageResourceId(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, Object value) {
    switch (field) {
    case NAME:
      if (value == null) {
        unsetName();
      } else {
        setName((String)value);
      }
      break;

    case VALUE:
      if (value == null) {
        unsetValue();
      } else {
        setValue((String)value);
      }
      break;

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

    case APPLICATION_ARGUMENT:
      if (value == null) {
        unsetApplicationArgument();
      } else {
        setApplicationArgument((String)value);
      }
      break;

    case IS_REQUIRED:
      if (value == null) {
        unsetIsRequired();
      } else {
        setIsRequired((Boolean)value);
      }
      break;

    case REQUIRED_TO_ADDED_TO_COMMAND_LINE:
      if (value == null) {
        unsetRequiredToAddedToCommandLine();
      } else {
        setRequiredToAddedToCommandLine((Boolean)value);
      }
      break;

    case DATA_MOVEMENT:
      if (value == null) {
        unsetDataMovement();
      } else {
        setDataMovement((Boolean)value);
      }
      break;

    case LOCATION:
      if (value == null) {
        unsetLocation();
      } else {
        setLocation((String)value);
      }
      break;

    case SEARCH_QUERY:
      if (value == null) {
        unsetSearchQuery();
      } else {
        setSearchQuery((String)value);
      }
      break;

    case OUTPUT_STREAMING:
      if (value == null) {
        unsetOutputStreaming();
      } else {
        setOutputStreaming((Boolean)value);
      }
      break;

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

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case NAME:
      return getName();

    case VALUE:
      return getValue();

    case TYPE:
      return getType();

    case APPLICATION_ARGUMENT:
      return getApplicationArgument();

    case IS_REQUIRED:
      return isIsRequired();

    case REQUIRED_TO_ADDED_TO_COMMAND_LINE:
      return isRequiredToAddedToCommandLine();

    case DATA_MOVEMENT:
      return isDataMovement();

    case LOCATION:
      return getLocation();

    case SEARCH_QUERY:
      return getSearchQuery();

    case OUTPUT_STREAMING:
      return isOutputStreaming();

    case STORAGE_RESOURCE_ID:
      return getStorageResourceId();

    }
    throw new 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 IllegalArgumentException();
    }

    switch (field) {
    case NAME:
      return isSetName();
    case VALUE:
      return isSetValue();
    case TYPE:
      return isSetType();
    case APPLICATION_ARGUMENT:
      return isSetApplicationArgument();
    case IS_REQUIRED:
      return isSetIsRequired();
    case REQUIRED_TO_ADDED_TO_COMMAND_LINE:
      return isSetRequiredToAddedToCommandLine();
    case DATA_MOVEMENT:
      return isSetDataMovement();
    case LOCATION:
      return isSetLocation();
    case SEARCH_QUERY:
      return isSetSearchQuery();
    case OUTPUT_STREAMING:
      return isSetOutputStreaming();
    case STORAGE_RESOURCE_ID:
      return isSetStorageResourceId();
    }
    throw new IllegalStateException();
  }

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

  public boolean equals(OutputDataObjectType that) {
    if (that == null)
      return false;

    boolean this_present_name = true && this.isSetName();
    boolean that_present_name = true && that.isSetName();
    if (this_present_name || that_present_name) {
      if (!(this_present_name && that_present_name))
        return false;
      if (!this.name.equals(that.name))
        return false;
    }

    boolean this_present_value = true && this.isSetValue();
    boolean that_present_value = true && that.isSetValue();
    if (this_present_value || that_present_value) {
      if (!(this_present_value && that_present_value))
        return false;
      if (!this.value.equals(that.value))
        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_applicationArgument = true && this.isSetApplicationArgument();
    boolean that_present_applicationArgument = true && that.isSetApplicationArgument();
    if (this_present_applicationArgument || that_present_applicationArgument) {
      if (!(this_present_applicationArgument && that_present_applicationArgument))
        return false;
      if (!this.applicationArgument.equals(that.applicationArgument))
        return false;
    }

    boolean this_present_isRequired = true && this.isSetIsRequired();
    boolean that_present_isRequired = true && that.isSetIsRequired();
    if (this_present_isRequired || that_present_isRequired) {
      if (!(this_present_isRequired && that_present_isRequired))
        return false;
      if (this.isRequired != that.isRequired)
        return false;
    }

    boolean this_present_requiredToAddedToCommandLine = true && this.isSetRequiredToAddedToCommandLine();
    boolean that_present_requiredToAddedToCommandLine = true && that.isSetRequiredToAddedToCommandLine();
    if (this_present_requiredToAddedToCommandLine || that_present_requiredToAddedToCommandLine) {
      if (!(this_present_requiredToAddedToCommandLine && that_present_requiredToAddedToCommandLine))
        return false;
      if (this.requiredToAddedToCommandLine != that.requiredToAddedToCommandLine)
        return false;
    }

    boolean this_present_dataMovement = true && this.isSetDataMovement();
    boolean that_present_dataMovement = true && that.isSetDataMovement();
    if (this_present_dataMovement || that_present_dataMovement) {
      if (!(this_present_dataMovement && that_present_dataMovement))
        return false;
      if (this.dataMovement != that.dataMovement)
        return false;
    }

    boolean this_present_location = true && this.isSetLocation();
    boolean that_present_location = true && that.isSetLocation();
    if (this_present_location || that_present_location) {
      if (!(this_present_location && that_present_location))
        return false;
      if (!this.location.equals(that.location))
        return false;
    }

    boolean this_present_searchQuery = true && this.isSetSearchQuery();
    boolean that_present_searchQuery = true && that.isSetSearchQuery();
    if (this_present_searchQuery || that_present_searchQuery) {
      if (!(this_present_searchQuery && that_present_searchQuery))
        return false;
      if (!this.searchQuery.equals(that.searchQuery))
        return false;
    }

    boolean this_present_outputStreaming = true && this.isSetOutputStreaming();
    boolean that_present_outputStreaming = true && that.isSetOutputStreaming();
    if (this_present_outputStreaming || that_present_outputStreaming) {
      if (!(this_present_outputStreaming && that_present_outputStreaming))
        return false;
      if (this.outputStreaming != that.outputStreaming)
        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() {
    List<Object> list = new ArrayList<Object>();

    boolean present_name = true && (isSetName());
    list.add(present_name);
    if (present_name)
      list.add(name);

    boolean present_value = true && (isSetValue());
    list.add(present_value);
    if (present_value)
      list.add(value);

    boolean present_type = true && (isSetType());
    list.add(present_type);
    if (present_type)
      list.add(type.getValue());

    boolean present_applicationArgument = true && (isSetApplicationArgument());
    list.add(present_applicationArgument);
    if (present_applicationArgument)
      list.add(applicationArgument);

    boolean present_isRequired = true && (isSetIsRequired());
    list.add(present_isRequired);
    if (present_isRequired)
      list.add(isRequired);

    boolean present_requiredToAddedToCommandLine = true && (isSetRequiredToAddedToCommandLine());
    list.add(present_requiredToAddedToCommandLine);
    if (present_requiredToAddedToCommandLine)
      list.add(requiredToAddedToCommandLine);

    boolean present_dataMovement = true && (isSetDataMovement());
    list.add(present_dataMovement);
    if (present_dataMovement)
      list.add(dataMovement);

    boolean present_location = true && (isSetLocation());
    list.add(present_location);
    if (present_location)
      list.add(location);

    boolean present_searchQuery = true && (isSetSearchQuery());
    list.add(present_searchQuery);
    if (present_searchQuery)
      list.add(searchQuery);

    boolean present_outputStreaming = true && (isSetOutputStreaming());
    list.add(present_outputStreaming);
    if (present_outputStreaming)
      list.add(outputStreaming);

    boolean present_storageResourceId = true && (isSetStorageResourceId());
    list.add(present_storageResourceId);
    if (present_storageResourceId)
      list.add(storageResourceId);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetValue()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, other.value);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetType()).compareTo(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 = Boolean.valueOf(isSetApplicationArgument()).compareTo(other.isSetApplicationArgument());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationArgument()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationArgument, other.applicationArgument);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetIsRequired()).compareTo(other.isSetIsRequired());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetIsRequired()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.isRequired, other.isRequired);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetRequiredToAddedToCommandLine()).compareTo(other.isSetRequiredToAddedToCommandLine());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetRequiredToAddedToCommandLine()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.requiredToAddedToCommandLine, other.requiredToAddedToCommandLine);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetDataMovement()).compareTo(other.isSetDataMovement());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDataMovement()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovement, other.dataMovement);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetLocation()).compareTo(other.isSetLocation());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetLocation()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.location, other.location);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetSearchQuery()).compareTo(other.isSetSearchQuery());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSearchQuery()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.searchQuery, other.searchQuery);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetOutputStreaming()).compareTo(other.isSetOutputStreaming());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOutputStreaming()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.outputStreaming, other.outputStreaming);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = 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 {
    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
  }

  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("OutputDataObjectType(");
    boolean first = true;

    sb.append("name:");
    if (this.name == null) {
      sb.append("null");
    } else {
      sb.append(this.name);
    }
    first = false;
    if (isSetValue()) {
      if (!first) sb.append(", ");
      sb.append("value:");
      if (this.value == null) {
        sb.append("null");
      } else {
        sb.append(this.value);
      }
      first = false;
    }
    if (isSetType()) {
      if (!first) sb.append(", ");
      sb.append("type:");
      if (this.type == null) {
        sb.append("null");
      } else {
        sb.append(this.type);
      }
      first = false;
    }
    if (isSetApplicationArgument()) {
      if (!first) sb.append(", ");
      sb.append("applicationArgument:");
      if (this.applicationArgument == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationArgument);
      }
      first = false;
    }
    if (isSetIsRequired()) {
      if (!first) sb.append(", ");
      sb.append("isRequired:");
      sb.append(this.isRequired);
      first = false;
    }
    if (isSetRequiredToAddedToCommandLine()) {
      if (!first) sb.append(", ");
      sb.append("requiredToAddedToCommandLine:");
      sb.append(this.requiredToAddedToCommandLine);
      first = false;
    }
    if (isSetDataMovement()) {
      if (!first) sb.append(", ");
      sb.append("dataMovement:");
      sb.append(this.dataMovement);
      first = false;
    }
    if (isSetLocation()) {
      if (!first) sb.append(", ");
      sb.append("location:");
      if (this.location == null) {
        sb.append("null");
      } else {
        sb.append(this.location);
      }
      first = false;
    }
    if (isSetSearchQuery()) {
      if (!first) sb.append(", ");
      sb.append("searchQuery:");
      if (this.searchQuery == null) {
        sb.append("null");
      } else {
        sb.append(this.searchQuery);
      }
      first = false;
    }
    if (isSetOutputStreaming()) {
      if (!first) sb.append(", ");
      sb.append("outputStreaming:");
      sb.append(this.outputStreaming);
      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 (!isSetName()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'name' 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, 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 OutputDataObjectTypeStandardSchemeFactory implements SchemeFactory {
    public OutputDataObjectTypeStandardScheme getScheme() {
      return new OutputDataObjectTypeStandardScheme();
    }
  }

  private static class OutputDataObjectTypeStandardScheme extends StandardScheme<OutputDataObjectType> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, OutputDataObjectType 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: // NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.name = iprot.readString();
              struct.setNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // VALUE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.value = iprot.readString();
              struct.setValueIsSet(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.application.io.DataType.findByValue(iprot.readI32());
              struct.setTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // APPLICATION_ARGUMENT
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.applicationArgument = iprot.readString();
              struct.setApplicationArgumentIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // IS_REQUIRED
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.isRequired = iprot.readBool();
              struct.setIsRequiredIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // REQUIRED_TO_ADDED_TO_COMMAND_LINE
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.requiredToAddedToCommandLine = iprot.readBool();
              struct.setRequiredToAddedToCommandLineIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // DATA_MOVEMENT
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.dataMovement = iprot.readBool();
              struct.setDataMovementIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // LOCATION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.location = iprot.readString();
              struct.setLocationIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // SEARCH_QUERY
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.searchQuery = iprot.readString();
              struct.setSearchQueryIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // OUTPUT_STREAMING
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.outputStreaming = iprot.readBool();
              struct.setOutputStreamingIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // 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, OutputDataObjectType struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.name != null) {
        oprot.writeFieldBegin(NAME_FIELD_DESC);
        oprot.writeString(struct.name);
        oprot.writeFieldEnd();
      }
      if (struct.value != null) {
        if (struct.isSetValue()) {
          oprot.writeFieldBegin(VALUE_FIELD_DESC);
          oprot.writeString(struct.value);
          oprot.writeFieldEnd();
        }
      }
      if (struct.type != null) {
        if (struct.isSetType()) {
          oprot.writeFieldBegin(TYPE_FIELD_DESC);
          oprot.writeI32(struct.type.getValue());
          oprot.writeFieldEnd();
        }
      }
      if (struct.applicationArgument != null) {
        if (struct.isSetApplicationArgument()) {
          oprot.writeFieldBegin(APPLICATION_ARGUMENT_FIELD_DESC);
          oprot.writeString(struct.applicationArgument);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetIsRequired()) {
        oprot.writeFieldBegin(IS_REQUIRED_FIELD_DESC);
        oprot.writeBool(struct.isRequired);
        oprot.writeFieldEnd();
      }
      if (struct.isSetRequiredToAddedToCommandLine()) {
        oprot.writeFieldBegin(REQUIRED_TO_ADDED_TO_COMMAND_LINE_FIELD_DESC);
        oprot.writeBool(struct.requiredToAddedToCommandLine);
        oprot.writeFieldEnd();
      }
      if (struct.isSetDataMovement()) {
        oprot.writeFieldBegin(DATA_MOVEMENT_FIELD_DESC);
        oprot.writeBool(struct.dataMovement);
        oprot.writeFieldEnd();
      }
      if (struct.location != null) {
        if (struct.isSetLocation()) {
          oprot.writeFieldBegin(LOCATION_FIELD_DESC);
          oprot.writeString(struct.location);
          oprot.writeFieldEnd();
        }
      }
      if (struct.searchQuery != null) {
        if (struct.isSetSearchQuery()) {
          oprot.writeFieldBegin(SEARCH_QUERY_FIELD_DESC);
          oprot.writeString(struct.searchQuery);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetOutputStreaming()) {
        oprot.writeFieldBegin(OUTPUT_STREAMING_FIELD_DESC);
        oprot.writeBool(struct.outputStreaming);
        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 OutputDataObjectTypeTupleSchemeFactory implements SchemeFactory {
    public OutputDataObjectTypeTupleScheme getScheme() {
      return new OutputDataObjectTypeTupleScheme();
    }
  }

  private static class OutputDataObjectTypeTupleScheme extends TupleScheme<OutputDataObjectType> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, OutputDataObjectType struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.name);
      BitSet optionals = new BitSet();
      if (struct.isSetValue()) {
        optionals.set(0);
      }
      if (struct.isSetType()) {
        optionals.set(1);
      }
      if (struct.isSetApplicationArgument()) {
        optionals.set(2);
      }
      if (struct.isSetIsRequired()) {
        optionals.set(3);
      }
      if (struct.isSetRequiredToAddedToCommandLine()) {
        optionals.set(4);
      }
      if (struct.isSetDataMovement()) {
        optionals.set(5);
      }
      if (struct.isSetLocation()) {
        optionals.set(6);
      }
      if (struct.isSetSearchQuery()) {
        optionals.set(7);
      }
      if (struct.isSetOutputStreaming()) {
        optionals.set(8);
      }
      if (struct.isSetStorageResourceId()) {
        optionals.set(9);
      }
      oprot.writeBitSet(optionals, 10);
      if (struct.isSetValue()) {
        oprot.writeString(struct.value);
      }
      if (struct.isSetType()) {
        oprot.writeI32(struct.type.getValue());
      }
      if (struct.isSetApplicationArgument()) {
        oprot.writeString(struct.applicationArgument);
      }
      if (struct.isSetIsRequired()) {
        oprot.writeBool(struct.isRequired);
      }
      if (struct.isSetRequiredToAddedToCommandLine()) {
        oprot.writeBool(struct.requiredToAddedToCommandLine);
      }
      if (struct.isSetDataMovement()) {
        oprot.writeBool(struct.dataMovement);
      }
      if (struct.isSetLocation()) {
        oprot.writeString(struct.location);
      }
      if (struct.isSetSearchQuery()) {
        oprot.writeString(struct.searchQuery);
      }
      if (struct.isSetOutputStreaming()) {
        oprot.writeBool(struct.outputStreaming);
      }
      if (struct.isSetStorageResourceId()) {
        oprot.writeString(struct.storageResourceId);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, OutputDataObjectType struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.name = iprot.readString();
      struct.setNameIsSet(true);
      BitSet incoming = iprot.readBitSet(10);
      if (incoming.get(0)) {
        struct.value = iprot.readString();
        struct.setValueIsSet(true);
      }
      if (incoming.get(1)) {
        struct.type = org.apache.airavata.model.application.io.DataType.findByValue(iprot.readI32());
        struct.setTypeIsSet(true);
      }
      if (incoming.get(2)) {
        struct.applicationArgument = iprot.readString();
        struct.setApplicationArgumentIsSet(true);
      }
      if (incoming.get(3)) {
        struct.isRequired = iprot.readBool();
        struct.setIsRequiredIsSet(true);
      }
      if (incoming.get(4)) {
        struct.requiredToAddedToCommandLine = iprot.readBool();
        struct.setRequiredToAddedToCommandLineIsSet(true);
      }
      if (incoming.get(5)) {
        struct.dataMovement = iprot.readBool();
        struct.setDataMovementIsSet(true);
      }
      if (incoming.get(6)) {
        struct.location = iprot.readString();
        struct.setLocationIsSet(true);
      }
      if (incoming.get(7)) {
        struct.searchQuery = iprot.readString();
        struct.setSearchQueryIsSet(true);
      }
      if (incoming.get(8)) {
        struct.outputStreaming = iprot.readBool();
        struct.setOutputStreamingIsSet(true);
      }
      if (incoming.get(9)) {
        struct.storageResourceId = iprot.readString();
        struct.setStorageResourceIdIsSet(true);
      }
    }
  }

}

