/**
 * Autogenerated by Thrift Compiler (1.0.0-dev)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.datacat.models.Messaging;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.protocol.TTupleProtocol;
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 javax.annotation.Generated;
import java.util.*;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (1.0.0-dev)", date = "2015-2-3")
public class ExperimentOutputCreatedEvent implements org.apache.thrift.TBase<ExperimentOutputCreatedEvent, ExperimentOutputCreatedEvent._Fields>, java.io.Serializable, Cloneable, Comparable<ExperimentOutputCreatedEvent> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ExperimentOutputCreatedEvent");

  private static final org.apache.thrift.protocol.TField EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField EXPERIMENT_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentName", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField OUTPUT_PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("outputPath", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField OWNER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("ownerId", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField GATEWAY_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayName", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationName", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField HOST_FIELD_DESC = new org.apache.thrift.protocol.TField("host", org.apache.thrift.protocol.TType.STRING, (short)7);

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

  public String experimentId; // required
  public String experimentName; // required
  public String outputPath; // required
  public String ownerId; // required
  public String gatewayName; // required
  public String applicationName; // required
  public String host; // required

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    EXPERIMENT_ID((short)1, "experimentId"),
    EXPERIMENT_NAME((short)2, "experimentName"),
    OUTPUT_PATH((short)3, "outputPath"),
    OWNER_ID((short)4, "ownerId"),
    GATEWAY_NAME((short)5, "gatewayName"),
    APPLICATION_NAME((short)6, "applicationName"),
    HOST((short)7, "host");

    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: // EXPERIMENT_ID
          return EXPERIMENT_ID;
        case 2: // EXPERIMENT_NAME
          return EXPERIMENT_NAME;
        case 3: // OUTPUT_PATH
          return OUTPUT_PATH;
        case 4: // OWNER_ID
          return OWNER_ID;
        case 5: // GATEWAY_NAME
          return GATEWAY_NAME;
        case 6: // APPLICATION_NAME
          return APPLICATION_NAME;
        case 7: // HOST
          return HOST;
        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
  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.EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("experimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.EXPERIMENT_NAME, new org.apache.thrift.meta_data.FieldMetaData("experimentName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.OUTPUT_PATH, new org.apache.thrift.meta_data.FieldMetaData("outputPath", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.OWNER_ID, new org.apache.thrift.meta_data.FieldMetaData("ownerId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.GATEWAY_NAME, new org.apache.thrift.meta_data.FieldMetaData("gatewayName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("applicationName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.HOST, new org.apache.thrift.meta_data.FieldMetaData("host", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ExperimentOutputCreatedEvent.class, metaDataMap);
  }

  public ExperimentOutputCreatedEvent() {
  }

  public ExperimentOutputCreatedEvent(
          String experimentId,
          String experimentName,
          String outputPath,
          String ownerId,
          String gatewayName,
          String applicationName,
          String host)
  {
    this();
    this.experimentId = experimentId;
    this.experimentName = experimentName;
    this.outputPath = outputPath;
    this.ownerId = ownerId;
    this.gatewayName = gatewayName;
    this.applicationName = applicationName;
    this.host = host;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ExperimentOutputCreatedEvent(ExperimentOutputCreatedEvent other) {
    if (other.isSetExperimentId()) {
      this.experimentId = other.experimentId;
    }
    if (other.isSetExperimentName()) {
      this.experimentName = other.experimentName;
    }
    if (other.isSetOutputPath()) {
      this.outputPath = other.outputPath;
    }
    if (other.isSetOwnerId()) {
      this.ownerId = other.ownerId;
    }
    if (other.isSetGatewayName()) {
      this.gatewayName = other.gatewayName;
    }
    if (other.isSetApplicationName()) {
      this.applicationName = other.applicationName;
    }
    if (other.isSetHost()) {
      this.host = other.host;
    }
  }

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

  @Override
  public void clear() {
    this.experimentId = null;
    this.experimentName = null;
    this.outputPath = null;
    this.ownerId = null;
    this.gatewayName = null;
    this.applicationName = null;
    this.host = null;
  }

  public String getExperimentId() {
    return this.experimentId;
  }

  public ExperimentOutputCreatedEvent setExperimentId(String experimentId) {
    this.experimentId = experimentId;
    return this;
  }

  public void unsetExperimentId() {
    this.experimentId = null;
  }

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

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

  public String getExperimentName() {
    return this.experimentName;
  }

  public ExperimentOutputCreatedEvent setExperimentName(String experimentName) {
    this.experimentName = experimentName;
    return this;
  }

  public void unsetExperimentName() {
    this.experimentName = null;
  }

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

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

  public String getOutputPath() {
    return this.outputPath;
  }

  public ExperimentOutputCreatedEvent setOutputPath(String outputPath) {
    this.outputPath = outputPath;
    return this;
  }

  public void unsetOutputPath() {
    this.outputPath = null;
  }

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

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

  public String getOwnerId() {
    return this.ownerId;
  }

  public ExperimentOutputCreatedEvent setOwnerId(String ownerId) {
    this.ownerId = ownerId;
    return this;
  }

  public void unsetOwnerId() {
    this.ownerId = null;
  }

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

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

  public String getGatewayName() {
    return this.gatewayName;
  }

  public ExperimentOutputCreatedEvent setGatewayName(String gatewayName) {
    this.gatewayName = gatewayName;
    return this;
  }

  public void unsetGatewayName() {
    this.gatewayName = null;
  }

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

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

  public String getApplicationName() {
    return this.applicationName;
  }

  public ExperimentOutputCreatedEvent setApplicationName(String applicationName) {
    this.applicationName = applicationName;
    return this;
  }

  public void unsetApplicationName() {
    this.applicationName = null;
  }

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

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

  public String getHost() {
    return this.host;
  }

  public ExperimentOutputCreatedEvent setHost(String host) {
    this.host = host;
    return this;
  }

  public void unsetHost() {
    this.host = null;
  }

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

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

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case EXPERIMENT_ID:
      if (value == null) {
        unsetExperimentId();
      } else {
        setExperimentId((String)value);
      }
      break;

    case EXPERIMENT_NAME:
      if (value == null) {
        unsetExperimentName();
      } else {
        setExperimentName((String)value);
      }
      break;

    case OUTPUT_PATH:
      if (value == null) {
        unsetOutputPath();
      } else {
        setOutputPath((String)value);
      }
      break;

    case OWNER_ID:
      if (value == null) {
        unsetOwnerId();
      } else {
        setOwnerId((String)value);
      }
      break;

    case GATEWAY_NAME:
      if (value == null) {
        unsetGatewayName();
      } else {
        setGatewayName((String)value);
      }
      break;

    case APPLICATION_NAME:
      if (value == null) {
        unsetApplicationName();
      } else {
        setApplicationName((String)value);
      }
      break;

    case HOST:
      if (value == null) {
        unsetHost();
      } else {
        setHost((String)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case EXPERIMENT_ID:
      return getExperimentId();

    case EXPERIMENT_NAME:
      return getExperimentName();

    case OUTPUT_PATH:
      return getOutputPath();

    case OWNER_ID:
      return getOwnerId();

    case GATEWAY_NAME:
      return getGatewayName();

    case APPLICATION_NAME:
      return getApplicationName();

    case HOST:
      return getHost();

    }
    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 EXPERIMENT_ID:
      return isSetExperimentId();
    case EXPERIMENT_NAME:
      return isSetExperimentName();
    case OUTPUT_PATH:
      return isSetOutputPath();
    case OWNER_ID:
      return isSetOwnerId();
    case GATEWAY_NAME:
      return isSetGatewayName();
    case APPLICATION_NAME:
      return isSetApplicationName();
    case HOST:
      return isSetHost();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_experimentId = true && this.isSetExperimentId();
    boolean that_present_experimentId = true && that.isSetExperimentId();
    if (this_present_experimentId || that_present_experimentId) {
      if (!(this_present_experimentId && that_present_experimentId))
        return false;
      if (!this.experimentId.equals(that.experimentId))
        return false;
    }

    boolean this_present_experimentName = true && this.isSetExperimentName();
    boolean that_present_experimentName = true && that.isSetExperimentName();
    if (this_present_experimentName || that_present_experimentName) {
      if (!(this_present_experimentName && that_present_experimentName))
        return false;
      if (!this.experimentName.equals(that.experimentName))
        return false;
    }

    boolean this_present_outputPath = true && this.isSetOutputPath();
    boolean that_present_outputPath = true && that.isSetOutputPath();
    if (this_present_outputPath || that_present_outputPath) {
      if (!(this_present_outputPath && that_present_outputPath))
        return false;
      if (!this.outputPath.equals(that.outputPath))
        return false;
    }

    boolean this_present_ownerId = true && this.isSetOwnerId();
    boolean that_present_ownerId = true && that.isSetOwnerId();
    if (this_present_ownerId || that_present_ownerId) {
      if (!(this_present_ownerId && that_present_ownerId))
        return false;
      if (!this.ownerId.equals(that.ownerId))
        return false;
    }

    boolean this_present_gatewayName = true && this.isSetGatewayName();
    boolean that_present_gatewayName = true && that.isSetGatewayName();
    if (this_present_gatewayName || that_present_gatewayName) {
      if (!(this_present_gatewayName && that_present_gatewayName))
        return false;
      if (!this.gatewayName.equals(that.gatewayName))
        return false;
    }

    boolean this_present_applicationName = true && this.isSetApplicationName();
    boolean that_present_applicationName = true && that.isSetApplicationName();
    if (this_present_applicationName || that_present_applicationName) {
      if (!(this_present_applicationName && that_present_applicationName))
        return false;
      if (!this.applicationName.equals(that.applicationName))
        return false;
    }

    boolean this_present_host = true && this.isSetHost();
    boolean that_present_host = true && that.isSetHost();
    if (this_present_host || that_present_host) {
      if (!(this_present_host && that_present_host))
        return false;
      if (!this.host.equals(that.host))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    List<Object> list = new ArrayList<Object>();

    boolean present_experimentId = true && (isSetExperimentId());
    list.add(present_experimentId);
    if (present_experimentId)
      list.add(experimentId);

    boolean present_experimentName = true && (isSetExperimentName());
    list.add(present_experimentName);
    if (present_experimentName)
      list.add(experimentName);

    boolean present_outputPath = true && (isSetOutputPath());
    list.add(present_outputPath);
    if (present_outputPath)
      list.add(outputPath);

    boolean present_ownerId = true && (isSetOwnerId());
    list.add(present_ownerId);
    if (present_ownerId)
      list.add(ownerId);

    boolean present_gatewayName = true && (isSetGatewayName());
    list.add(present_gatewayName);
    if (present_gatewayName)
      list.add(gatewayName);

    boolean present_applicationName = true && (isSetApplicationName());
    list.add(present_applicationName);
    if (present_applicationName)
      list.add(applicationName);

    boolean present_host = true && (isSetHost());
    list.add(present_host);
    if (present_host)
      list.add(host);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetExperimentId()).compareTo(other.isSetExperimentId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExperimentId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentId, other.experimentId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetExperimentName()).compareTo(other.isSetExperimentName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExperimentName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentName, other.experimentName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetOutputPath()).compareTo(other.isSetOutputPath());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOutputPath()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.outputPath, other.outputPath);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetOwnerId()).compareTo(other.isSetOwnerId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOwnerId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ownerId, other.ownerId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetGatewayName()).compareTo(other.isSetGatewayName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGatewayName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayName, other.gatewayName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetApplicationName()).compareTo(other.isSetApplicationName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationName, other.applicationName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetHost()).compareTo(other.isSetHost());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetHost()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.host, other.host);
      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 TException {
    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
  }

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

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

    sb.append("experimentId:");
    if (this.experimentId == null) {
      sb.append("null");
    } else {
      sb.append(this.experimentId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("experimentName:");
    if (this.experimentName == null) {
      sb.append("null");
    } else {
      sb.append(this.experimentName);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("outputPath:");
    if (this.outputPath == null) {
      sb.append("null");
    } else {
      sb.append(this.outputPath);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("ownerId:");
    if (this.ownerId == null) {
      sb.append("null");
    } else {
      sb.append(this.ownerId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("gatewayName:");
    if (this.gatewayName == null) {
      sb.append("null");
    } else {
      sb.append(this.gatewayName);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("applicationName:");
    if (this.applicationName == null) {
      sb.append("null");
    } else {
      sb.append(this.applicationName);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("host:");
    if (this.host == null) {
      sb.append("null");
    } else {
      sb.append(this.host);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws TException {
    // check for required fields
    if (experimentId == null) {
      throw new TProtocolException("Required field 'experimentId' was not present! Struct: " + toString());
    }
    if (experimentName == null) {
      throw new TProtocolException("Required field 'experimentName' was not present! Struct: " + toString());
    }
    if (outputPath == null) {
      throw new TProtocolException("Required field 'outputPath' was not present! Struct: " + toString());
    }
    if (ownerId == null) {
      throw new TProtocolException("Required field 'ownerId' was not present! Struct: " + toString());
    }
    if (gatewayName == null) {
      throw new TProtocolException("Required field 'gatewayName' was not present! Struct: " + toString());
    }
    if (applicationName == null) {
      throw new TProtocolException("Required field 'applicationName' was not present! Struct: " + toString());
    }
    if (host == null) {
      throw new TProtocolException("Required field 'host' was not present! 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 (TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
    try {
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class ExperimentOutputCreatedEventStandardSchemeFactory implements SchemeFactory {
    public ExperimentOutputCreatedEventStandardScheme getScheme() {
      return new ExperimentOutputCreatedEventStandardScheme();
    }
  }

  private static class ExperimentOutputCreatedEventStandardScheme extends StandardScheme<ExperimentOutputCreatedEvent> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, ExperimentOutputCreatedEvent struct) throws 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: // EXPERIMENT_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.experimentId = iprot.readString();
              struct.setExperimentIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // EXPERIMENT_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.experimentName = iprot.readString();
              struct.setExperimentNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // OUTPUT_PATH
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.outputPath = iprot.readString();
              struct.setOutputPathIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // OWNER_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.ownerId = iprot.readString();
              struct.setOwnerIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // GATEWAY_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.gatewayName = iprot.readString();
              struct.setGatewayNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // APPLICATION_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.applicationName = iprot.readString();
              struct.setApplicationNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // HOST
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.host = iprot.readString();
              struct.setHostIsSet(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();

      // check for required fields of primitive type, which can't be checked in the validate method
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.experimentId != null) {
        oprot.writeFieldBegin(EXPERIMENT_ID_FIELD_DESC);
        oprot.writeString(struct.experimentId);
        oprot.writeFieldEnd();
      }
      if (struct.experimentName != null) {
        oprot.writeFieldBegin(EXPERIMENT_NAME_FIELD_DESC);
        oprot.writeString(struct.experimentName);
        oprot.writeFieldEnd();
      }
      if (struct.outputPath != null) {
        oprot.writeFieldBegin(OUTPUT_PATH_FIELD_DESC);
        oprot.writeString(struct.outputPath);
        oprot.writeFieldEnd();
      }
      if (struct.ownerId != null) {
        oprot.writeFieldBegin(OWNER_ID_FIELD_DESC);
        oprot.writeString(struct.ownerId);
        oprot.writeFieldEnd();
      }
      if (struct.gatewayName != null) {
        oprot.writeFieldBegin(GATEWAY_NAME_FIELD_DESC);
        oprot.writeString(struct.gatewayName);
        oprot.writeFieldEnd();
      }
      if (struct.applicationName != null) {
        oprot.writeFieldBegin(APPLICATION_NAME_FIELD_DESC);
        oprot.writeString(struct.applicationName);
        oprot.writeFieldEnd();
      }
      if (struct.host != null) {
        oprot.writeFieldBegin(HOST_FIELD_DESC);
        oprot.writeString(struct.host);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ExperimentOutputCreatedEventTupleSchemeFactory implements SchemeFactory {
    public ExperimentOutputCreatedEventTupleScheme getScheme() {
      return new ExperimentOutputCreatedEventTupleScheme();
    }
  }

  private static class ExperimentOutputCreatedEventTupleScheme extends TupleScheme<ExperimentOutputCreatedEvent> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ExperimentOutputCreatedEvent struct) throws TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.experimentId);
      oprot.writeString(struct.experimentName);
      oprot.writeString(struct.outputPath);
      oprot.writeString(struct.ownerId);
      oprot.writeString(struct.gatewayName);
      oprot.writeString(struct.applicationName);
      oprot.writeString(struct.host);
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ExperimentOutputCreatedEvent struct) throws TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.experimentId = iprot.readString();
      struct.setExperimentIdIsSet(true);
      struct.experimentName = iprot.readString();
      struct.setExperimentNameIsSet(true);
      struct.outputPath = iprot.readString();
      struct.setOutputPathIsSet(true);
      struct.ownerId = iprot.readString();
      struct.setOwnerIdIsSet(true);
      struct.gatewayName = iprot.readString();
      struct.setGatewayNameIsSet(true);
      struct.applicationName = iprot.readString();
      struct.setApplicationNameIsSet(true);
      struct.host = iprot.readString();
      struct.setHostIsSet(true);
    }
  }

}

