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

com.gemstone.gemfire.pdx.PdxInstance 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;

import java.util.List;

import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;

/**
 * PdxInstance provides run time access to the fields of a PDX without 
 * deserializing the PDX. Preventing deserialization saves time
 * and memory and does not require the domain class.
 * This interface is implemented by GemFire. The PdxInstance implementation 
 * is a light weight wrapper that simply refers to the raw bytes of the PDX 
 * that are kept in the cache.
 * Applications can choose to access PdxInstances instead of Java objects by 
 * configuring the Cache to prefer PDX instances during deserialization. 
 * This can be done in cache.xml by setting the attribute read-serialized 
 * to true on the pdx element. Or it can be done programmatically using
 * either the {@link CacheFactory#setPdxReadSerialized(boolean) setPdxReadSerialized}
 * or {@link ClientCacheFactory#setPdxReadSerialized(boolean) client setPdxReadSerialized}
 * method. Once this preference is configured, then any time deserialization of a 
 * PDX is done it will deserialize into a PdxInstance.
 * 

PdxInstances are immutable. If you want to change one call * {@link #createWriter}. *

* A PdxInstance's fields will always be those of the version it represents. * So if you add a field to your domain class you can end up with a PdxInstance * for version 1 (that does not have the field) and a PdxInstance for version 2. * The PdxInstance for version 1 will not have the added field and the PdxInstance * for version 2 will have the field. This differs from deserialization of a pdx * back to a domain class. In that case if version 2 is deserializing version 1 * PdxReader will return a default value for the added field even though version 1 * has no knowledge of it. * * @author darrel * @since 6.6 */ public interface PdxInstance extends java.io.Serializable { /** * Return the full name of the class that this pdx instance represents. * @return the name of the class that this pdx instance represents. * @since 6.6.2 */ public String getClassName(); /** * Returns true if this instance represents an enum. * Enum's have a String field named "name" and an int field named "ordinal". * It is ok to cast a PdxInstance that represents an enum to {@link java.lang.Comparable}. * PdxInstances representing enums are not writable. * @return true if this instance represents an enum. */ public boolean isEnum(); /** * Deserializes and returns the domain object that this instance represents. * * @return the deserialized domain object. * @throws PdxSerializationException if the instance could not be deserialized */ public Object getObject(); /** * Checks if the named field exists and returns the result. *

This can be useful when writing code that handles more than one version of * a PDX class. * @param fieldName the name of the field to check * @return true if the named field exists; otherwise false */ public boolean hasField(String fieldName); /** * Return an unmodifiable list of the field names on this PdxInstance. * @return an unmodifiable list of the field names on this PdxInstance */ public List getFieldNames(); /** * Checks if the named field was {@link PdxWriter#markIdentityField(String) marked} as an identity field. *

Note that if no fields have been marked then all the fields are used as identity fields even though * this method will return false since none of them have been marked. * @param fieldName the name of the field to check * @return true if the named field exists and was marked as an identify field; otherwise false */ public boolean isIdentityField(String fieldName); /** * Reads the named field and returns its value. If the field does * not exist null is returned. *

A null result indicates that the field does not exist * or that it exists and its value is currently null. * The {@link #hasField(String) hasField} method can be used to figure out * which if these two cases is true. *

If an Object[] is deserialized by this call then that array's component * type will be Object.class instead of the original class that * the array had when it was serialized. This is done so that PdxInstance objects * can be added to the array. * * @param fieldName * name of the field to read * * @return If this instance has the named field then the field's value is returned, * otherwise null is returned. * @throws PdxSerializationException if the field could not be deserialized */ public Object getField(String fieldName); /** * Returns true if the given object is equals to this instance. *

If other is not a PdxInstance then it is not equal to this instance. * NOTE: Even if other is the result of calling {@link #getObject()} it will not * be equal to this instance. *

Otherwise equality of two PdxInstances is determined as follows: *

    *
  1. The domain class name must be equal for both PdxInstances *
  2. Each identity field must be equal. *
* If one of the instances does not have a field that the other one does then equals will assume it * has the field with a default value. * If a PdxInstance has marked identity fields using {@link PdxWriter#markIdentityField(String) markIdentityField} * then only the marked identity fields are its identity fields. * Otherwise all its fields are identity fields. *

An identity field is equal if all the following are true: *

    *
  1. The field name is equal. *
  2. The field type is equal. *
  3. The field value is equal. *
*

If a field's type is OBJECT then its value must be deserialized to determine if it is equals. If the deserialized object is an array then {@link java.util.Arrays#deepEquals(Object[], Object[]) deepEquals} is used to determine equality. Otherwise {@link Object#equals(Object) equals} is used. *

If a field's type is OBJECT[] then its value must be deserialized and {@link java.util.Arrays#deepEquals(Object[], Object[]) deepEquals} is used to determine equality. *

For all other field types then the value does not need to be deserialized. Instead the serialized raw bytes are compared and used to determine equality. *

Note that any fields that have objects that do not override {@link Object#equals(Object) equals} will cause equals to return false when you might have expected it to return true. * The only exceptions to this are those that call {@link java.util.Arrays#deepEquals(Object[], Object[]) deepEquals} as noted above. You should either override equals and hashCode in these cases * or mark other fields as your identity fields. * @param other the other instance to compare to this. * @return true if this instance is equal to other. */ public boolean equals(Object other); /** * Generates a hashCode based on the identity fields of * this PdxInstance. *

If a PdxInstance has marked identity fields using {@link PdxWriter#markIdentityField(String) markIdentityField} * then only the marked identity fields are its identity fields. * Otherwise all its fields are identity fields. *

* If an identity field is of type OBJECT then it is deserialized. If the deserialized object is an array then {@link java.util.Arrays#deepHashCode(Object[]) deepHashCode} is used. Otherwise {@link Object#hashCode() hashCode} is used. *

If an identity field is of type OBJECT[] this it is deserialized and {@link java.util.Arrays#deepHashCode(Object[]) deepHashCode} is used. *

Otherwise the field is not deserialized and the raw bytes of its value are used to compute the hash code. *

* The algorithm used to compute the hashCode is: * hashCode = 1; * foreach (field: sortedIdentityFields()) { * if (field.isDefaultValue()) * continue; * if (field.isArray()) { * hashCode = hashCode*31 + Arrays.deepHashCode(field); * } else { * hashCode = hashCode*31 + field.hashCode(); * } * } * if (hashCode == 0) { * hashCode = 1; * } */ public int hashCode(); /** * Prints out all of the identity fields of this PdxInstance. *

If a PdxInstance has marked identity fields using {@link PdxWriter#markIdentityField(String) markIdentityField} * then only the marked identity fields are its identity fields. * Otherwise all its fields are identity fields. */ public String toString(); /** * Creates and returns a {@link WritablePdxInstance} whose initial * values are those of this PdxInstance. * This call returns a copy of the current field values so modifications * made to the returned value will not modify this PdxInstance. * * @return a {@link WritablePdxInstance} * @throws IllegaStateException if the PdxInstance is an enum. */ public WritablePdxInstance createWriter(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy