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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * Resource Job Manager Information
 * 
 * resourceJobManagerType:
 *  A typical HPC cluster has a single Job Manager to manage the resources.
 * 
 * pushMonitoringEndpoint:
 *  If the job manager pushes out state changes to a database or bus, specify the service endpoint.
 *   Ex: Moab Web Service, Moab MongoDB URL, AMQP (GLUE2) Broker
 * 
 * jobManagerBinPath:
 *  Path to the Job Manager Installation Binary directory.
 * 
 * jobManagerCommands:
 *  An enumeration of commonly used manager commands.
 * 
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class ResourceJobManager implements org.apache.thrift.TBase<ResourceJobManager, ResourceJobManager._Fields>, java.io.Serializable, Cloneable, Comparable<ResourceJobManager> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ResourceJobManager");

  private static final org.apache.thrift.protocol.TField RESOURCE_JOB_MANAGER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("resourceJobManagerId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField RESOURCE_JOB_MANAGER_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("resourceJobManagerType", org.apache.thrift.protocol.TType.I32, (short)2);
  private static final org.apache.thrift.protocol.TField PUSH_MONITORING_ENDPOINT_FIELD_DESC = new org.apache.thrift.protocol.TField("pushMonitoringEndpoint", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField JOB_MANAGER_BIN_PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("jobManagerBinPath", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField JOB_MANAGER_COMMANDS_FIELD_DESC = new org.apache.thrift.protocol.TField("jobManagerCommands", org.apache.thrift.protocol.TType.MAP, (short)5);
  private static final org.apache.thrift.protocol.TField PARALLELISM_PREFIX_FIELD_DESC = new org.apache.thrift.protocol.TField("parallelismPrefix", org.apache.thrift.protocol.TType.MAP, (short)6);

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

  private java.lang.String resourceJobManagerId; // required
  private ResourceJobManagerType resourceJobManagerType; // required
  private java.lang.String pushMonitoringEndpoint; // optional
  private java.lang.String jobManagerBinPath; // optional
  private java.util.Map<JobManagerCommand,java.lang.String> jobManagerCommands; // optional
  private java.util.Map<org.apache.airavata.model.parallelism.ApplicationParallelismType,java.lang.String> parallelismPrefix; // 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 {
    RESOURCE_JOB_MANAGER_ID((short)1, "resourceJobManagerId"),
    /**
     * 
     * @see ResourceJobManagerType
     */
    RESOURCE_JOB_MANAGER_TYPE((short)2, "resourceJobManagerType"),
    PUSH_MONITORING_ENDPOINT((short)3, "pushMonitoringEndpoint"),
    JOB_MANAGER_BIN_PATH((short)4, "jobManagerBinPath"),
    JOB_MANAGER_COMMANDS((short)5, "jobManagerCommands"),
    PARALLELISM_PREFIX((short)6, "parallelismPrefix");

    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: // RESOURCE_JOB_MANAGER_ID
          return RESOURCE_JOB_MANAGER_ID;
        case 2: // RESOURCE_JOB_MANAGER_TYPE
          return RESOURCE_JOB_MANAGER_TYPE;
        case 3: // PUSH_MONITORING_ENDPOINT
          return PUSH_MONITORING_ENDPOINT;
        case 4: // JOB_MANAGER_BIN_PATH
          return JOB_MANAGER_BIN_PATH;
        case 5: // JOB_MANAGER_COMMANDS
          return JOB_MANAGER_COMMANDS;
        case 6: // PARALLELISM_PREFIX
          return PARALLELISM_PREFIX;
        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 _Fields optionals[] = {_Fields.PUSH_MONITORING_ENDPOINT,_Fields.JOB_MANAGER_BIN_PATH,_Fields.JOB_MANAGER_COMMANDS,_Fields.PARALLELISM_PREFIX};
  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.RESOURCE_JOB_MANAGER_ID, new org.apache.thrift.meta_data.FieldMetaData("resourceJobManagerId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.RESOURCE_JOB_MANAGER_TYPE, new org.apache.thrift.meta_data.FieldMetaData("resourceJobManagerType", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ResourceJobManagerType.class)));
    tmpMap.put(_Fields.PUSH_MONITORING_ENDPOINT, new org.apache.thrift.meta_data.FieldMetaData("pushMonitoringEndpoint", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.JOB_MANAGER_BIN_PATH, new org.apache.thrift.meta_data.FieldMetaData("jobManagerBinPath", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.JOB_MANAGER_COMMANDS, new org.apache.thrift.meta_data.FieldMetaData("jobManagerCommands", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, JobManagerCommand.class), 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.PARALLELISM_PREFIX, new org.apache.thrift.meta_data.FieldMetaData("parallelismPrefix", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, org.apache.airavata.model.parallelism.ApplicationParallelismType.class), 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ResourceJobManager.class, metaDataMap);
  }

  public ResourceJobManager() {
    this.resourceJobManagerId = "DO_NOT_SET_AT_CLIENTS";

  }

  public ResourceJobManager(
    java.lang.String resourceJobManagerId,
    ResourceJobManagerType resourceJobManagerType)
  {
    this();
    this.resourceJobManagerId = resourceJobManagerId;
    this.resourceJobManagerType = resourceJobManagerType;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ResourceJobManager(ResourceJobManager other) {
    if (other.isSetResourceJobManagerId()) {
      this.resourceJobManagerId = other.resourceJobManagerId;
    }
    if (other.isSetResourceJobManagerType()) {
      this.resourceJobManagerType = other.resourceJobManagerType;
    }
    if (other.isSetPushMonitoringEndpoint()) {
      this.pushMonitoringEndpoint = other.pushMonitoringEndpoint;
    }
    if (other.isSetJobManagerBinPath()) {
      this.jobManagerBinPath = other.jobManagerBinPath;
    }
    if (other.isSetJobManagerCommands()) {
      java.util.Map<JobManagerCommand,java.lang.String> __this__jobManagerCommands = new java.util.HashMap<JobManagerCommand,java.lang.String>(other.jobManagerCommands.size());
      for (java.util.Map.Entry<JobManagerCommand, java.lang.String> other_element : other.jobManagerCommands.entrySet()) {

        JobManagerCommand other_element_key = other_element.getKey();
        java.lang.String other_element_value = other_element.getValue();

        JobManagerCommand __this__jobManagerCommands_copy_key = other_element_key;

        java.lang.String __this__jobManagerCommands_copy_value = other_element_value;

        __this__jobManagerCommands.put(__this__jobManagerCommands_copy_key, __this__jobManagerCommands_copy_value);
      }
      this.jobManagerCommands = __this__jobManagerCommands;
    }
    if (other.isSetParallelismPrefix()) {
      java.util.Map<org.apache.airavata.model.parallelism.ApplicationParallelismType,java.lang.String> __this__parallelismPrefix = new java.util.HashMap<org.apache.airavata.model.parallelism.ApplicationParallelismType,java.lang.String>(other.parallelismPrefix.size());
      for (java.util.Map.Entry<org.apache.airavata.model.parallelism.ApplicationParallelismType, java.lang.String> other_element : other.parallelismPrefix.entrySet()) {

        org.apache.airavata.model.parallelism.ApplicationParallelismType other_element_key = other_element.getKey();
        java.lang.String other_element_value = other_element.getValue();

        org.apache.airavata.model.parallelism.ApplicationParallelismType __this__parallelismPrefix_copy_key = other_element_key;

        java.lang.String __this__parallelismPrefix_copy_value = other_element_value;

        __this__parallelismPrefix.put(__this__parallelismPrefix_copy_key, __this__parallelismPrefix_copy_value);
      }
      this.parallelismPrefix = __this__parallelismPrefix;
    }
  }

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

  @Override
  public void clear() {
    this.resourceJobManagerId = "DO_NOT_SET_AT_CLIENTS";

    this.resourceJobManagerType = null;
    this.pushMonitoringEndpoint = null;
    this.jobManagerBinPath = null;
    this.jobManagerCommands = null;
    this.parallelismPrefix = null;
  }

  public java.lang.String getResourceJobManagerId() {
    return this.resourceJobManagerId;
  }

  public void setResourceJobManagerId(java.lang.String resourceJobManagerId) {
    this.resourceJobManagerId = resourceJobManagerId;
  }

  public void unsetResourceJobManagerId() {
    this.resourceJobManagerId = null;
  }

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

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

  /**
   * 
   * @see ResourceJobManagerType
   */
  public ResourceJobManagerType getResourceJobManagerType() {
    return this.resourceJobManagerType;
  }

  /**
   * 
   * @see ResourceJobManagerType
   */
  public void setResourceJobManagerType(ResourceJobManagerType resourceJobManagerType) {
    this.resourceJobManagerType = resourceJobManagerType;
  }

  public void unsetResourceJobManagerType() {
    this.resourceJobManagerType = null;
  }

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

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

  public java.lang.String getPushMonitoringEndpoint() {
    return this.pushMonitoringEndpoint;
  }

  public void setPushMonitoringEndpoint(java.lang.String pushMonitoringEndpoint) {
    this.pushMonitoringEndpoint = pushMonitoringEndpoint;
  }

  public void unsetPushMonitoringEndpoint() {
    this.pushMonitoringEndpoint = null;
  }

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

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

  public java.lang.String getJobManagerBinPath() {
    return this.jobManagerBinPath;
  }

  public void setJobManagerBinPath(java.lang.String jobManagerBinPath) {
    this.jobManagerBinPath = jobManagerBinPath;
  }

  public void unsetJobManagerBinPath() {
    this.jobManagerBinPath = null;
  }

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

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

  public int getJobManagerCommandsSize() {
    return (this.jobManagerCommands == null) ? 0 : this.jobManagerCommands.size();
  }

  public void putToJobManagerCommands(JobManagerCommand key, java.lang.String val) {
    if (this.jobManagerCommands == null) {
      this.jobManagerCommands = new java.util.HashMap<JobManagerCommand,java.lang.String>();
    }
    this.jobManagerCommands.put(key, val);
  }

  public java.util.Map<JobManagerCommand,java.lang.String> getJobManagerCommands() {
    return this.jobManagerCommands;
  }

  public void setJobManagerCommands(java.util.Map<JobManagerCommand,java.lang.String> jobManagerCommands) {
    this.jobManagerCommands = jobManagerCommands;
  }

  public void unsetJobManagerCommands() {
    this.jobManagerCommands = null;
  }

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

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

  public int getParallelismPrefixSize() {
    return (this.parallelismPrefix == null) ? 0 : this.parallelismPrefix.size();
  }

  public void putToParallelismPrefix(org.apache.airavata.model.parallelism.ApplicationParallelismType key, java.lang.String val) {
    if (this.parallelismPrefix == null) {
      this.parallelismPrefix = new java.util.HashMap<org.apache.airavata.model.parallelism.ApplicationParallelismType,java.lang.String>();
    }
    this.parallelismPrefix.put(key, val);
  }

  public java.util.Map<org.apache.airavata.model.parallelism.ApplicationParallelismType,java.lang.String> getParallelismPrefix() {
    return this.parallelismPrefix;
  }

  public void setParallelismPrefix(java.util.Map<org.apache.airavata.model.parallelism.ApplicationParallelismType,java.lang.String> parallelismPrefix) {
    this.parallelismPrefix = parallelismPrefix;
  }

  public void unsetParallelismPrefix() {
    this.parallelismPrefix = null;
  }

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

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

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

    case RESOURCE_JOB_MANAGER_TYPE:
      if (value == null) {
        unsetResourceJobManagerType();
      } else {
        setResourceJobManagerType((ResourceJobManagerType)value);
      }
      break;

    case PUSH_MONITORING_ENDPOINT:
      if (value == null) {
        unsetPushMonitoringEndpoint();
      } else {
        setPushMonitoringEndpoint((java.lang.String)value);
      }
      break;

    case JOB_MANAGER_BIN_PATH:
      if (value == null) {
        unsetJobManagerBinPath();
      } else {
        setJobManagerBinPath((java.lang.String)value);
      }
      break;

    case JOB_MANAGER_COMMANDS:
      if (value == null) {
        unsetJobManagerCommands();
      } else {
        setJobManagerCommands((java.util.Map<JobManagerCommand,java.lang.String>)value);
      }
      break;

    case PARALLELISM_PREFIX:
      if (value == null) {
        unsetParallelismPrefix();
      } else {
        setParallelismPrefix((java.util.Map<org.apache.airavata.model.parallelism.ApplicationParallelismType,java.lang.String>)value);
      }
      break;

    }
  }

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

    case RESOURCE_JOB_MANAGER_TYPE:
      return getResourceJobManagerType();

    case PUSH_MONITORING_ENDPOINT:
      return getPushMonitoringEndpoint();

    case JOB_MANAGER_BIN_PATH:
      return getJobManagerBinPath();

    case JOB_MANAGER_COMMANDS:
      return getJobManagerCommands();

    case PARALLELISM_PREFIX:
      return getParallelismPrefix();

    }
    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 RESOURCE_JOB_MANAGER_ID:
      return isSetResourceJobManagerId();
    case RESOURCE_JOB_MANAGER_TYPE:
      return isSetResourceJobManagerType();
    case PUSH_MONITORING_ENDPOINT:
      return isSetPushMonitoringEndpoint();
    case JOB_MANAGER_BIN_PATH:
      return isSetJobManagerBinPath();
    case JOB_MANAGER_COMMANDS:
      return isSetJobManagerCommands();
    case PARALLELISM_PREFIX:
      return isSetParallelismPrefix();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_resourceJobManagerId = true && this.isSetResourceJobManagerId();
    boolean that_present_resourceJobManagerId = true && that.isSetResourceJobManagerId();
    if (this_present_resourceJobManagerId || that_present_resourceJobManagerId) {
      if (!(this_present_resourceJobManagerId && that_present_resourceJobManagerId))
        return false;
      if (!this.resourceJobManagerId.equals(that.resourceJobManagerId))
        return false;
    }

    boolean this_present_resourceJobManagerType = true && this.isSetResourceJobManagerType();
    boolean that_present_resourceJobManagerType = true && that.isSetResourceJobManagerType();
    if (this_present_resourceJobManagerType || that_present_resourceJobManagerType) {
      if (!(this_present_resourceJobManagerType && that_present_resourceJobManagerType))
        return false;
      if (!this.resourceJobManagerType.equals(that.resourceJobManagerType))
        return false;
    }

    boolean this_present_pushMonitoringEndpoint = true && this.isSetPushMonitoringEndpoint();
    boolean that_present_pushMonitoringEndpoint = true && that.isSetPushMonitoringEndpoint();
    if (this_present_pushMonitoringEndpoint || that_present_pushMonitoringEndpoint) {
      if (!(this_present_pushMonitoringEndpoint && that_present_pushMonitoringEndpoint))
        return false;
      if (!this.pushMonitoringEndpoint.equals(that.pushMonitoringEndpoint))
        return false;
    }

    boolean this_present_jobManagerBinPath = true && this.isSetJobManagerBinPath();
    boolean that_present_jobManagerBinPath = true && that.isSetJobManagerBinPath();
    if (this_present_jobManagerBinPath || that_present_jobManagerBinPath) {
      if (!(this_present_jobManagerBinPath && that_present_jobManagerBinPath))
        return false;
      if (!this.jobManagerBinPath.equals(that.jobManagerBinPath))
        return false;
    }

    boolean this_present_jobManagerCommands = true && this.isSetJobManagerCommands();
    boolean that_present_jobManagerCommands = true && that.isSetJobManagerCommands();
    if (this_present_jobManagerCommands || that_present_jobManagerCommands) {
      if (!(this_present_jobManagerCommands && that_present_jobManagerCommands))
        return false;
      if (!this.jobManagerCommands.equals(that.jobManagerCommands))
        return false;
    }

    boolean this_present_parallelismPrefix = true && this.isSetParallelismPrefix();
    boolean that_present_parallelismPrefix = true && that.isSetParallelismPrefix();
    if (this_present_parallelismPrefix || that_present_parallelismPrefix) {
      if (!(this_present_parallelismPrefix && that_present_parallelismPrefix))
        return false;
      if (!this.parallelismPrefix.equals(that.parallelismPrefix))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetResourceJobManagerId()) ? 131071 : 524287);
    if (isSetResourceJobManagerId())
      hashCode = hashCode * 8191 + resourceJobManagerId.hashCode();

    hashCode = hashCode * 8191 + ((isSetResourceJobManagerType()) ? 131071 : 524287);
    if (isSetResourceJobManagerType())
      hashCode = hashCode * 8191 + resourceJobManagerType.getValue();

    hashCode = hashCode * 8191 + ((isSetPushMonitoringEndpoint()) ? 131071 : 524287);
    if (isSetPushMonitoringEndpoint())
      hashCode = hashCode * 8191 + pushMonitoringEndpoint.hashCode();

    hashCode = hashCode * 8191 + ((isSetJobManagerBinPath()) ? 131071 : 524287);
    if (isSetJobManagerBinPath())
      hashCode = hashCode * 8191 + jobManagerBinPath.hashCode();

    hashCode = hashCode * 8191 + ((isSetJobManagerCommands()) ? 131071 : 524287);
    if (isSetJobManagerCommands())
      hashCode = hashCode * 8191 + jobManagerCommands.hashCode();

    hashCode = hashCode * 8191 + ((isSetParallelismPrefix()) ? 131071 : 524287);
    if (isSetParallelismPrefix())
      hashCode = hashCode * 8191 + parallelismPrefix.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetResourceJobManagerId()).compareTo(other.isSetResourceJobManagerId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetResourceJobManagerId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceJobManagerId, other.resourceJobManagerId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetResourceJobManagerType()).compareTo(other.isSetResourceJobManagerType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetResourceJobManagerType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceJobManagerType, other.resourceJobManagerType);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetPushMonitoringEndpoint()).compareTo(other.isSetPushMonitoringEndpoint());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPushMonitoringEndpoint()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.pushMonitoringEndpoint, other.pushMonitoringEndpoint);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetJobManagerBinPath()).compareTo(other.isSetJobManagerBinPath());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetJobManagerBinPath()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobManagerBinPath, other.jobManagerBinPath);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetJobManagerCommands()).compareTo(other.isSetJobManagerCommands());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetJobManagerCommands()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobManagerCommands, other.jobManagerCommands);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetParallelismPrefix()).compareTo(other.isSetParallelismPrefix());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetParallelismPrefix()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parallelismPrefix, other.parallelismPrefix);
      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("ResourceJobManager(");
    boolean first = true;

    sb.append("resourceJobManagerId:");
    if (this.resourceJobManagerId == null) {
      sb.append("null");
    } else {
      sb.append(this.resourceJobManagerId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("resourceJobManagerType:");
    if (this.resourceJobManagerType == null) {
      sb.append("null");
    } else {
      sb.append(this.resourceJobManagerType);
    }
    first = false;
    if (isSetPushMonitoringEndpoint()) {
      if (!first) sb.append(", ");
      sb.append("pushMonitoringEndpoint:");
      if (this.pushMonitoringEndpoint == null) {
        sb.append("null");
      } else {
        sb.append(this.pushMonitoringEndpoint);
      }
      first = false;
    }
    if (isSetJobManagerBinPath()) {
      if (!first) sb.append(", ");
      sb.append("jobManagerBinPath:");
      if (this.jobManagerBinPath == null) {
        sb.append("null");
      } else {
        sb.append(this.jobManagerBinPath);
      }
      first = false;
    }
    if (isSetJobManagerCommands()) {
      if (!first) sb.append(", ");
      sb.append("jobManagerCommands:");
      if (this.jobManagerCommands == null) {
        sb.append("null");
      } else {
        sb.append(this.jobManagerCommands);
      }
      first = false;
    }
    if (isSetParallelismPrefix()) {
      if (!first) sb.append(", ");
      sb.append("parallelismPrefix:");
      if (this.parallelismPrefix == null) {
        sb.append("null");
      } else {
        sb.append(this.parallelismPrefix);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

  private static class ResourceJobManagerStandardScheme extends org.apache.thrift.scheme.StandardScheme<ResourceJobManager> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, ResourceJobManager 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: // RESOURCE_JOB_MANAGER_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.resourceJobManagerId = iprot.readString();
              struct.setResourceJobManagerIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // RESOURCE_JOB_MANAGER_TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.resourceJobManagerType = org.apache.airavata.model.appcatalog.computeresource.ResourceJobManagerType.findByValue(iprot.readI32());
              struct.setResourceJobManagerTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // PUSH_MONITORING_ENDPOINT
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.pushMonitoringEndpoint = iprot.readString();
              struct.setPushMonitoringEndpointIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // JOB_MANAGER_BIN_PATH
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.jobManagerBinPath = iprot.readString();
              struct.setJobManagerBinPathIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // JOB_MANAGER_COMMANDS
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map0 = iprot.readMapBegin();
                struct.jobManagerCommands = new java.util.HashMap<JobManagerCommand,java.lang.String>(2*_map0.size);
                JobManagerCommand _key1;
                java.lang.String _val2;
                for (int _i3 = 0; _i3 < _map0.size; ++_i3)
                {
                  _key1 = org.apache.airavata.model.appcatalog.computeresource.JobManagerCommand.findByValue(iprot.readI32());
                  _val2 = iprot.readString();
                  struct.jobManagerCommands.put(_key1, _val2);
                }
                iprot.readMapEnd();
              }
              struct.setJobManagerCommandsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // PARALLELISM_PREFIX
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map4 = iprot.readMapBegin();
                struct.parallelismPrefix = new java.util.HashMap<org.apache.airavata.model.parallelism.ApplicationParallelismType,java.lang.String>(2*_map4.size);
                org.apache.airavata.model.parallelism.ApplicationParallelismType _key5;
                java.lang.String _val6;
                for (int _i7 = 0; _i7 < _map4.size; ++_i7)
                {
                  _key5 = org.apache.airavata.model.parallelism.ApplicationParallelismType.findByValue(iprot.readI32());
                  _val6 = iprot.readString();
                  struct.parallelismPrefix.put(_key5, _val6);
                }
                iprot.readMapEnd();
              }
              struct.setParallelismPrefixIsSet(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, ResourceJobManager struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.resourceJobManagerId != null) {
        oprot.writeFieldBegin(RESOURCE_JOB_MANAGER_ID_FIELD_DESC);
        oprot.writeString(struct.resourceJobManagerId);
        oprot.writeFieldEnd();
      }
      if (struct.resourceJobManagerType != null) {
        oprot.writeFieldBegin(RESOURCE_JOB_MANAGER_TYPE_FIELD_DESC);
        oprot.writeI32(struct.resourceJobManagerType.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.pushMonitoringEndpoint != null) {
        if (struct.isSetPushMonitoringEndpoint()) {
          oprot.writeFieldBegin(PUSH_MONITORING_ENDPOINT_FIELD_DESC);
          oprot.writeString(struct.pushMonitoringEndpoint);
          oprot.writeFieldEnd();
        }
      }
      if (struct.jobManagerBinPath != null) {
        if (struct.isSetJobManagerBinPath()) {
          oprot.writeFieldBegin(JOB_MANAGER_BIN_PATH_FIELD_DESC);
          oprot.writeString(struct.jobManagerBinPath);
          oprot.writeFieldEnd();
        }
      }
      if (struct.jobManagerCommands != null) {
        if (struct.isSetJobManagerCommands()) {
          oprot.writeFieldBegin(JOB_MANAGER_COMMANDS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.I32, org.apache.thrift.protocol.TType.STRING, struct.jobManagerCommands.size()));
            for (java.util.Map.Entry<JobManagerCommand, java.lang.String> _iter8 : struct.jobManagerCommands.entrySet())
            {
              oprot.writeI32(_iter8.getKey().getValue());
              oprot.writeString(_iter8.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.parallelismPrefix != null) {
        if (struct.isSetParallelismPrefix()) {
          oprot.writeFieldBegin(PARALLELISM_PREFIX_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.I32, org.apache.thrift.protocol.TType.STRING, struct.parallelismPrefix.size()));
            for (java.util.Map.Entry<org.apache.airavata.model.parallelism.ApplicationParallelismType, java.lang.String> _iter9 : struct.parallelismPrefix.entrySet())
            {
              oprot.writeI32(_iter9.getKey().getValue());
              oprot.writeString(_iter9.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class ResourceJobManagerTupleScheme extends org.apache.thrift.scheme.TupleScheme<ResourceJobManager> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ResourceJobManager struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.resourceJobManagerId);
      oprot.writeI32(struct.resourceJobManagerType.getValue());
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetPushMonitoringEndpoint()) {
        optionals.set(0);
      }
      if (struct.isSetJobManagerBinPath()) {
        optionals.set(1);
      }
      if (struct.isSetJobManagerCommands()) {
        optionals.set(2);
      }
      if (struct.isSetParallelismPrefix()) {
        optionals.set(3);
      }
      oprot.writeBitSet(optionals, 4);
      if (struct.isSetPushMonitoringEndpoint()) {
        oprot.writeString(struct.pushMonitoringEndpoint);
      }
      if (struct.isSetJobManagerBinPath()) {
        oprot.writeString(struct.jobManagerBinPath);
      }
      if (struct.isSetJobManagerCommands()) {
        {
          oprot.writeI32(struct.jobManagerCommands.size());
          for (java.util.Map.Entry<JobManagerCommand, java.lang.String> _iter10 : struct.jobManagerCommands.entrySet())
          {
            oprot.writeI32(_iter10.getKey().getValue());
            oprot.writeString(_iter10.getValue());
          }
        }
      }
      if (struct.isSetParallelismPrefix()) {
        {
          oprot.writeI32(struct.parallelismPrefix.size());
          for (java.util.Map.Entry<org.apache.airavata.model.parallelism.ApplicationParallelismType, java.lang.String> _iter11 : struct.parallelismPrefix.entrySet())
          {
            oprot.writeI32(_iter11.getKey().getValue());
            oprot.writeString(_iter11.getValue());
          }
        }
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ResourceJobManager struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.resourceJobManagerId = iprot.readString();
      struct.setResourceJobManagerIdIsSet(true);
      struct.resourceJobManagerType = org.apache.airavata.model.appcatalog.computeresource.ResourceJobManagerType.findByValue(iprot.readI32());
      struct.setResourceJobManagerTypeIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(4);
      if (incoming.get(0)) {
        struct.pushMonitoringEndpoint = iprot.readString();
        struct.setPushMonitoringEndpointIsSet(true);
      }
      if (incoming.get(1)) {
        struct.jobManagerBinPath = iprot.readString();
        struct.setJobManagerBinPathIsSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.thrift.protocol.TMap _map12 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.I32, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.jobManagerCommands = new java.util.HashMap<JobManagerCommand,java.lang.String>(2*_map12.size);
          JobManagerCommand _key13;
          java.lang.String _val14;
          for (int _i15 = 0; _i15 < _map12.size; ++_i15)
          {
            _key13 = org.apache.airavata.model.appcatalog.computeresource.JobManagerCommand.findByValue(iprot.readI32());
            _val14 = iprot.readString();
            struct.jobManagerCommands.put(_key13, _val14);
          }
        }
        struct.setJobManagerCommandsIsSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.thrift.protocol.TMap _map16 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.I32, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.parallelismPrefix = new java.util.HashMap<org.apache.airavata.model.parallelism.ApplicationParallelismType,java.lang.String>(2*_map16.size);
          org.apache.airavata.model.parallelism.ApplicationParallelismType _key17;
          java.lang.String _val18;
          for (int _i19 = 0; _i19 < _map16.size; ++_i19)
          {
            _key17 = org.apache.airavata.model.parallelism.ApplicationParallelismType.findByValue(iprot.readI32());
            _val18 = iprot.readString();
            struct.parallelismPrefix.put(_key17, _val18);
          }
        }
        struct.setParallelismPrefixIsSet(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();
  }
}

