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

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

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"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
public class DataProductModel implements org.apache.thrift.TBase<DataProductModel, DataProductModel._Fields>, java.io.Serializable, Cloneable, Comparable<DataProductModel> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("DataProductModel");

  private static final org.apache.thrift.protocol.TField PRODUCT_URI_FIELD_DESC = new org.apache.thrift.protocol.TField("productUri", 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 PARENT_PRODUCT_URI_FIELD_DESC = new org.apache.thrift.protocol.TField("parentProductUri", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField PRODUCT_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("productName", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField PRODUCT_DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("productDescription", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField OWNER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("ownerName", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField DATA_PRODUCT_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("dataProductType", org.apache.thrift.protocol.TType.I32, (short)7);
  private static final org.apache.thrift.protocol.TField PRODUCT_SIZE_FIELD_DESC = new org.apache.thrift.protocol.TField("productSize", org.apache.thrift.protocol.TType.I32, (short)8);
  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)9);
  private static final org.apache.thrift.protocol.TField LAST_MODIFIED_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("lastModifiedTime", org.apache.thrift.protocol.TType.I64, (short)10);
  private static final org.apache.thrift.protocol.TField PRODUCT_METADATA_FIELD_DESC = new org.apache.thrift.protocol.TField("productMetadata", org.apache.thrift.protocol.TType.MAP, (short)11);
  private static final org.apache.thrift.protocol.TField REPLICA_LOCATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("replicaLocations", org.apache.thrift.protocol.TType.LIST, (short)12);

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

  private String productUri; // optional
  private String gatewayId; // optional
  private String parentProductUri; // optional
  private String productName; // optional
  private String productDescription; // optional
  private String ownerName; // optional
  private DataProductType dataProductType; // optional
  private int productSize; // optional
  private long creationTime; // optional
  private long lastModifiedTime; // optional
  private Map<String,String> productMetadata; // optional
  private List<DataReplicaLocationModel> replicaLocations; // 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 {
    PRODUCT_URI((short)1, "productUri"),
    GATEWAY_ID((short)2, "gatewayId"),
    PARENT_PRODUCT_URI((short)3, "parentProductUri"),
    PRODUCT_NAME((short)4, "productName"),
    PRODUCT_DESCRIPTION((short)5, "productDescription"),
    OWNER_NAME((short)6, "ownerName"),
    /**
     * 
     * @see DataProductType
     */
    DATA_PRODUCT_TYPE((short)7, "dataProductType"),
    PRODUCT_SIZE((short)8, "productSize"),
    CREATION_TIME((short)9, "creationTime"),
    LAST_MODIFIED_TIME((short)10, "lastModifiedTime"),
    PRODUCT_METADATA((short)11, "productMetadata"),
    REPLICA_LOCATIONS((short)12, "replicaLocations");

    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: // PRODUCT_URI
          return PRODUCT_URI;
        case 2: // GATEWAY_ID
          return GATEWAY_ID;
        case 3: // PARENT_PRODUCT_URI
          return PARENT_PRODUCT_URI;
        case 4: // PRODUCT_NAME
          return PRODUCT_NAME;
        case 5: // PRODUCT_DESCRIPTION
          return PRODUCT_DESCRIPTION;
        case 6: // OWNER_NAME
          return OWNER_NAME;
        case 7: // DATA_PRODUCT_TYPE
          return DATA_PRODUCT_TYPE;
        case 8: // PRODUCT_SIZE
          return PRODUCT_SIZE;
        case 9: // CREATION_TIME
          return CREATION_TIME;
        case 10: // LAST_MODIFIED_TIME
          return LAST_MODIFIED_TIME;
        case 11: // PRODUCT_METADATA
          return PRODUCT_METADATA;
        case 12: // REPLICA_LOCATIONS
          return REPLICA_LOCATIONS;
        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 __PRODUCTSIZE_ISSET_ID = 0;
  private static final int __CREATIONTIME_ISSET_ID = 1;
  private static final int __LASTMODIFIEDTIME_ISSET_ID = 2;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.PRODUCT_URI,_Fields.GATEWAY_ID,_Fields.PARENT_PRODUCT_URI,_Fields.PRODUCT_NAME,_Fields.PRODUCT_DESCRIPTION,_Fields.OWNER_NAME,_Fields.DATA_PRODUCT_TYPE,_Fields.PRODUCT_SIZE,_Fields.CREATION_TIME,_Fields.LAST_MODIFIED_TIME,_Fields.PRODUCT_METADATA,_Fields.REPLICA_LOCATIONS};
  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.PRODUCT_URI, new org.apache.thrift.meta_data.FieldMetaData("productUri", 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.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PARENT_PRODUCT_URI, new org.apache.thrift.meta_data.FieldMetaData("parentProductUri", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PRODUCT_NAME, new org.apache.thrift.meta_data.FieldMetaData("productName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PRODUCT_DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("productDescription", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.OWNER_NAME, new org.apache.thrift.meta_data.FieldMetaData("ownerName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.DATA_PRODUCT_TYPE, new org.apache.thrift.meta_data.FieldMetaData("dataProductType", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, DataProductType.class)));
    tmpMap.put(_Fields.PRODUCT_SIZE, new org.apache.thrift.meta_data.FieldMetaData("productSize", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    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.LAST_MODIFIED_TIME, new org.apache.thrift.meta_data.FieldMetaData("lastModifiedTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.PRODUCT_METADATA, new org.apache.thrift.meta_data.FieldMetaData("productMetadata", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.REPLICA_LOCATIONS, new org.apache.thrift.meta_data.FieldMetaData("replicaLocations", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT            , "DataReplicaLocationModel"))));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(DataProductModel.class, metaDataMap);
  }

  public DataProductModel() {
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public DataProductModel(DataProductModel other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetProductUri()) {
      this.productUri = other.productUri;
    }
    if (other.isSetGatewayId()) {
      this.gatewayId = other.gatewayId;
    }
    if (other.isSetParentProductUri()) {
      this.parentProductUri = other.parentProductUri;
    }
    if (other.isSetProductName()) {
      this.productName = other.productName;
    }
    if (other.isSetProductDescription()) {
      this.productDescription = other.productDescription;
    }
    if (other.isSetOwnerName()) {
      this.ownerName = other.ownerName;
    }
    if (other.isSetDataProductType()) {
      this.dataProductType = other.dataProductType;
    }
    this.productSize = other.productSize;
    this.creationTime = other.creationTime;
    this.lastModifiedTime = other.lastModifiedTime;
    if (other.isSetProductMetadata()) {
      Map<String,String> __this__productMetadata = new HashMap<String,String>(other.productMetadata);
      this.productMetadata = __this__productMetadata;
    }
    if (other.isSetReplicaLocations()) {
      List<DataReplicaLocationModel> __this__replicaLocations = new ArrayList<DataReplicaLocationModel>(other.replicaLocations.size());
      for (DataReplicaLocationModel other_element : other.replicaLocations) {
        __this__replicaLocations.add(other_element);
      }
      this.replicaLocations = __this__replicaLocations;
    }
  }

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

  @Override
  public void clear() {
    this.productUri = null;
    this.gatewayId = null;
    this.parentProductUri = null;
    this.productName = null;
    this.productDescription = null;
    this.ownerName = null;
    this.dataProductType = null;
    setProductSizeIsSet(false);
    this.productSize = 0;
    setCreationTimeIsSet(false);
    this.creationTime = 0;
    setLastModifiedTimeIsSet(false);
    this.lastModifiedTime = 0;
    this.productMetadata = null;
    this.replicaLocations = null;
  }

  public String getProductUri() {
    return this.productUri;
  }

  public void setProductUri(String productUri) {
    this.productUri = productUri;
  }

  public void unsetProductUri() {
    this.productUri = null;
  }

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

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

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

  public void setGatewayId(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 String getParentProductUri() {
    return this.parentProductUri;
  }

  public void setParentProductUri(String parentProductUri) {
    this.parentProductUri = parentProductUri;
  }

  public void unsetParentProductUri() {
    this.parentProductUri = null;
  }

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

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

  public String getProductName() {
    return this.productName;
  }

  public void setProductName(String productName) {
    this.productName = productName;
  }

  public void unsetProductName() {
    this.productName = null;
  }

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

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

  public String getProductDescription() {
    return this.productDescription;
  }

  public void setProductDescription(String productDescription) {
    this.productDescription = productDescription;
  }

  public void unsetProductDescription() {
    this.productDescription = null;
  }

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

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

  public String getOwnerName() {
    return this.ownerName;
  }

  public void setOwnerName(String ownerName) {
    this.ownerName = ownerName;
  }

  public void unsetOwnerName() {
    this.ownerName = null;
  }

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

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

  /**
   * 
   * @see DataProductType
   */
  public DataProductType getDataProductType() {
    return this.dataProductType;
  }

  /**
   * 
   * @see DataProductType
   */
  public void setDataProductType(DataProductType dataProductType) {
    this.dataProductType = dataProductType;
  }

  public void unsetDataProductType() {
    this.dataProductType = null;
  }

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

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

  public int getProductSize() {
    return this.productSize;
  }

  public void setProductSize(int productSize) {
    this.productSize = productSize;
    setProductSizeIsSet(true);
  }

  public void unsetProductSize() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRODUCTSIZE_ISSET_ID);
  }

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

  public void setProductSizeIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRODUCTSIZE_ISSET_ID, value);
  }

  public long getCreationTime() {
    return this.creationTime;
  }

  public void setCreationTime(long creationTime) {
    this.creationTime = creationTime;
    setCreationTimeIsSet(true);
  }

  public void unsetCreationTime() {
    __isset_bitfield = 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 EncodingUtils.testBit(__isset_bitfield, __CREATIONTIME_ISSET_ID);
  }

  public void setCreationTimeIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __CREATIONTIME_ISSET_ID, value);
  }

  public long getLastModifiedTime() {
    return this.lastModifiedTime;
  }

  public void setLastModifiedTime(long lastModifiedTime) {
    this.lastModifiedTime = lastModifiedTime;
    setLastModifiedTimeIsSet(true);
  }

  public void unsetLastModifiedTime() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LASTMODIFIEDTIME_ISSET_ID);
  }

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

  public void setLastModifiedTimeIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LASTMODIFIEDTIME_ISSET_ID, value);
  }

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

  public void putToProductMetadata(String key, String val) {
    if (this.productMetadata == null) {
      this.productMetadata = new HashMap<String,String>();
    }
    this.productMetadata.put(key, val);
  }

  public Map<String,String> getProductMetadata() {
    return this.productMetadata;
  }

  public void setProductMetadata(Map<String,String> productMetadata) {
    this.productMetadata = productMetadata;
  }

  public void unsetProductMetadata() {
    this.productMetadata = null;
  }

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

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

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

  public java.util.Iterator<DataReplicaLocationModel> getReplicaLocationsIterator() {
    return (this.replicaLocations == null) ? null : this.replicaLocations.iterator();
  }

  public void addToReplicaLocations(DataReplicaLocationModel elem) {
    if (this.replicaLocations == null) {
      this.replicaLocations = new ArrayList<DataReplicaLocationModel>();
    }
    this.replicaLocations.add(elem);
  }

  public List<DataReplicaLocationModel> getReplicaLocations() {
    return this.replicaLocations;
  }

  public void setReplicaLocations(List<DataReplicaLocationModel> replicaLocations) {
    this.replicaLocations = replicaLocations;
  }

  public void unsetReplicaLocations() {
    this.replicaLocations = null;
  }

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

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

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case PRODUCT_URI:
      if (value == null) {
        unsetProductUri();
      } else {
        setProductUri((String)value);
      }
      break;

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

    case PARENT_PRODUCT_URI:
      if (value == null) {
        unsetParentProductUri();
      } else {
        setParentProductUri((String)value);
      }
      break;

    case PRODUCT_NAME:
      if (value == null) {
        unsetProductName();
      } else {
        setProductName((String)value);
      }
      break;

    case PRODUCT_DESCRIPTION:
      if (value == null) {
        unsetProductDescription();
      } else {
        setProductDescription((String)value);
      }
      break;

    case OWNER_NAME:
      if (value == null) {
        unsetOwnerName();
      } else {
        setOwnerName((String)value);
      }
      break;

    case DATA_PRODUCT_TYPE:
      if (value == null) {
        unsetDataProductType();
      } else {
        setDataProductType((DataProductType)value);
      }
      break;

    case PRODUCT_SIZE:
      if (value == null) {
        unsetProductSize();
      } else {
        setProductSize((Integer)value);
      }
      break;

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

    case LAST_MODIFIED_TIME:
      if (value == null) {
        unsetLastModifiedTime();
      } else {
        setLastModifiedTime((Long)value);
      }
      break;

    case PRODUCT_METADATA:
      if (value == null) {
        unsetProductMetadata();
      } else {
        setProductMetadata((Map<String,String>)value);
      }
      break;

    case REPLICA_LOCATIONS:
      if (value == null) {
        unsetReplicaLocations();
      } else {
        setReplicaLocations((List<DataReplicaLocationModel>)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case PRODUCT_URI:
      return getProductUri();

    case GATEWAY_ID:
      return getGatewayId();

    case PARENT_PRODUCT_URI:
      return getParentProductUri();

    case PRODUCT_NAME:
      return getProductName();

    case PRODUCT_DESCRIPTION:
      return getProductDescription();

    case OWNER_NAME:
      return getOwnerName();

    case DATA_PRODUCT_TYPE:
      return getDataProductType();

    case PRODUCT_SIZE:
      return getProductSize();

    case CREATION_TIME:
      return getCreationTime();

    case LAST_MODIFIED_TIME:
      return getLastModifiedTime();

    case PRODUCT_METADATA:
      return getProductMetadata();

    case REPLICA_LOCATIONS:
      return getReplicaLocations();

    }
    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 PRODUCT_URI:
      return isSetProductUri();
    case GATEWAY_ID:
      return isSetGatewayId();
    case PARENT_PRODUCT_URI:
      return isSetParentProductUri();
    case PRODUCT_NAME:
      return isSetProductName();
    case PRODUCT_DESCRIPTION:
      return isSetProductDescription();
    case OWNER_NAME:
      return isSetOwnerName();
    case DATA_PRODUCT_TYPE:
      return isSetDataProductType();
    case PRODUCT_SIZE:
      return isSetProductSize();
    case CREATION_TIME:
      return isSetCreationTime();
    case LAST_MODIFIED_TIME:
      return isSetLastModifiedTime();
    case PRODUCT_METADATA:
      return isSetProductMetadata();
    case REPLICA_LOCATIONS:
      return isSetReplicaLocations();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_productUri = true && this.isSetProductUri();
    boolean that_present_productUri = true && that.isSetProductUri();
    if (this_present_productUri || that_present_productUri) {
      if (!(this_present_productUri && that_present_productUri))
        return false;
      if (!this.productUri.equals(that.productUri))
        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_parentProductUri = true && this.isSetParentProductUri();
    boolean that_present_parentProductUri = true && that.isSetParentProductUri();
    if (this_present_parentProductUri || that_present_parentProductUri) {
      if (!(this_present_parentProductUri && that_present_parentProductUri))
        return false;
      if (!this.parentProductUri.equals(that.parentProductUri))
        return false;
    }

    boolean this_present_productName = true && this.isSetProductName();
    boolean that_present_productName = true && that.isSetProductName();
    if (this_present_productName || that_present_productName) {
      if (!(this_present_productName && that_present_productName))
        return false;
      if (!this.productName.equals(that.productName))
        return false;
    }

    boolean this_present_productDescription = true && this.isSetProductDescription();
    boolean that_present_productDescription = true && that.isSetProductDescription();
    if (this_present_productDescription || that_present_productDescription) {
      if (!(this_present_productDescription && that_present_productDescription))
        return false;
      if (!this.productDescription.equals(that.productDescription))
        return false;
    }

    boolean this_present_ownerName = true && this.isSetOwnerName();
    boolean that_present_ownerName = true && that.isSetOwnerName();
    if (this_present_ownerName || that_present_ownerName) {
      if (!(this_present_ownerName && that_present_ownerName))
        return false;
      if (!this.ownerName.equals(that.ownerName))
        return false;
    }

    boolean this_present_dataProductType = true && this.isSetDataProductType();
    boolean that_present_dataProductType = true && that.isSetDataProductType();
    if (this_present_dataProductType || that_present_dataProductType) {
      if (!(this_present_dataProductType && that_present_dataProductType))
        return false;
      if (!this.dataProductType.equals(that.dataProductType))
        return false;
    }

    boolean this_present_productSize = true && this.isSetProductSize();
    boolean that_present_productSize = true && that.isSetProductSize();
    if (this_present_productSize || that_present_productSize) {
      if (!(this_present_productSize && that_present_productSize))
        return false;
      if (this.productSize != that.productSize)
        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_lastModifiedTime = true && this.isSetLastModifiedTime();
    boolean that_present_lastModifiedTime = true && that.isSetLastModifiedTime();
    if (this_present_lastModifiedTime || that_present_lastModifiedTime) {
      if (!(this_present_lastModifiedTime && that_present_lastModifiedTime))
        return false;
      if (this.lastModifiedTime != that.lastModifiedTime)
        return false;
    }

    boolean this_present_productMetadata = true && this.isSetProductMetadata();
    boolean that_present_productMetadata = true && that.isSetProductMetadata();
    if (this_present_productMetadata || that_present_productMetadata) {
      if (!(this_present_productMetadata && that_present_productMetadata))
        return false;
      if (!this.productMetadata.equals(that.productMetadata))
        return false;
    }

    boolean this_present_replicaLocations = true && this.isSetReplicaLocations();
    boolean that_present_replicaLocations = true && that.isSetReplicaLocations();
    if (this_present_replicaLocations || that_present_replicaLocations) {
      if (!(this_present_replicaLocations && that_present_replicaLocations))
        return false;
      if (!this.replicaLocations.equals(that.replicaLocations))
        return false;
    }

    return true;
  }

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

    boolean present_productUri = true && (isSetProductUri());
    list.add(present_productUri);
    if (present_productUri)
      list.add(productUri);

    boolean present_gatewayId = true && (isSetGatewayId());
    list.add(present_gatewayId);
    if (present_gatewayId)
      list.add(gatewayId);

    boolean present_parentProductUri = true && (isSetParentProductUri());
    list.add(present_parentProductUri);
    if (present_parentProductUri)
      list.add(parentProductUri);

    boolean present_productName = true && (isSetProductName());
    list.add(present_productName);
    if (present_productName)
      list.add(productName);

    boolean present_productDescription = true && (isSetProductDescription());
    list.add(present_productDescription);
    if (present_productDescription)
      list.add(productDescription);

    boolean present_ownerName = true && (isSetOwnerName());
    list.add(present_ownerName);
    if (present_ownerName)
      list.add(ownerName);

    boolean present_dataProductType = true && (isSetDataProductType());
    list.add(present_dataProductType);
    if (present_dataProductType)
      list.add(dataProductType.getValue());

    boolean present_productSize = true && (isSetProductSize());
    list.add(present_productSize);
    if (present_productSize)
      list.add(productSize);

    boolean present_creationTime = true && (isSetCreationTime());
    list.add(present_creationTime);
    if (present_creationTime)
      list.add(creationTime);

    boolean present_lastModifiedTime = true && (isSetLastModifiedTime());
    list.add(present_lastModifiedTime);
    if (present_lastModifiedTime)
      list.add(lastModifiedTime);

    boolean present_productMetadata = true && (isSetProductMetadata());
    list.add(present_productMetadata);
    if (present_productMetadata)
      list.add(productMetadata);

    boolean present_replicaLocations = true && (isSetReplicaLocations());
    list.add(present_replicaLocations);
    if (present_replicaLocations)
      list.add(replicaLocations);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetProductUri()).compareTo(other.isSetProductUri());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProductUri()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.productUri, other.productUri);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = 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 = Boolean.valueOf(isSetParentProductUri()).compareTo(other.isSetParentProductUri());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetParentProductUri()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentProductUri, other.parentProductUri);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetProductName()).compareTo(other.isSetProductName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProductName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.productName, other.productName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetProductDescription()).compareTo(other.isSetProductDescription());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProductDescription()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.productDescription, other.productDescription);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetOwnerName()).compareTo(other.isSetOwnerName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOwnerName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ownerName, other.ownerName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetDataProductType()).compareTo(other.isSetDataProductType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDataProductType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataProductType, other.dataProductType);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetProductSize()).compareTo(other.isSetProductSize());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProductSize()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.productSize, other.productSize);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = 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 = Boolean.valueOf(isSetLastModifiedTime()).compareTo(other.isSetLastModifiedTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetLastModifiedTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.lastModifiedTime, other.lastModifiedTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetProductMetadata()).compareTo(other.isSetProductMetadata());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProductMetadata()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.productMetadata, other.productMetadata);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetReplicaLocations()).compareTo(other.isSetReplicaLocations());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetReplicaLocations()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.replicaLocations, other.replicaLocations);
      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("DataProductModel(");
    boolean first = true;

    if (isSetProductUri()) {
      sb.append("productUri:");
      if (this.productUri == null) {
        sb.append("null");
      } else {
        sb.append(this.productUri);
      }
      first = false;
    }
    if (isSetGatewayId()) {
      if (!first) sb.append(", ");
      sb.append("gatewayId:");
      if (this.gatewayId == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayId);
      }
      first = false;
    }
    if (isSetParentProductUri()) {
      if (!first) sb.append(", ");
      sb.append("parentProductUri:");
      if (this.parentProductUri == null) {
        sb.append("null");
      } else {
        sb.append(this.parentProductUri);
      }
      first = false;
    }
    if (isSetProductName()) {
      if (!first) sb.append(", ");
      sb.append("productName:");
      if (this.productName == null) {
        sb.append("null");
      } else {
        sb.append(this.productName);
      }
      first = false;
    }
    if (isSetProductDescription()) {
      if (!first) sb.append(", ");
      sb.append("productDescription:");
      if (this.productDescription == null) {
        sb.append("null");
      } else {
        sb.append(this.productDescription);
      }
      first = false;
    }
    if (isSetOwnerName()) {
      if (!first) sb.append(", ");
      sb.append("ownerName:");
      if (this.ownerName == null) {
        sb.append("null");
      } else {
        sb.append(this.ownerName);
      }
      first = false;
    }
    if (isSetDataProductType()) {
      if (!first) sb.append(", ");
      sb.append("dataProductType:");
      if (this.dataProductType == null) {
        sb.append("null");
      } else {
        sb.append(this.dataProductType);
      }
      first = false;
    }
    if (isSetProductSize()) {
      if (!first) sb.append(", ");
      sb.append("productSize:");
      sb.append(this.productSize);
      first = false;
    }
    if (isSetCreationTime()) {
      if (!first) sb.append(", ");
      sb.append("creationTime:");
      sb.append(this.creationTime);
      first = false;
    }
    if (isSetLastModifiedTime()) {
      if (!first) sb.append(", ");
      sb.append("lastModifiedTime:");
      sb.append(this.lastModifiedTime);
      first = false;
    }
    if (isSetProductMetadata()) {
      if (!first) sb.append(", ");
      sb.append("productMetadata:");
      if (this.productMetadata == null) {
        sb.append("null");
      } else {
        sb.append(this.productMetadata);
      }
      first = false;
    }
    if (isSetReplicaLocations()) {
      if (!first) sb.append(", ");
      sb.append("replicaLocations:");
      if (this.replicaLocations == null) {
        sb.append("null");
      } else {
        sb.append(this.replicaLocations);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    // check for sub-struct validity
  }

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

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

  private static class DataProductModelStandardSchemeFactory implements SchemeFactory {
    public DataProductModelStandardScheme getScheme() {
      return new DataProductModelStandardScheme();
    }
  }

  private static class DataProductModelStandardScheme extends StandardScheme<DataProductModel> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, DataProductModel 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: // PRODUCT_URI
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.productUri = iprot.readString();
              struct.setProductUriIsSet(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: // PARENT_PRODUCT_URI
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.parentProductUri = iprot.readString();
              struct.setParentProductUriIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // PRODUCT_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.productName = iprot.readString();
              struct.setProductNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // PRODUCT_DESCRIPTION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.productDescription = iprot.readString();
              struct.setProductDescriptionIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // OWNER_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.ownerName = iprot.readString();
              struct.setOwnerNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // DATA_PRODUCT_TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.dataProductType = org.apache.airavata.model.data.replica.DataProductType.findByValue(iprot.readI32());
              struct.setDataProductTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // PRODUCT_SIZE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.productSize = iprot.readI32();
              struct.setProductSizeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // 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 10: // LAST_MODIFIED_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.lastModifiedTime = iprot.readI64();
              struct.setLastModifiedTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // PRODUCT_METADATA
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map0 = iprot.readMapBegin();
                struct.productMetadata = new HashMap<String,String>(2*_map0.size);
                String _key1;
                String _val2;
                for (int _i3 = 0; _i3 < _map0.size; ++_i3)
                {
                  _key1 = iprot.readString();
                  _val2 = iprot.readString();
                  struct.productMetadata.put(_key1, _val2);
                }
                iprot.readMapEnd();
              }
              struct.setProductMetadataIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // REPLICA_LOCATIONS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list4 = iprot.readListBegin();
                struct.replicaLocations = new ArrayList<DataReplicaLocationModel>(_list4.size);
                DataReplicaLocationModel _elem5;
                for (int _i6 = 0; _i6 < _list4.size; ++_i6)
                {
                  _elem5 = new DataReplicaLocationModel();
                  _elem5.read(iprot);
                  struct.replicaLocations.add(_elem5);
                }
                iprot.readListEnd();
              }
              struct.setReplicaLocationsIsSet(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, DataProductModel struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.productUri != null) {
        if (struct.isSetProductUri()) {
          oprot.writeFieldBegin(PRODUCT_URI_FIELD_DESC);
          oprot.writeString(struct.productUri);
          oprot.writeFieldEnd();
        }
      }
      if (struct.gatewayId != null) {
        if (struct.isSetGatewayId()) {
          oprot.writeFieldBegin(GATEWAY_ID_FIELD_DESC);
          oprot.writeString(struct.gatewayId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.parentProductUri != null) {
        if (struct.isSetParentProductUri()) {
          oprot.writeFieldBegin(PARENT_PRODUCT_URI_FIELD_DESC);
          oprot.writeString(struct.parentProductUri);
          oprot.writeFieldEnd();
        }
      }
      if (struct.productName != null) {
        if (struct.isSetProductName()) {
          oprot.writeFieldBegin(PRODUCT_NAME_FIELD_DESC);
          oprot.writeString(struct.productName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.productDescription != null) {
        if (struct.isSetProductDescription()) {
          oprot.writeFieldBegin(PRODUCT_DESCRIPTION_FIELD_DESC);
          oprot.writeString(struct.productDescription);
          oprot.writeFieldEnd();
        }
      }
      if (struct.ownerName != null) {
        if (struct.isSetOwnerName()) {
          oprot.writeFieldBegin(OWNER_NAME_FIELD_DESC);
          oprot.writeString(struct.ownerName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.dataProductType != null) {
        if (struct.isSetDataProductType()) {
          oprot.writeFieldBegin(DATA_PRODUCT_TYPE_FIELD_DESC);
          oprot.writeI32(struct.dataProductType.getValue());
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetProductSize()) {
        oprot.writeFieldBegin(PRODUCT_SIZE_FIELD_DESC);
        oprot.writeI32(struct.productSize);
        oprot.writeFieldEnd();
      }
      if (struct.isSetCreationTime()) {
        oprot.writeFieldBegin(CREATION_TIME_FIELD_DESC);
        oprot.writeI64(struct.creationTime);
        oprot.writeFieldEnd();
      }
      if (struct.isSetLastModifiedTime()) {
        oprot.writeFieldBegin(LAST_MODIFIED_TIME_FIELD_DESC);
        oprot.writeI64(struct.lastModifiedTime);
        oprot.writeFieldEnd();
      }
      if (struct.productMetadata != null) {
        if (struct.isSetProductMetadata()) {
          oprot.writeFieldBegin(PRODUCT_METADATA_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.productMetadata.size()));
            for (Map.Entry<String, String> _iter7 : struct.productMetadata.entrySet())
            {
              oprot.writeString(_iter7.getKey());
              oprot.writeString(_iter7.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.replicaLocations != null) {
        if (struct.isSetReplicaLocations()) {
          oprot.writeFieldBegin(REPLICA_LOCATIONS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.replicaLocations.size()));
            for (DataReplicaLocationModel _iter8 : struct.replicaLocations)
            {
              _iter8.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class DataProductModelTupleSchemeFactory implements SchemeFactory {
    public DataProductModelTupleScheme getScheme() {
      return new DataProductModelTupleScheme();
    }
  }

  private static class DataProductModelTupleScheme extends TupleScheme<DataProductModel> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, DataProductModel struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      BitSet optionals = new BitSet();
      if (struct.isSetProductUri()) {
        optionals.set(0);
      }
      if (struct.isSetGatewayId()) {
        optionals.set(1);
      }
      if (struct.isSetParentProductUri()) {
        optionals.set(2);
      }
      if (struct.isSetProductName()) {
        optionals.set(3);
      }
      if (struct.isSetProductDescription()) {
        optionals.set(4);
      }
      if (struct.isSetOwnerName()) {
        optionals.set(5);
      }
      if (struct.isSetDataProductType()) {
        optionals.set(6);
      }
      if (struct.isSetProductSize()) {
        optionals.set(7);
      }
      if (struct.isSetCreationTime()) {
        optionals.set(8);
      }
      if (struct.isSetLastModifiedTime()) {
        optionals.set(9);
      }
      if (struct.isSetProductMetadata()) {
        optionals.set(10);
      }
      if (struct.isSetReplicaLocations()) {
        optionals.set(11);
      }
      oprot.writeBitSet(optionals, 12);
      if (struct.isSetProductUri()) {
        oprot.writeString(struct.productUri);
      }
      if (struct.isSetGatewayId()) {
        oprot.writeString(struct.gatewayId);
      }
      if (struct.isSetParentProductUri()) {
        oprot.writeString(struct.parentProductUri);
      }
      if (struct.isSetProductName()) {
        oprot.writeString(struct.productName);
      }
      if (struct.isSetProductDescription()) {
        oprot.writeString(struct.productDescription);
      }
      if (struct.isSetOwnerName()) {
        oprot.writeString(struct.ownerName);
      }
      if (struct.isSetDataProductType()) {
        oprot.writeI32(struct.dataProductType.getValue());
      }
      if (struct.isSetProductSize()) {
        oprot.writeI32(struct.productSize);
      }
      if (struct.isSetCreationTime()) {
        oprot.writeI64(struct.creationTime);
      }
      if (struct.isSetLastModifiedTime()) {
        oprot.writeI64(struct.lastModifiedTime);
      }
      if (struct.isSetProductMetadata()) {
        {
          oprot.writeI32(struct.productMetadata.size());
          for (Map.Entry<String, String> _iter9 : struct.productMetadata.entrySet())
          {
            oprot.writeString(_iter9.getKey());
            oprot.writeString(_iter9.getValue());
          }
        }
      }
      if (struct.isSetReplicaLocations()) {
        {
          oprot.writeI32(struct.replicaLocations.size());
          for (DataReplicaLocationModel _iter10 : struct.replicaLocations)
          {
            _iter10.write(oprot);
          }
        }
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, DataProductModel struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      BitSet incoming = iprot.readBitSet(12);
      if (incoming.get(0)) {
        struct.productUri = iprot.readString();
        struct.setProductUriIsSet(true);
      }
      if (incoming.get(1)) {
        struct.gatewayId = iprot.readString();
        struct.setGatewayIdIsSet(true);
      }
      if (incoming.get(2)) {
        struct.parentProductUri = iprot.readString();
        struct.setParentProductUriIsSet(true);
      }
      if (incoming.get(3)) {
        struct.productName = iprot.readString();
        struct.setProductNameIsSet(true);
      }
      if (incoming.get(4)) {
        struct.productDescription = iprot.readString();
        struct.setProductDescriptionIsSet(true);
      }
      if (incoming.get(5)) {
        struct.ownerName = iprot.readString();
        struct.setOwnerNameIsSet(true);
      }
      if (incoming.get(6)) {
        struct.dataProductType = org.apache.airavata.model.data.replica.DataProductType.findByValue(iprot.readI32());
        struct.setDataProductTypeIsSet(true);
      }
      if (incoming.get(7)) {
        struct.productSize = iprot.readI32();
        struct.setProductSizeIsSet(true);
      }
      if (incoming.get(8)) {
        struct.creationTime = iprot.readI64();
        struct.setCreationTimeIsSet(true);
      }
      if (incoming.get(9)) {
        struct.lastModifiedTime = iprot.readI64();
        struct.setLastModifiedTimeIsSet(true);
      }
      if (incoming.get(10)) {
        {
          org.apache.thrift.protocol.TMap _map11 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.productMetadata = new HashMap<String,String>(2*_map11.size);
          String _key12;
          String _val13;
          for (int _i14 = 0; _i14 < _map11.size; ++_i14)
          {
            _key12 = iprot.readString();
            _val13 = iprot.readString();
            struct.productMetadata.put(_key12, _val13);
          }
        }
        struct.setProductMetadataIsSet(true);
      }
      if (incoming.get(11)) {
        {
          org.apache.thrift.protocol.TList _list15 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.replicaLocations = new ArrayList<DataReplicaLocationModel>(_list15.size);
          DataReplicaLocationModel _elem16;
          for (int _i17 = 0; _i17 < _list15.size; ++_i17)
          {
            _elem16 = new DataReplicaLocationModel();
            _elem16.read(iprot);
            struct.replicaLocations.add(_elem16);
          }
        }
        struct.setReplicaLocationsIsSet(true);
      }
    }
  }

}

