org.eclipse.persistence.sdo.DefaultValueStore Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sdo;
import commonj.sdo.DataObject;
import commonj.sdo.Property;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Purpose:Default implementation of the ValueStore interface.
*
Responsibilities:
* - Provide get/set/isset/unset access to the values of a DataObject
*
- Store the values of the declared and open content propeties in memory
*
*/
public class DefaultValueStore implements ValueStore {
private Map openContentValues;//open content values keyed on real prop name
private Object[] typePropertyValues;
/** Visibility reduced from [public] in 2.1.0. May 15 2007 */
private boolean[] typePropertiesIsSetStatus;
private DataObject dataObject;
public DefaultValueStore() {
}
@Override
public Object getDeclaredProperty(int propertyIndex) {
if (typePropertyValues != null) {
return typePropertyValues[propertyIndex];
}
return null;
}
@Override
public Object getOpenContentProperty(Property property) {
return getOpenContentValues().get(property);
}
@Override
public void setDeclaredProperty(int propertyIndex, Object value) {
getTypePropertyValues()[propertyIndex] = value;
getTypePropertiesIsSetStatus()[propertyIndex] = true;
}
@Override
public void setOpenContentProperty(Property property, Object value) {
getOpenContentValues().put(property, value);
}
@Override
public boolean isSetDeclaredProperty(int propertyIndex) {
boolean[] typePropertiesIsSetStatus = getTypePropertiesIsSetStatus();
if(propertyIndex >= typePropertiesIsSetStatus.length) {
// New properties have been added to the type since the DataObject
// was created so return false to indicate that the new property has
// not been set.
return false;
}
return typePropertiesIsSetStatus[propertyIndex];
}
@Override
public boolean isSetOpenContentProperty(Property property) {
return getOpenContentValues().containsKey(property);
}
@Override
public void unsetDeclaredProperty(int propertyIndex) {
Property prop = ((SDODataObject)dataObject).getInstanceProperty(propertyIndex);
if (!prop.isMany()) {
getTypePropertyValues()[propertyIndex] = null;
}
getTypePropertiesIsSetStatus()[propertyIndex] = false;
}
@Override
public void unsetOpenContentProperty(Property property) {
getOpenContentValues().remove(property);
}
/**
* Perform any post-instantiation integrity operations that could not be done during
* ValueStore creation.
* Since the dataObject reference passed in may be bidirectional or self-referencing
* - we cannot set this variable until the dataObject itself is finished instantiation
* - hence the 2-step initialization.
*
* @param aDataObject
*/
@Override
public void initialize(DataObject aDataObject) {
dataObject = aDataObject;
setTypePropertiesIsSetStatus(new boolean[aDataObject.getType().getProperties().size()]);
setTypePropertyValues(new Object[aDataObject.getType().getProperties().size()]);
}
/**
* Set the values for declared properties
* @param typePropertyValuesArray
*/
public void setTypePropertyValues(Object[] typePropertyValuesArray) {
typePropertyValues = typePropertyValuesArray;
}
/**
* INTERNAL:
* @param typePropertiesIsSetStatusArray boolean[] of isSet values for declared properties
*/
public void setTypePropertiesIsSetStatus(boolean[] typePropertiesIsSetStatusArray) {
typePropertiesIsSetStatus = typePropertiesIsSetStatusArray;
}
/**
* INTERNAL:
* @return Object[] of the values of declared properties
*/
public Object[] getTypePropertyValues() {
return typePropertyValues;
}
/**
* INTERNAL:
* @return boolean[] of isSet values for declared properties
*/
public boolean[] getTypePropertiesIsSetStatus() {
return typePropertiesIsSetStatus;
}
/**
* INTERNAL:
* @param openContentValues
*/
public void setOpenContentValues(Map openContentValues) {
this.openContentValues = openContentValues;
}
/**
* INTERNAL:
* @return Non-null Map of values for open content properties
*/
public Map getOpenContentValues() {
if (openContentValues == null) {
openContentValues = new HashMap();
}
return openContentValues;
}
// Do not implement this function unless the valueStore handles its own object wrapping
@Override
public void setManyProperty(Property property, Object value) {
}
/**
* Get a shallow copy of the original ValueStore.
* Changes made to the copy must not impact the original ValueStore
* @return ValueStore
*/
@Override
public ValueStore copy() {
/**
* Implementer: SDODataObject.resetChanges()
*/
DefaultValueStore anOriginalValueStore = new DefaultValueStore();
anOriginalValueStore.dataObject = dataObject;
boolean[] currentIsSet = getTypePropertiesIsSetStatus();
boolean[] isSetCopy = new boolean[currentIsSet.length];
System.arraycopy(currentIsSet, 0, isSetCopy, 0, currentIsSet.length);
Object[] currentValues = getTypePropertyValues();
Object[] valueCopy = new Object[currentValues.length];
System.arraycopy(currentValues, 0, valueCopy, 0, currentValues.length);
// shallow copy isSet boolean
anOriginalValueStore.setTypePropertiesIsSetStatus(isSetCopy);
// shallow copy the object values
anOriginalValueStore.setTypePropertyValues(valueCopy);
HashMap clonedMap = new HashMap();
/**
* Note: if the oc Map is null we will return an empty map
* this empty Map will be set on the copy but the original will still actually have a null Map
* this is ok because any get on the original will create a new Map and we will
* not have object equality between copy and original oc maps
* Just be aware that the two openContentValues will not pass value equility unless
* the public get function is used
*/
clonedMap.putAll(getOpenContentValues());
// shallow copy oc values
anOriginalValueStore.setOpenContentValues(clonedMap);
return anOriginalValueStore;
}
/**
* Indicates if a given ValueStore is equal to this. The following
* attributes are tested for equality:
* - data object
* - type property values
* - open content property values
* - property isSet values
*/
@Override
public boolean equals(Object obj) {
DefaultValueStore dvs;
try {
dvs = (DefaultValueStore) obj;
} catch (ClassCastException cce) {
return false;
}
// Compare data object
if (dvs.dataObject != this.dataObject) {
return false;
}
// Compare declared properties and isSet status
// All lists must be the same length
if (dvs.getTypePropertyValues().length != this.getTypePropertyValues().length ||
dvs.getTypePropertiesIsSetStatus().length != this.getTypePropertiesIsSetStatus().length) {
return false;
}
for (int i=0; i keyIt = dvs.getOpenContentValues().keySet().iterator();
while (keyIt.hasNext()) {
Property key = keyIt.next();
Object dvsOCVal = dvs.getOpenContentProperty(key);
Object thisOCVal = this.getOpenContentProperty(key);
// Both values need to be null or non-null
if (dvsOCVal == null) {
if (thisOCVal != null) {
return false;
}
// Here both are null so no need to check anything
} else {
if (!(dvsOCVal.equals(thisOCVal))) {
return false;
}
}
}
return true;
}
@Override
public int hashCode() {
Object[] typePropertyValues = getTypePropertyValues();
boolean[] typePropertiesIsSetStatus = getTypePropertiesIsSetStatus();
int result = dataObject != null ? dataObject.hashCode() : 0;
result = 31 * result + (typePropertyValues != null ? Arrays.hashCode(typePropertyValues) : 0);
result = 31 * result + (typePropertiesIsSetStatus != null ? Arrays.hashCode(typePropertiesIsSetStatus) : 0);
result = 31 * result + getOpenContentValues().hashCode();
return result;
}
}