/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Autogenerated by Thrift Compiler (0.9.2)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.model.experiment;

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

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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
/**
 * A structure holding the experiment configuration.
 * 
 * 
 */
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2015-11-16")
public class UserConfigurationDataModel implements org.apache.thrift.TBase<UserConfigurationDataModel, UserConfigurationDataModel._Fields>, java.io.Serializable, Cloneable, Comparable<UserConfigurationDataModel> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("UserConfigurationDataModel");

  private static final org.apache.thrift.protocol.TField AIRAVATA_AUTO_SCHEDULE_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataAutoSchedule", org.apache.thrift.protocol.TType.BOOL, (short)1);
  private static final org.apache.thrift.protocol.TField OVERRIDE_MANUAL_SCHEDULED_PARAMS_FIELD_DESC = new org.apache.thrift.protocol.TField("overrideManualScheduledParams", org.apache.thrift.protocol.TType.BOOL, (short)2);
  private static final org.apache.thrift.protocol.TField SHARE_EXPERIMENT_PUBLICLY_FIELD_DESC = new org.apache.thrift.protocol.TField("shareExperimentPublicly", org.apache.thrift.protocol.TType.BOOL, (short)3);
  private static final org.apache.thrift.protocol.TField COMPUTATIONAL_RESOURCE_SCHEDULING_FIELD_DESC = new org.apache.thrift.protocol.TField("computationalResourceScheduling", org.apache.thrift.protocol.TType.STRUCT, (short)4);
  private static final org.apache.thrift.protocol.TField THROTTLE_RESOURCES_FIELD_DESC = new org.apache.thrift.protocol.TField("throttleResources", org.apache.thrift.protocol.TType.BOOL, (short)5);
  private static final org.apache.thrift.protocol.TField USER_DN_FIELD_DESC = new org.apache.thrift.protocol.TField("userDN", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField GENERATE_CERT_FIELD_DESC = new org.apache.thrift.protocol.TField("generateCert", org.apache.thrift.protocol.TType.BOOL, (short)7);

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

  private boolean airavataAutoSchedule; // required
  private boolean overrideManualScheduledParams; // required
  private boolean shareExperimentPublicly; // optional
  private org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel computationalResourceScheduling; // optional
  private boolean throttleResources; // optional
  private String userDN; // optional
  private boolean generateCert; // 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 {
    AIRAVATA_AUTO_SCHEDULE((short)1, "airavataAutoSchedule"),
    OVERRIDE_MANUAL_SCHEDULED_PARAMS((short)2, "overrideManualScheduledParams"),
    SHARE_EXPERIMENT_PUBLICLY((short)3, "shareExperimentPublicly"),
    COMPUTATIONAL_RESOURCE_SCHEDULING((short)4, "computationalResourceScheduling"),
    THROTTLE_RESOURCES((short)5, "throttleResources"),
    USER_DN((short)6, "userDN"),
    GENERATE_CERT((short)7, "generateCert");

    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: // AIRAVATA_AUTO_SCHEDULE
          return AIRAVATA_AUTO_SCHEDULE;
        case 2: // OVERRIDE_MANUAL_SCHEDULED_PARAMS
          return OVERRIDE_MANUAL_SCHEDULED_PARAMS;
        case 3: // SHARE_EXPERIMENT_PUBLICLY
          return SHARE_EXPERIMENT_PUBLICLY;
        case 4: // COMPUTATIONAL_RESOURCE_SCHEDULING
          return COMPUTATIONAL_RESOURCE_SCHEDULING;
        case 5: // THROTTLE_RESOURCES
          return THROTTLE_RESOURCES;
        case 6: // USER_DN
          return USER_DN;
        case 7: // GENERATE_CERT
          return GENERATE_CERT;
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    public static _Fields findByName(String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __AIRAVATAAUTOSCHEDULE_ISSET_ID = 0;
  private static final int __OVERRIDEMANUALSCHEDULEDPARAMS_ISSET_ID = 1;
  private static final int __SHAREEXPERIMENTPUBLICLY_ISSET_ID = 2;
  private static final int __THROTTLERESOURCES_ISSET_ID = 3;
  private static final int __GENERATECERT_ISSET_ID = 4;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.SHARE_EXPERIMENT_PUBLICLY,_Fields.COMPUTATIONAL_RESOURCE_SCHEDULING,_Fields.THROTTLE_RESOURCES,_Fields.USER_DN,_Fields.GENERATE_CERT};
  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.AIRAVATA_AUTO_SCHEDULE, new org.apache.thrift.meta_data.FieldMetaData("airavataAutoSchedule", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.OVERRIDE_MANUAL_SCHEDULED_PARAMS, new org.apache.thrift.meta_data.FieldMetaData("overrideManualScheduledParams", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.SHARE_EXPERIMENT_PUBLICLY, new org.apache.thrift.meta_data.FieldMetaData("shareExperimentPublicly", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.COMPUTATIONAL_RESOURCE_SCHEDULING, new org.apache.thrift.meta_data.FieldMetaData("computationalResourceScheduling", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel.class)));
    tmpMap.put(_Fields.THROTTLE_RESOURCES, new org.apache.thrift.meta_data.FieldMetaData("throttleResources", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.USER_DN, new org.apache.thrift.meta_data.FieldMetaData("userDN", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.GENERATE_CERT, new org.apache.thrift.meta_data.FieldMetaData("generateCert", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(UserConfigurationDataModel.class, metaDataMap);
  }

  public UserConfigurationDataModel() {
    this.airavataAutoSchedule = false;

    this.overrideManualScheduledParams = false;

    this.shareExperimentPublicly = false;

    this.throttleResources = false;

    this.generateCert = false;

  }

  public UserConfigurationDataModel(
    boolean airavataAutoSchedule,
    boolean overrideManualScheduledParams)
  {
    this();
    this.airavataAutoSchedule = airavataAutoSchedule;
    setAiravataAutoScheduleIsSet(true);
    this.overrideManualScheduledParams = overrideManualScheduledParams;
    setOverrideManualScheduledParamsIsSet(true);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public UserConfigurationDataModel(UserConfigurationDataModel other) {
    __isset_bitfield = other.__isset_bitfield;
    this.airavataAutoSchedule = other.airavataAutoSchedule;
    this.overrideManualScheduledParams = other.overrideManualScheduledParams;
    this.shareExperimentPublicly = other.shareExperimentPublicly;
    if (other.isSetComputationalResourceScheduling()) {
      this.computationalResourceScheduling = new org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel(other.computationalResourceScheduling);
    }
    this.throttleResources = other.throttleResources;
    if (other.isSetUserDN()) {
      this.userDN = other.userDN;
    }
    this.generateCert = other.generateCert;
  }

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

  @Override
  public void clear() {
    this.airavataAutoSchedule = false;

    this.overrideManualScheduledParams = false;

    this.shareExperimentPublicly = false;

    this.computationalResourceScheduling = null;
    this.throttleResources = false;

    this.userDN = null;
    this.generateCert = false;

  }

  public boolean isAiravataAutoSchedule() {
    return this.airavataAutoSchedule;
  }

  public void setAiravataAutoSchedule(boolean airavataAutoSchedule) {
    this.airavataAutoSchedule = airavataAutoSchedule;
    setAiravataAutoScheduleIsSet(true);
  }

  public void unsetAiravataAutoSchedule() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AIRAVATAAUTOSCHEDULE_ISSET_ID);
  }

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

  public void setAiravataAutoScheduleIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AIRAVATAAUTOSCHEDULE_ISSET_ID, value);
  }

  public boolean isOverrideManualScheduledParams() {
    return this.overrideManualScheduledParams;
  }

  public void setOverrideManualScheduledParams(boolean overrideManualScheduledParams) {
    this.overrideManualScheduledParams = overrideManualScheduledParams;
    setOverrideManualScheduledParamsIsSet(true);
  }

  public void unsetOverrideManualScheduledParams() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OVERRIDEMANUALSCHEDULEDPARAMS_ISSET_ID);
  }

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

  public void setOverrideManualScheduledParamsIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OVERRIDEMANUALSCHEDULEDPARAMS_ISSET_ID, value);
  }

  public boolean isShareExperimentPublicly() {
    return this.shareExperimentPublicly;
  }

  public void setShareExperimentPublicly(boolean shareExperimentPublicly) {
    this.shareExperimentPublicly = shareExperimentPublicly;
    setShareExperimentPubliclyIsSet(true);
  }

  public void unsetShareExperimentPublicly() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SHAREEXPERIMENTPUBLICLY_ISSET_ID);
  }

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

  public void setShareExperimentPubliclyIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SHAREEXPERIMENTPUBLICLY_ISSET_ID, value);
  }

  public org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel getComputationalResourceScheduling() {
    return this.computationalResourceScheduling;
  }

  public void setComputationalResourceScheduling(org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel computationalResourceScheduling) {
    this.computationalResourceScheduling = computationalResourceScheduling;
  }

  public void unsetComputationalResourceScheduling() {
    this.computationalResourceScheduling = null;
  }

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

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

  public boolean isThrottleResources() {
    return this.throttleResources;
  }

  public void setThrottleResources(boolean throttleResources) {
    this.throttleResources = throttleResources;
    setThrottleResourcesIsSet(true);
  }

  public void unsetThrottleResources() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __THROTTLERESOURCES_ISSET_ID);
  }

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

  public void setThrottleResourcesIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __THROTTLERESOURCES_ISSET_ID, value);
  }

  public String getUserDN() {
    return this.userDN;
  }

  public void setUserDN(String userDN) {
    this.userDN = userDN;
  }

  public void unsetUserDN() {
    this.userDN = null;
  }

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

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

  public boolean isGenerateCert() {
    return this.generateCert;
  }

  public void setGenerateCert(boolean generateCert) {
    this.generateCert = generateCert;
    setGenerateCertIsSet(true);
  }

  public void unsetGenerateCert() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __GENERATECERT_ISSET_ID);
  }

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

  public void setGenerateCertIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __GENERATECERT_ISSET_ID, value);
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case AIRAVATA_AUTO_SCHEDULE:
      if (value == null) {
        unsetAiravataAutoSchedule();
      } else {
        setAiravataAutoSchedule((Boolean)value);
      }
      break;

    case OVERRIDE_MANUAL_SCHEDULED_PARAMS:
      if (value == null) {
        unsetOverrideManualScheduledParams();
      } else {
        setOverrideManualScheduledParams((Boolean)value);
      }
      break;

    case SHARE_EXPERIMENT_PUBLICLY:
      if (value == null) {
        unsetShareExperimentPublicly();
      } else {
        setShareExperimentPublicly((Boolean)value);
      }
      break;

    case COMPUTATIONAL_RESOURCE_SCHEDULING:
      if (value == null) {
        unsetComputationalResourceScheduling();
      } else {
        setComputationalResourceScheduling((org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel)value);
      }
      break;

    case THROTTLE_RESOURCES:
      if (value == null) {
        unsetThrottleResources();
      } else {
        setThrottleResources((Boolean)value);
      }
      break;

    case USER_DN:
      if (value == null) {
        unsetUserDN();
      } else {
        setUserDN((String)value);
      }
      break;

    case GENERATE_CERT:
      if (value == null) {
        unsetGenerateCert();
      } else {
        setGenerateCert((Boolean)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case AIRAVATA_AUTO_SCHEDULE:
      return Boolean.valueOf(isAiravataAutoSchedule());

    case OVERRIDE_MANUAL_SCHEDULED_PARAMS:
      return Boolean.valueOf(isOverrideManualScheduledParams());

    case SHARE_EXPERIMENT_PUBLICLY:
      return Boolean.valueOf(isShareExperimentPublicly());

    case COMPUTATIONAL_RESOURCE_SCHEDULING:
      return getComputationalResourceScheduling();

    case THROTTLE_RESOURCES:
      return Boolean.valueOf(isThrottleResources());

    case USER_DN:
      return getUserDN();

    case GENERATE_CERT:
      return Boolean.valueOf(isGenerateCert());

    }
    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 AIRAVATA_AUTO_SCHEDULE:
      return isSetAiravataAutoSchedule();
    case OVERRIDE_MANUAL_SCHEDULED_PARAMS:
      return isSetOverrideManualScheduledParams();
    case SHARE_EXPERIMENT_PUBLICLY:
      return isSetShareExperimentPublicly();
    case COMPUTATIONAL_RESOURCE_SCHEDULING:
      return isSetComputationalResourceScheduling();
    case THROTTLE_RESOURCES:
      return isSetThrottleResources();
    case USER_DN:
      return isSetUserDN();
    case GENERATE_CERT:
      return isSetGenerateCert();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_airavataAutoSchedule = true;
    boolean that_present_airavataAutoSchedule = true;
    if (this_present_airavataAutoSchedule || that_present_airavataAutoSchedule) {
      if (!(this_present_airavataAutoSchedule && that_present_airavataAutoSchedule))
        return false;
      if (this.airavataAutoSchedule != that.airavataAutoSchedule)
        return false;
    }

    boolean this_present_overrideManualScheduledParams = true;
    boolean that_present_overrideManualScheduledParams = true;
    if (this_present_overrideManualScheduledParams || that_present_overrideManualScheduledParams) {
      if (!(this_present_overrideManualScheduledParams && that_present_overrideManualScheduledParams))
        return false;
      if (this.overrideManualScheduledParams != that.overrideManualScheduledParams)
        return false;
    }

    boolean this_present_shareExperimentPublicly = true && this.isSetShareExperimentPublicly();
    boolean that_present_shareExperimentPublicly = true && that.isSetShareExperimentPublicly();
    if (this_present_shareExperimentPublicly || that_present_shareExperimentPublicly) {
      if (!(this_present_shareExperimentPublicly && that_present_shareExperimentPublicly))
        return false;
      if (this.shareExperimentPublicly != that.shareExperimentPublicly)
        return false;
    }

    boolean this_present_computationalResourceScheduling = true && this.isSetComputationalResourceScheduling();
    boolean that_present_computationalResourceScheduling = true && that.isSetComputationalResourceScheduling();
    if (this_present_computationalResourceScheduling || that_present_computationalResourceScheduling) {
      if (!(this_present_computationalResourceScheduling && that_present_computationalResourceScheduling))
        return false;
      if (!this.computationalResourceScheduling.equals(that.computationalResourceScheduling))
        return false;
    }

    boolean this_present_throttleResources = true && this.isSetThrottleResources();
    boolean that_present_throttleResources = true && that.isSetThrottleResources();
    if (this_present_throttleResources || that_present_throttleResources) {
      if (!(this_present_throttleResources && that_present_throttleResources))
        return false;
      if (this.throttleResources != that.throttleResources)
        return false;
    }

    boolean this_present_userDN = true && this.isSetUserDN();
    boolean that_present_userDN = true && that.isSetUserDN();
    if (this_present_userDN || that_present_userDN) {
      if (!(this_present_userDN && that_present_userDN))
        return false;
      if (!this.userDN.equals(that.userDN))
        return false;
    }

    boolean this_present_generateCert = true && this.isSetGenerateCert();
    boolean that_present_generateCert = true && that.isSetGenerateCert();
    if (this_present_generateCert || that_present_generateCert) {
      if (!(this_present_generateCert && that_present_generateCert))
        return false;
      if (this.generateCert != that.generateCert)
        return false;
    }

    return true;
  }

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

    boolean present_airavataAutoSchedule = true;
    list.add(present_airavataAutoSchedule);
    if (present_airavataAutoSchedule)
      list.add(airavataAutoSchedule);

    boolean present_overrideManualScheduledParams = true;
    list.add(present_overrideManualScheduledParams);
    if (present_overrideManualScheduledParams)
      list.add(overrideManualScheduledParams);

    boolean present_shareExperimentPublicly = true && (isSetShareExperimentPublicly());
    list.add(present_shareExperimentPublicly);
    if (present_shareExperimentPublicly)
      list.add(shareExperimentPublicly);

    boolean present_computationalResourceScheduling = true && (isSetComputationalResourceScheduling());
    list.add(present_computationalResourceScheduling);
    if (present_computationalResourceScheduling)
      list.add(computationalResourceScheduling);

    boolean present_throttleResources = true && (isSetThrottleResources());
    list.add(present_throttleResources);
    if (present_throttleResources)
      list.add(throttleResources);

    boolean present_userDN = true && (isSetUserDN());
    list.add(present_userDN);
    if (present_userDN)
      list.add(userDN);

    boolean present_generateCert = true && (isSetGenerateCert());
    list.add(present_generateCert);
    if (present_generateCert)
      list.add(generateCert);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetAiravataAutoSchedule()).compareTo(other.isSetAiravataAutoSchedule());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAiravataAutoSchedule()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataAutoSchedule, other.airavataAutoSchedule);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetOverrideManualScheduledParams()).compareTo(other.isSetOverrideManualScheduledParams());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOverrideManualScheduledParams()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.overrideManualScheduledParams, other.overrideManualScheduledParams);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetShareExperimentPublicly()).compareTo(other.isSetShareExperimentPublicly());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetShareExperimentPublicly()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.shareExperimentPublicly, other.shareExperimentPublicly);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetComputationalResourceScheduling()).compareTo(other.isSetComputationalResourceScheduling());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetComputationalResourceScheduling()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computationalResourceScheduling, other.computationalResourceScheduling);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetThrottleResources()).compareTo(other.isSetThrottleResources());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetThrottleResources()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.throttleResources, other.throttleResources);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetUserDN()).compareTo(other.isSetUserDN());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUserDN()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userDN, other.userDN);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetGenerateCert()).compareTo(other.isSetGenerateCert());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGenerateCert()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.generateCert, other.generateCert);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    sb.append("airavataAutoSchedule:");
    sb.append(this.airavataAutoSchedule);
    first = false;
    if (!first) sb.append(", ");
    sb.append("overrideManualScheduledParams:");
    sb.append(this.overrideManualScheduledParams);
    first = false;
    if (isSetShareExperimentPublicly()) {
      if (!first) sb.append(", ");
      sb.append("shareExperimentPublicly:");
      sb.append(this.shareExperimentPublicly);
      first = false;
    }
    if (isSetComputationalResourceScheduling()) {
      if (!first) sb.append(", ");
      sb.append("computationalResourceScheduling:");
      if (this.computationalResourceScheduling == null) {
        sb.append("null");
      } else {
        sb.append(this.computationalResourceScheduling);
      }
      first = false;
    }
    if (isSetThrottleResources()) {
      if (!first) sb.append(", ");
      sb.append("throttleResources:");
      sb.append(this.throttleResources);
      first = false;
    }
    if (isSetUserDN()) {
      if (!first) sb.append(", ");
      sb.append("userDN:");
      if (this.userDN == null) {
        sb.append("null");
      } else {
        sb.append(this.userDN);
      }
      first = false;
    }
    if (isSetGenerateCert()) {
      if (!first) sb.append(", ");
      sb.append("generateCert:");
      sb.append(this.generateCert);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

    // check for sub-struct validity
    if (computationalResourceScheduling != null) {
      computationalResourceScheduling.validate();
    }
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
    try {
      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
      __isset_bitfield = 0;
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class UserConfigurationDataModelStandardSchemeFactory implements SchemeFactory {
    public UserConfigurationDataModelStandardScheme getScheme() {
      return new UserConfigurationDataModelStandardScheme();
    }
  }

  private static class UserConfigurationDataModelStandardScheme extends StandardScheme<UserConfigurationDataModel> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, UserConfigurationDataModel 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: // AIRAVATA_AUTO_SCHEDULE
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.airavataAutoSchedule = iprot.readBool();
              struct.setAiravataAutoScheduleIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // OVERRIDE_MANUAL_SCHEDULED_PARAMS
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.overrideManualScheduledParams = iprot.readBool();
              struct.setOverrideManualScheduledParamsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // SHARE_EXPERIMENT_PUBLICLY
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.shareExperimentPublicly = iprot.readBool();
              struct.setShareExperimentPubliclyIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // COMPUTATIONAL_RESOURCE_SCHEDULING
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.computationalResourceScheduling = new org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel();
              struct.computationalResourceScheduling.read(iprot);
              struct.setComputationalResourceSchedulingIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // THROTTLE_RESOURCES
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.throttleResources = iprot.readBool();
              struct.setThrottleResourcesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // USER_DN
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.userDN = iprot.readString();
              struct.setUserDNIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // GENERATE_CERT
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.generateCert = iprot.readBool();
              struct.setGenerateCertIsSet(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, UserConfigurationDataModel struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      oprot.writeFieldBegin(AIRAVATA_AUTO_SCHEDULE_FIELD_DESC);
      oprot.writeBool(struct.airavataAutoSchedule);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(OVERRIDE_MANUAL_SCHEDULED_PARAMS_FIELD_DESC);
      oprot.writeBool(struct.overrideManualScheduledParams);
      oprot.writeFieldEnd();
      if (struct.isSetShareExperimentPublicly()) {
        oprot.writeFieldBegin(SHARE_EXPERIMENT_PUBLICLY_FIELD_DESC);
        oprot.writeBool(struct.shareExperimentPublicly);
        oprot.writeFieldEnd();
      }
      if (struct.computationalResourceScheduling != null) {
        if (struct.isSetComputationalResourceScheduling()) {
          oprot.writeFieldBegin(COMPUTATIONAL_RESOURCE_SCHEDULING_FIELD_DESC);
          struct.computationalResourceScheduling.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetThrottleResources()) {
        oprot.writeFieldBegin(THROTTLE_RESOURCES_FIELD_DESC);
        oprot.writeBool(struct.throttleResources);
        oprot.writeFieldEnd();
      }
      if (struct.userDN != null) {
        if (struct.isSetUserDN()) {
          oprot.writeFieldBegin(USER_DN_FIELD_DESC);
          oprot.writeString(struct.userDN);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetGenerateCert()) {
        oprot.writeFieldBegin(GENERATE_CERT_FIELD_DESC);
        oprot.writeBool(struct.generateCert);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class UserConfigurationDataModelTupleSchemeFactory implements SchemeFactory {
    public UserConfigurationDataModelTupleScheme getScheme() {
      return new UserConfigurationDataModelTupleScheme();
    }
  }

  private static class UserConfigurationDataModelTupleScheme extends TupleScheme<UserConfigurationDataModel> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, UserConfigurationDataModel struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeBool(struct.airavataAutoSchedule);
      oprot.writeBool(struct.overrideManualScheduledParams);
      BitSet optionals = new BitSet();
      if (struct.isSetShareExperimentPublicly()) {
        optionals.set(0);
      }
      if (struct.isSetComputationalResourceScheduling()) {
        optionals.set(1);
      }
      if (struct.isSetThrottleResources()) {
        optionals.set(2);
      }
      if (struct.isSetUserDN()) {
        optionals.set(3);
      }
      if (struct.isSetGenerateCert()) {
        optionals.set(4);
      }
      oprot.writeBitSet(optionals, 5);
      if (struct.isSetShareExperimentPublicly()) {
        oprot.writeBool(struct.shareExperimentPublicly);
      }
      if (struct.isSetComputationalResourceScheduling()) {
        struct.computationalResourceScheduling.write(oprot);
      }
      if (struct.isSetThrottleResources()) {
        oprot.writeBool(struct.throttleResources);
      }
      if (struct.isSetUserDN()) {
        oprot.writeString(struct.userDN);
      }
      if (struct.isSetGenerateCert()) {
        oprot.writeBool(struct.generateCert);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, UserConfigurationDataModel struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.airavataAutoSchedule = iprot.readBool();
      struct.setAiravataAutoScheduleIsSet(true);
      struct.overrideManualScheduledParams = iprot.readBool();
      struct.setOverrideManualScheduledParamsIsSet(true);
      BitSet incoming = iprot.readBitSet(5);
      if (incoming.get(0)) {
        struct.shareExperimentPublicly = iprot.readBool();
        struct.setShareExperimentPubliclyIsSet(true);
      }
      if (incoming.get(1)) {
        struct.computationalResourceScheduling = new org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel();
        struct.computationalResourceScheduling.read(iprot);
        struct.setComputationalResourceSchedulingIsSet(true);
      }
      if (incoming.get(2)) {
        struct.throttleResources = iprot.readBool();
        struct.setThrottleResourcesIsSet(true);
      }
      if (incoming.get(3)) {
        struct.userDN = iprot.readString();
        struct.setUserDNIsSet(true);
      }
      if (incoming.get(4)) {
        struct.generateCert = iprot.readBool();
        struct.setGenerateCertIsSet(true);
      }
    }
  }

}

