All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.pdx.internal.WritablePdxInstanceImpl Maven / Gradle / Ivy

/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed 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. See accompanying
 * LICENSE file.
 */
package com.gemstone.gemfire.pdx.internal;

import java.nio.ByteBuffer;
import java.util.Date;
import com.gemstone.gemfire.InternalGemFireException;
import com.gemstone.gemfire.pdx.PdxFieldDoesNotExistException;
import com.gemstone.gemfire.pdx.PdxFieldTypeMismatchException;
import com.gemstone.gemfire.pdx.WritablePdxInstance;

public class WritablePdxInstanceImpl extends PdxInstanceImpl implements
    WritablePdxInstance {
  private static final long serialVersionUID = 7398999150097596214L;
  private static final Object NULL_TOKEN = new Object();
  private Object[] dirtyFields = null;

  public WritablePdxInstanceImpl(PdxReaderImpl original) {
    super(original);
  }

  private synchronized void dirtyField(PdxField f, Object value) {
    if (this.dirtyFields == null) {
      this.dirtyFields = new Object[getPdxType().getFieldCount()];
    }
    if (value == null) {
      value = NULL_TOKEN;
    }
    this.dirtyFields[f.getFieldIndex()] = value;
    clearCachedState();
  }
  /**
   * Flush pending writes if the given field is dirty.
   */
  @Override
  protected synchronized PdxReaderImpl getUnmodifiableReader(String fieldName) {
    if (this.dirtyFields != null) {
      PdxField f = getPdxType().getPdxField(fieldName);
      if (f != null) {
        if (this.dirtyFields[f.getFieldIndex()] != null) {
          return getUnmodifiableReader();
        }
      }
    }
    return new PdxReaderImpl(this);
  }
  
  @Override
  public synchronized Object getCachedObject() {
    return super.getCachedObject();
  }

  @Override
  public synchronized int hashCode() {
    return super.hashCode();
  }

  /**
   * Flush any pending writes.
   */
  @Override
  protected synchronized PdxReaderImpl getUnmodifiableReader() {
    if (this.dirtyFields != null) {
      PdxOutputStream os = new PdxOutputStream(basicSize() + PdxWriterImpl.HEADER_SIZE);
      PdxWriterImpl writer = new PdxWriterImpl(getPdxType(), os);
      for (PdxField f: getPdxType().getFields()) {
        Object dv = this.dirtyFields[f.getFieldIndex()];
        if (dv != null) {
          if (dv == NULL_TOKEN) {
            dv = null;
          }
          writer.writeField(f, dv);
        } else {
          writer.writeRawField(f, getRaw(f));
        }
      }
      writer.completeByteStreamGeneration();
      ByteBuffer bb = os.toByteBuffer();
      bb.position(PdxWriterImpl.HEADER_SIZE);
      basicSetBuffer(bb.slice());
      this.dirtyFields = null;
    }
    return new PdxReaderImpl(this);
  }

  public void setField(String fieldName, Object value) {
    PdxField f = getPdxType().getPdxField(fieldName);
    if (f == null) {
      throw new PdxFieldDoesNotExistException("A field named " + fieldName + " does not exist on " + getPdxType());
    }
    if (value != null) {
      switch (f.getFieldType()) {
      case CHAR:
        if (!(value instanceof Character)) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a Character but was a " + value.getClass());
        }
        break;
      case BOOLEAN:
        if (!(value instanceof Boolean)) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a Boolean but was a " + value.getClass());
        }
        break;
      case BYTE:
        if (!(value instanceof Byte)) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a Byte but was a " + value.getClass());
        }
        break;
      case SHORT:
        if (!(value instanceof Short)) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a Short but was a " + value.getClass());
        }
        break;
      case INT:
        if (!(value instanceof Integer)) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a Integer but was a " + value.getClass());
        }
        break;
      case LONG:
        if (!(value instanceof Long)) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a Long but was a " + value.getClass());
        }
        break;
      case FLOAT:
        if (!(value instanceof Float)) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a Float but was a " + value.getClass());
        }
        break;
      case DOUBLE:
        if (!(value instanceof Double)) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a Double but was a " + value.getClass());
        }
        break;
      case STRING:
        if (!(value instanceof String)) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a String but was a " + value.getClass());
        }
        break;
      case BOOLEAN_ARRAY:
        if (!(value instanceof boolean[])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a boolean[] but was a " + value.getClass());
        }
        break;
      case CHAR_ARRAY:
        if (!(value instanceof char[])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a char[] but was a " + value.getClass());
        }
        break;
      case BYTE_ARRAY:
        if (!(value instanceof byte[])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a byte[] but was a " + value.getClass());
        }
        break;
      case SHORT_ARRAY:
        if (!(value instanceof short[])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a short[] but was a " + value.getClass());
        }
        break;
      case INT_ARRAY:
        if (!(value instanceof int[])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a int[] but was a " + value.getClass());
        }
        break;
      case LONG_ARRAY:
        if (!(value instanceof long[])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a long[] but was a " + value.getClass());
        }
        break;
      case FLOAT_ARRAY:
        if (!(value instanceof float[])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a float[] but was a " + value.getClass());
        }
        break;
      case DOUBLE_ARRAY:
        if (!(value instanceof double[])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a double[] but was a " + value.getClass());
        }
        break;
      case STRING_ARRAY:
        if (!(value instanceof String[])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a String[] but was a " + value.getClass());
        }
        break;
      case ARRAY_OF_BYTE_ARRAYS:
        if (!(value instanceof byte[][])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a byte[][] but was a " + value.getClass());
        }
        break;
      case OBJECT_ARRAY:
        if (!(value instanceof Object[])) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a Object[] but was a " + value.getClass());
        }
        break;
      case OBJECT:
        // no check needed
        break;
      // All of the following classes are not final. We only support the exact class in this case; not subclasses.
      case DATE:
        if (!Date.class.equals(value.getClass())) {
          throw new PdxFieldTypeMismatchException("Values for this field must be a Date but was a " + value.getClass());
        }
        break;
      default:
        throw new InternalGemFireException("Unhandled field type " + f.getFieldType());
      }
    } else {
      switch (f.getFieldType()) {
      case CHAR:
        value = Character.valueOf((char)0);
        break;
      case BOOLEAN:
        value = Boolean.valueOf(false);
        break;
      case BYTE:
        value = Byte.valueOf((byte)0);
        break;
      case SHORT:
        value = Short.valueOf((short)0);
        break;
      case INT:
        value = Integer.valueOf(0);
        break;
      case FLOAT:
        value = Float.valueOf(0.0f);
        break;
      case DOUBLE:
        value = Double.valueOf(0.0);
        break;
      case LONG:
        value = Long.valueOf(0L);
        break;
      case DATE:
      case STRING:
      case BOOLEAN_ARRAY:
      case CHAR_ARRAY:
      case BYTE_ARRAY:
      case SHORT_ARRAY:
      case INT_ARRAY:
      case LONG_ARRAY:
      case FLOAT_ARRAY:
      case DOUBLE_ARRAY:
      case STRING_ARRAY:
      case ARRAY_OF_BYTE_ARRAYS:
      case OBJECT_ARRAY:
      case OBJECT:
        // null ok
        break;
      default:
        throw new InternalGemFireException("Unhandled field type " + f.getFieldType());
      }
    }
    dirtyField(f, value);
  }
  
  @Override
  public boolean equals(Object obj) {
    // no need to compare dirtyFields
    // Overriding just to make this clear
    return super.equals(obj);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy