/**
 * 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.workspace;

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

  private static final org.apache.thrift.protocol.TField NOTIFICATION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("notificationId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayId", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField TITLE_FIELD_DESC = new org.apache.thrift.protocol.TField("title", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField NOTIFICATION_MESSAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("notificationMessage", org.apache.thrift.protocol.TType.STRING, (short)4);
  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)5);
  private static final org.apache.thrift.protocol.TField PUBLISHED_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("publishedTime", org.apache.thrift.protocol.TType.I64, (short)6);
  private static final org.apache.thrift.protocol.TField EXPIRATION_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("expirationTime", org.apache.thrift.protocol.TType.I64, (short)7);
  private static final org.apache.thrift.protocol.TField PRIORITY_FIELD_DESC = new org.apache.thrift.protocol.TField("priority", org.apache.thrift.protocol.TType.I32, (short)8);

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

  private java.lang.String notificationId; // optional
  private java.lang.String gatewayId; // required
  private java.lang.String title; // required
  private java.lang.String notificationMessage; // required
  private long creationTime; // optional
  private long publishedTime; // optional
  private long expirationTime; // optional
  private NotificationPriority priority; // 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 {
    NOTIFICATION_ID((short)1, "notificationId"),
    GATEWAY_ID((short)2, "gatewayId"),
    TITLE((short)3, "title"),
    NOTIFICATION_MESSAGE((short)4, "notificationMessage"),
    CREATION_TIME((short)5, "creationTime"),
    PUBLISHED_TIME((short)6, "publishedTime"),
    EXPIRATION_TIME((short)7, "expirationTime"),
    /**
     * 
     * @see NotificationPriority
     */
    PRIORITY((short)8, "priority");

    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: // NOTIFICATION_ID
          return NOTIFICATION_ID;
        case 2: // GATEWAY_ID
          return GATEWAY_ID;
        case 3: // TITLE
          return TITLE;
        case 4: // NOTIFICATION_MESSAGE
          return NOTIFICATION_MESSAGE;
        case 5: // CREATION_TIME
          return CREATION_TIME;
        case 6: // PUBLISHED_TIME
          return PUBLISHED_TIME;
        case 7: // EXPIRATION_TIME
          return EXPIRATION_TIME;
        case 8: // PRIORITY
          return PRIORITY;
        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 __CREATIONTIME_ISSET_ID = 0;
  private static final int __PUBLISHEDTIME_ISSET_ID = 1;
  private static final int __EXPIRATIONTIME_ISSET_ID = 2;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.NOTIFICATION_ID,_Fields.CREATION_TIME,_Fields.PUBLISHED_TIME,_Fields.EXPIRATION_TIME,_Fields.PRIORITY};
  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.NOTIFICATION_ID, new org.apache.thrift.meta_data.FieldMetaData("notificationId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.GATEWAY_ID, new org.apache.thrift.meta_data.FieldMetaData("gatewayId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TITLE, new org.apache.thrift.meta_data.FieldMetaData("title", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.NOTIFICATION_MESSAGE, new org.apache.thrift.meta_data.FieldMetaData("notificationMessage", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    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.PUBLISHED_TIME, new org.apache.thrift.meta_data.FieldMetaData("publishedTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.EXPIRATION_TIME, new org.apache.thrift.meta_data.FieldMetaData("expirationTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.PRIORITY, new org.apache.thrift.meta_data.FieldMetaData("priority", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, NotificationPriority.class)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Notification.class, metaDataMap);
  }

  public Notification() {
  }

  public Notification(
    java.lang.String gatewayId,
    java.lang.String title,
    java.lang.String notificationMessage)
  {
    this();
    this.gatewayId = gatewayId;
    this.title = title;
    this.notificationMessage = notificationMessage;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public Notification(Notification other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetNotificationId()) {
      this.notificationId = other.notificationId;
    }
    if (other.isSetGatewayId()) {
      this.gatewayId = other.gatewayId;
    }
    if (other.isSetTitle()) {
      this.title = other.title;
    }
    if (other.isSetNotificationMessage()) {
      this.notificationMessage = other.notificationMessage;
    }
    this.creationTime = other.creationTime;
    this.publishedTime = other.publishedTime;
    this.expirationTime = other.expirationTime;
    if (other.isSetPriority()) {
      this.priority = other.priority;
    }
  }

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

  @Override
  public void clear() {
    this.notificationId = null;
    this.gatewayId = null;
    this.title = null;
    this.notificationMessage = null;
    setCreationTimeIsSet(false);
    this.creationTime = 0;
    setPublishedTimeIsSet(false);
    this.publishedTime = 0;
    setExpirationTimeIsSet(false);
    this.expirationTime = 0;
    this.priority = null;
  }

  public java.lang.String getNotificationId() {
    return this.notificationId;
  }

  public void setNotificationId(java.lang.String notificationId) {
    this.notificationId = notificationId;
  }

  public void unsetNotificationId() {
    this.notificationId = null;
  }

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

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

  public java.lang.String getGatewayId() {
    return this.gatewayId;
  }

  public void setGatewayId(java.lang.String gatewayId) {
    this.gatewayId = gatewayId;
  }

  public void unsetGatewayId() {
    this.gatewayId = null;
  }

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

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

  public java.lang.String getTitle() {
    return this.title;
  }

  public void setTitle(java.lang.String title) {
    this.title = title;
  }

  public void unsetTitle() {
    this.title = null;
  }

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

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

  public java.lang.String getNotificationMessage() {
    return this.notificationMessage;
  }

  public void setNotificationMessage(java.lang.String notificationMessage) {
    this.notificationMessage = notificationMessage;
  }

  public void unsetNotificationMessage() {
    this.notificationMessage = null;
  }

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

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

  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 getPublishedTime() {
    return this.publishedTime;
  }

  public void setPublishedTime(long publishedTime) {
    this.publishedTime = publishedTime;
    setPublishedTimeIsSet(true);
  }

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

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

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

  public long getExpirationTime() {
    return this.expirationTime;
  }

  public void setExpirationTime(long expirationTime) {
    this.expirationTime = expirationTime;
    setExpirationTimeIsSet(true);
  }

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

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

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

  /**
   * 
   * @see NotificationPriority
   */
  public NotificationPriority getPriority() {
    return this.priority;
  }

  /**
   * 
   * @see NotificationPriority
   */
  public void setPriority(NotificationPriority priority) {
    this.priority = priority;
  }

  public void unsetPriority() {
    this.priority = null;
  }

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

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

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

    case GATEWAY_ID:
      if (value == null) {
        unsetGatewayId();
      } else {
        setGatewayId((java.lang.String)value);
      }
      break;

    case TITLE:
      if (value == null) {
        unsetTitle();
      } else {
        setTitle((java.lang.String)value);
      }
      break;

    case NOTIFICATION_MESSAGE:
      if (value == null) {
        unsetNotificationMessage();
      } else {
        setNotificationMessage((java.lang.String)value);
      }
      break;

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

    case PUBLISHED_TIME:
      if (value == null) {
        unsetPublishedTime();
      } else {
        setPublishedTime((java.lang.Long)value);
      }
      break;

    case EXPIRATION_TIME:
      if (value == null) {
        unsetExpirationTime();
      } else {
        setExpirationTime((java.lang.Long)value);
      }
      break;

    case PRIORITY:
      if (value == null) {
        unsetPriority();
      } else {
        setPriority((NotificationPriority)value);
      }
      break;

    }
  }

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

    case GATEWAY_ID:
      return getGatewayId();

    case TITLE:
      return getTitle();

    case NOTIFICATION_MESSAGE:
      return getNotificationMessage();

    case CREATION_TIME:
      return getCreationTime();

    case PUBLISHED_TIME:
      return getPublishedTime();

    case EXPIRATION_TIME:
      return getExpirationTime();

    case PRIORITY:
      return getPriority();

    }
    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 NOTIFICATION_ID:
      return isSetNotificationId();
    case GATEWAY_ID:
      return isSetGatewayId();
    case TITLE:
      return isSetTitle();
    case NOTIFICATION_MESSAGE:
      return isSetNotificationMessage();
    case CREATION_TIME:
      return isSetCreationTime();
    case PUBLISHED_TIME:
      return isSetPublishedTime();
    case EXPIRATION_TIME:
      return isSetExpirationTime();
    case PRIORITY:
      return isSetPriority();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_notificationId = true && this.isSetNotificationId();
    boolean that_present_notificationId = true && that.isSetNotificationId();
    if (this_present_notificationId || that_present_notificationId) {
      if (!(this_present_notificationId && that_present_notificationId))
        return false;
      if (!this.notificationId.equals(that.notificationId))
        return false;
    }

    boolean this_present_gatewayId = true && this.isSetGatewayId();
    boolean that_present_gatewayId = true && that.isSetGatewayId();
    if (this_present_gatewayId || that_present_gatewayId) {
      if (!(this_present_gatewayId && that_present_gatewayId))
        return false;
      if (!this.gatewayId.equals(that.gatewayId))
        return false;
    }

    boolean this_present_title = true && this.isSetTitle();
    boolean that_present_title = true && that.isSetTitle();
    if (this_present_title || that_present_title) {
      if (!(this_present_title && that_present_title))
        return false;
      if (!this.title.equals(that.title))
        return false;
    }

    boolean this_present_notificationMessage = true && this.isSetNotificationMessage();
    boolean that_present_notificationMessage = true && that.isSetNotificationMessage();
    if (this_present_notificationMessage || that_present_notificationMessage) {
      if (!(this_present_notificationMessage && that_present_notificationMessage))
        return false;
      if (!this.notificationMessage.equals(that.notificationMessage))
        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_publishedTime = true && this.isSetPublishedTime();
    boolean that_present_publishedTime = true && that.isSetPublishedTime();
    if (this_present_publishedTime || that_present_publishedTime) {
      if (!(this_present_publishedTime && that_present_publishedTime))
        return false;
      if (this.publishedTime != that.publishedTime)
        return false;
    }

    boolean this_present_expirationTime = true && this.isSetExpirationTime();
    boolean that_present_expirationTime = true && that.isSetExpirationTime();
    if (this_present_expirationTime || that_present_expirationTime) {
      if (!(this_present_expirationTime && that_present_expirationTime))
        return false;
      if (this.expirationTime != that.expirationTime)
        return false;
    }

    boolean this_present_priority = true && this.isSetPriority();
    boolean that_present_priority = true && that.isSetPriority();
    if (this_present_priority || that_present_priority) {
      if (!(this_present_priority && that_present_priority))
        return false;
      if (!this.priority.equals(that.priority))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetNotificationId()) ? 131071 : 524287);
    if (isSetNotificationId())
      hashCode = hashCode * 8191 + notificationId.hashCode();

    hashCode = hashCode * 8191 + ((isSetGatewayId()) ? 131071 : 524287);
    if (isSetGatewayId())
      hashCode = hashCode * 8191 + gatewayId.hashCode();

    hashCode = hashCode * 8191 + ((isSetTitle()) ? 131071 : 524287);
    if (isSetTitle())
      hashCode = hashCode * 8191 + title.hashCode();

    hashCode = hashCode * 8191 + ((isSetNotificationMessage()) ? 131071 : 524287);
    if (isSetNotificationMessage())
      hashCode = hashCode * 8191 + notificationMessage.hashCode();

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

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

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

    hashCode = hashCode * 8191 + ((isSetPriority()) ? 131071 : 524287);
    if (isSetPriority())
      hashCode = hashCode * 8191 + priority.getValue();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetNotificationId()).compareTo(other.isSetNotificationId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetNotificationId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.notificationId, other.notificationId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetGatewayId()).compareTo(other.isSetGatewayId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGatewayId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayId, other.gatewayId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetTitle()).compareTo(other.isSetTitle());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTitle()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.title, other.title);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetNotificationMessage()).compareTo(other.isSetNotificationMessage());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetNotificationMessage()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.notificationMessage, other.notificationMessage);
      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(isSetPublishedTime()).compareTo(other.isSetPublishedTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPublishedTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.publishedTime, other.publishedTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetExpirationTime()).compareTo(other.isSetExpirationTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExpirationTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.expirationTime, other.expirationTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetPriority()).compareTo(other.isSetPriority());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPriority()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priority, other.priority);
      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("Notification(");
    boolean first = true;

    if (isSetNotificationId()) {
      sb.append("notificationId:");
      if (this.notificationId == null) {
        sb.append("null");
      } else {
        sb.append(this.notificationId);
      }
      first = false;
    }
    if (!first) sb.append(", ");
    sb.append("gatewayId:");
    if (this.gatewayId == null) {
      sb.append("null");
    } else {
      sb.append(this.gatewayId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("title:");
    if (this.title == null) {
      sb.append("null");
    } else {
      sb.append(this.title);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("notificationMessage:");
    if (this.notificationMessage == null) {
      sb.append("null");
    } else {
      sb.append(this.notificationMessage);
    }
    first = false;
    if (isSetCreationTime()) {
      if (!first) sb.append(", ");
      sb.append("creationTime:");
      sb.append(this.creationTime);
      first = false;
    }
    if (isSetPublishedTime()) {
      if (!first) sb.append(", ");
      sb.append("publishedTime:");
      sb.append(this.publishedTime);
      first = false;
    }
    if (isSetExpirationTime()) {
      if (!first) sb.append(", ");
      sb.append("expirationTime:");
      sb.append(this.expirationTime);
      first = false;
    }
    if (isSetPriority()) {
      if (!first) sb.append(", ");
      sb.append("priority:");
      if (this.priority == null) {
        sb.append("null");
      } else {
        sb.append(this.priority);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

    if (!isSetNotificationMessage()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'notificationMessage' 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 NotificationStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public NotificationStandardScheme getScheme() {
      return new NotificationStandardScheme();
    }
  }

  private static class NotificationStandardScheme extends org.apache.thrift.scheme.StandardScheme<Notification> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, Notification 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: // NOTIFICATION_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.notificationId = iprot.readString();
              struct.setNotificationIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // GATEWAY_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.gatewayId = iprot.readString();
              struct.setGatewayIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // TITLE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.title = iprot.readString();
              struct.setTitleIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // NOTIFICATION_MESSAGE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.notificationMessage = iprot.readString();
              struct.setNotificationMessageIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // 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 6: // PUBLISHED_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.publishedTime = iprot.readI64();
              struct.setPublishedTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // EXPIRATION_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.expirationTime = iprot.readI64();
              struct.setExpirationTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // PRIORITY
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.priority = org.apache.airavata.model.workspace.NotificationPriority.findByValue(iprot.readI32());
              struct.setPriorityIsSet(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, Notification struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.notificationId != null) {
        if (struct.isSetNotificationId()) {
          oprot.writeFieldBegin(NOTIFICATION_ID_FIELD_DESC);
          oprot.writeString(struct.notificationId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.gatewayId != null) {
        oprot.writeFieldBegin(GATEWAY_ID_FIELD_DESC);
        oprot.writeString(struct.gatewayId);
        oprot.writeFieldEnd();
      }
      if (struct.title != null) {
        oprot.writeFieldBegin(TITLE_FIELD_DESC);
        oprot.writeString(struct.title);
        oprot.writeFieldEnd();
      }
      if (struct.notificationMessage != null) {
        oprot.writeFieldBegin(NOTIFICATION_MESSAGE_FIELD_DESC);
        oprot.writeString(struct.notificationMessage);
        oprot.writeFieldEnd();
      }
      if (struct.isSetCreationTime()) {
        oprot.writeFieldBegin(CREATION_TIME_FIELD_DESC);
        oprot.writeI64(struct.creationTime);
        oprot.writeFieldEnd();
      }
      if (struct.isSetPublishedTime()) {
        oprot.writeFieldBegin(PUBLISHED_TIME_FIELD_DESC);
        oprot.writeI64(struct.publishedTime);
        oprot.writeFieldEnd();
      }
      if (struct.isSetExpirationTime()) {
        oprot.writeFieldBegin(EXPIRATION_TIME_FIELD_DESC);
        oprot.writeI64(struct.expirationTime);
        oprot.writeFieldEnd();
      }
      if (struct.priority != null) {
        if (struct.isSetPriority()) {
          oprot.writeFieldBegin(PRIORITY_FIELD_DESC);
          oprot.writeI32(struct.priority.getValue());
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class NotificationTupleScheme extends org.apache.thrift.scheme.TupleScheme<Notification> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, Notification struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.gatewayId);
      oprot.writeString(struct.title);
      oprot.writeString(struct.notificationMessage);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetNotificationId()) {
        optionals.set(0);
      }
      if (struct.isSetCreationTime()) {
        optionals.set(1);
      }
      if (struct.isSetPublishedTime()) {
        optionals.set(2);
      }
      if (struct.isSetExpirationTime()) {
        optionals.set(3);
      }
      if (struct.isSetPriority()) {
        optionals.set(4);
      }
      oprot.writeBitSet(optionals, 5);
      if (struct.isSetNotificationId()) {
        oprot.writeString(struct.notificationId);
      }
      if (struct.isSetCreationTime()) {
        oprot.writeI64(struct.creationTime);
      }
      if (struct.isSetPublishedTime()) {
        oprot.writeI64(struct.publishedTime);
      }
      if (struct.isSetExpirationTime()) {
        oprot.writeI64(struct.expirationTime);
      }
      if (struct.isSetPriority()) {
        oprot.writeI32(struct.priority.getValue());
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, Notification struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.gatewayId = iprot.readString();
      struct.setGatewayIdIsSet(true);
      struct.title = iprot.readString();
      struct.setTitleIsSet(true);
      struct.notificationMessage = iprot.readString();
      struct.setNotificationMessageIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(5);
      if (incoming.get(0)) {
        struct.notificationId = iprot.readString();
        struct.setNotificationIdIsSet(true);
      }
      if (incoming.get(1)) {
        struct.creationTime = iprot.readI64();
        struct.setCreationTimeIsSet(true);
      }
      if (incoming.get(2)) {
        struct.publishedTime = iprot.readI64();
        struct.setPublishedTimeIsSet(true);
      }
      if (incoming.get(3)) {
        struct.expirationTime = iprot.readI64();
        struct.setExpirationTimeIsSet(true);
      }
      if (incoming.get(4)) {
        struct.priority = org.apache.airavata.model.workspace.NotificationPriority.findByValue(iprot.readI32());
        struct.setPriorityIsSet(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();
  }
}

