com.microsoft.azure.storage.table.EntityProperty Maven / Gradle / Ivy
/**
* Copyright Microsoft Corporation
*
* 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.
*/
package com.microsoft.azure.storage.table;
import java.text.ParseException;
import java.util.Date;
import java.util.UUID;
import com.microsoft.azure.storage.Constants;
import com.microsoft.azure.storage.core.Base64;
import com.microsoft.azure.storage.core.SR;
import com.microsoft.azure.storage.core.Utility;
/**
* A class which represents a single typed property value in a table entity. An {@link EntityProperty} stores the data
* type as an {@link EdmType}. The value, which may be null
for object types, but not for primitive types,
* is serialized and stored as a String
.
*
* {@link EntityProperty} provides overloaded constructors and overloads of the setValue
method for
* supported value types. Each overloaded constructor or setValue
method sets the {@link EdmType} and
* serializes the value appropriately based on the parameter type.
*
* Use one of the getValueAs
Type methods to deserialize an {@link EntityProperty} as the
* appropriate Java type. The method will throw a {@link ParseException} or {@link IllegalArgumentException} if the
* {@link EntityProperty} cannot be deserialized as the Java type.
*/
public final class EntityProperty {
private String value;
private Class type;
private EdmType edmType = EdmType.NULL;
private boolean isEncrypted = false;
/**
* Flag that specifies whether the client should look to correct Date values stored on a {@link TableEntity}
* that may have been written using versions of this library prior to 2.0.0.
* See here for more details.
*/
private boolean dateBackwardCompatibility = false;
/**
* Reserved for internal use. Constructs an {@link EntityProperty} instance from a Object
value type,
* and verifies that the value can be interpreted as the specified data type.
*
* @param value
* The Object
to convert to a string and store.
*/
protected EntityProperty(final String value, final Class type) {
this.type = type;
this.value = value;
if (type.equals(byte[].class)) {
this.getValueAsByteArray();
this.edmType = EdmType.BINARY;
}
else if (type.equals(Byte[].class)) {
this.getValueAsByteObjectArray();
this.edmType = EdmType.BINARY;
}
else if (type.equals(String.class)) {
this.edmType = EdmType.STRING;
}
else if (type.equals(boolean.class)) {
this.getValueAsBoolean();
this.edmType = EdmType.BOOLEAN;
}
else if (type.equals(Boolean.class)) {
this.getValueAsBooleanObject();
this.edmType = EdmType.BOOLEAN;
}
else if (type.equals(Date.class)) {
this.getValueAsDate();
this.edmType = EdmType.DATE_TIME;
}
else if (type.equals(double.class)) {
this.getValueAsDouble();
this.edmType = EdmType.DOUBLE;
}
else if (type.equals(Double.class)) {
this.getValueAsDoubleObject();
this.edmType = EdmType.DOUBLE;
}
else if (type.equals(UUID.class)) {
this.getValueAsUUID();
this.edmType = EdmType.GUID;
}
else if (type.equals(int.class)) {
this.getValueAsInteger();
this.edmType = EdmType.INT32;
}
else if (type.equals(Integer.class)) {
this.getValueAsIntegerObject();
this.edmType = EdmType.INT32;
}
else if (type.equals(long.class)) {
this.getValueAsLong();
this.edmType = EdmType.INT64;
}
else if (type.equals(Long.class)) {
this.getValueAsLongObject();
this.edmType = EdmType.INT64;
}
else {
throw new IllegalArgumentException(String.format(SR.TYPE_NOT_SUPPORTED, type.toString()));
}
}
/**
* Reserved for internal use. Constructs an {@link EntityProperty} instance from a Object
value and a
* data type, and verifies that the value can be interpreted as the specified data type.
*
* @param value
* The Object
to convert to a string and store.
* @param type
* The Class<?>
type of the value to construct.
*/
protected EntityProperty(final Object value, final Class type) {
if (type.equals(byte[].class)) {
setValue((byte[]) value);
this.type = type;
}
else if (type.equals(Byte[].class)) {
setValue((Byte[]) value);
this.type = type;
}
else if (type.equals(String.class)) {
setValue((String) value);
this.type = type;
}
else if (type.equals(boolean.class)) {
setValue(((Boolean) value).booleanValue());
this.type = type;
}
else if (type.equals(Boolean.class)) {
setValue((Boolean) value);
this.type = type;
}
else if (type.equals(double.class)) {
setValue(((Double) value).doubleValue());
this.type = type;
}
else if (type.equals(Double.class)) {
setValue((Double) value);
this.type = type;
}
else if (type.equals(UUID.class)) {
setValue((UUID) value);
this.type = type;
}
else if (type.equals(int.class)) {
setValue(((Integer) value).intValue());
this.type = type;
}
else if (type.equals(Integer.class)) {
setValue((Integer) value);
this.type = type;
}
else if (type.equals(long.class)) {
setValue(((Long) value).longValue());
this.type = type;
}
else if (type.equals(Long.class)) {
setValue((Long) value);
this.type = type;
}
else if (type.equals(Date.class)) {
setValue((Date) value);
this.type = type;
}
else {
throw new IllegalArgumentException(String.format(SR.TYPE_NOT_SUPPORTED, type.toString()));
}
}
/**
* Reserved for internal use. Constructs an {@link EntityProperty} instance from a String
value and a
* data type, and verifies that the value can be interpreted as the specified data type.
*
* @param value
* The String
representation of the value to construct.
* @param edmType
* The {@link EdmType} data type of the value to construct.
*/
protected EntityProperty(final String value, final EdmType edmType) {
this.edmType = edmType;
this.value = value;
// validate data is encoded correctly
if (edmType == EdmType.STRING) {
this.type = String.class;
return;
}
else if (edmType == EdmType.BINARY) {
this.getValueAsByteArray();
this.type = Byte[].class;
}
else if (edmType == EdmType.BOOLEAN) {
this.getValueAsBoolean();
this.type = Boolean.class;
}
else if (edmType == EdmType.DOUBLE) {
this.getValueAsDouble();
this.type = Double.class;
}
else if (edmType == EdmType.GUID) {
this.getValueAsUUID();
this.type = UUID.class;
}
else if (edmType == EdmType.INT32) {
this.getValueAsInteger();
this.type = Integer.class;
}
else if (edmType == EdmType.INT64) {
this.getValueAsLong();
this.type = Long.class;
}
else if (edmType == EdmType.DATE_TIME) {
this.getValueAsDate();
this.type = Date.class;
}
else {
// these are overwritten when this is called from the table parser with a more informative message
if (edmType == null) {
throw new IllegalArgumentException(SR.EDMTYPE_WAS_NULL);
}
throw new IllegalArgumentException(String.format(SR.INVALID_EDMTYPE_VALUE, edmType.toString()));
}
}
/**
* Constructs an {@link EntityProperty} instance from a boolean
value.
*
* @param value
* The boolean
value of the entity property to set.
*/
public EntityProperty(final boolean value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from a Boolean
value.
*
* @param value
* The Boolean
value of the entity property to set.
*/
public EntityProperty(final Boolean value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from a byte[]
value.
*
* @param value
* The byte[]
value of the entity property to set.
*/
public EntityProperty(final byte[] value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from a Byte[]
.
*
* @param value
* The Byte[]
to set as the entity property value.
*/
public EntityProperty(final Byte[] value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from a java.util.Date
value.
*
* @param value
* The java.util.Date
to set as the entity property value.
*/
public EntityProperty(final Date value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from a double
value.
*
* @param value
* The double
value of the entity property to set.
*/
public EntityProperty(final double value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from a Double
value.
*
* @param value
* The Double
value of the entity property to set.
*/
public EntityProperty(final Double value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from an int
value.
*
* @param value
* The int
value of the entity property to set.
*/
public EntityProperty(final int value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from an Integer
value.
*
* @param value
* The Integer
value of the entity property to set.
*/
public EntityProperty(final Integer value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from a long
value.
*
* @param value
* The long
value of the entity property to set.
*/
public EntityProperty(final long value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from a Long
value.
*
* @param value
* The Long
value of the entity property to set.
*/
public EntityProperty(final Long value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from a String
value.
*
* @param value
* The String
to set as the entity property value.
*/
public EntityProperty(final String value) {
this.setValue(value);
}
/**
* Constructs an {@link EntityProperty} instance from a java.util.UUID
value.
*
* @param value
* The java.util.UUID
to set as the entity property value.
*/
public EntityProperty(final UUID value) {
this.setValue(value);
}
/**
* Gets the {@link EdmType} storage data type for the {@link EntityProperty}.
*
* @return
* The {@link EdmType} enumeration value for the data type of the {@link EntityProperty}.
*/
public EdmType getEdmType() {
return this.edmType;
}
/**
* Gets a flag indicating that the {@link EntityProperty} value is null
.
*
* @return
* A boolean
flag indicating that the {@link EntityProperty} value is null
.
*/
public boolean getIsNull() {
return this.value == null;
}
/**
* Gets the class type of the {@link EntityProperty}.
*
* @return
* The Class<?>
of the {@link EntityProperty}.
*/
public Class getType() {
return this.type;
}
/**
* Gets a flag indicating whether the {@link EntityProperty} value is encrypted.
*
* @return
* A boolean
flag indicating whether the {@link EntityProperty} value is encrypted.
*/
protected boolean isEncrypted() {
return this.isEncrypted;
}
/**
* Gets the value of this {@link EntityProperty} as a boolean
.
*
* @return
* A boolean
representation of the {@link EntityProperty} value.
*
* @throws IllegalArgumentException
* If the value is null
or cannot be parsed as a Boolean
.
*/
public boolean getValueAsBoolean() {
if (this.getIsNull()) {
throw new IllegalArgumentException(SR.ENTITY_PROPERTY_CANNOT_BE_NULL_FOR_PRIMITIVES);
}
return Boolean.parseBoolean(this.value);
}
/**
* Gets the value of this {@link EntityProperty} as a Boolean
.
*
* @return
* A Boolean
representation of the {@link EntityProperty} value.
*
* @throws IllegalArgumentException
* If the value is null
or cannot be parsed as a Boolean
.
*/
public Boolean getValueAsBooleanObject() {
if (this.getIsNull()) {
return null;
}
return Boolean.parseBoolean(this.value);
}
/**
* Gets the value of this {@link EntityProperty} as a byte
array.
*
* @return
* A byte[]
representation of the {@link EntityProperty} value, or null
.
*/
public byte[] getValueAsByteArray() {
return this.getIsNull() ? null : Base64.decode(this.value);
}
/**
* Gets the value of this {@link EntityProperty} as a Byte
array.
*
* @return
* A Byte[]
representation of the {@link EntityProperty} value, or null
.
*/
public Byte[] getValueAsByteObjectArray() {
return this.getIsNull() ? null : Base64.decodeAsByteObjectArray(this.value);
}
/**
* Gets the value of this {@link EntityProperty} as a java.util.Date
.
*
* @return
* A java.util.Date
representation of the {@link EntityProperty} value, or null
.
*
* @throws IllegalArgumentException
* If the value is not null
and cannot be parsed as a java.util.Date
.
*/
public Date getValueAsDate() {
return this.getIsNull() ? null : Utility.parseDate(this.value, this.dateBackwardCompatibility);
}
/**
* Gets the value of this {@link EntityProperty} as a double
.
*
* @return
* A double
representation of the {@link EntityProperty} value.
*
* @throws IllegalArgumentException
* If the value is null
or cannot be parsed as a double
.
*/
public double getValueAsDouble() {
if (this.getIsNull()) {
throw new IllegalArgumentException(SR.ENTITY_PROPERTY_CANNOT_BE_NULL_FOR_PRIMITIVES);
}
else if (this.value.equals("Infinity") || this.value.equals("INF")) {
return Double.POSITIVE_INFINITY;
}
else if (this.value.equals("-Infinity") || this.value.equals("-INF")) {
return Double.NEGATIVE_INFINITY;
}
else if (this.value.equals("NaN")) {
return Double.NaN;
}
else {
return Double.parseDouble(this.value);
}
}
/**
* Gets the value of this {@link EntityProperty} as a double
.
*
* @return
* A double
representation of the {@link EntityProperty} value.
*
* @throws IllegalArgumentException
* If the value is null
or cannot be parsed as a double
.
*/
public Double getValueAsDoubleObject() {
if (this.getIsNull()) {
return null;
}
else if (this.value.equals("Infinity") || this.value.equals("INF")) {
return Double.POSITIVE_INFINITY;
}
else if (this.value.equals("-Infinity") || this.value.equals("-INF")) {
return Double.NEGATIVE_INFINITY;
}
else if (this.value.equals("NaN")) {
return Double.NaN;
}
else {
return Double.parseDouble(this.value);
}
}
/**
* Gets the value of this {@link EntityProperty} as an int
.
*
* @return
* An int
representation of the {@link EntityProperty} value.
*
* @throws IllegalArgumentException
* If the value is null
or cannot be parsed as an int
.
*/
public int getValueAsInteger() {
if (this.getIsNull()) {
throw new IllegalArgumentException(SR.ENTITY_PROPERTY_CANNOT_BE_NULL_FOR_PRIMITIVES);
}
return Integer.parseInt(this.value);
}
/**
* Gets the value of this {@link EntityProperty} as an Integer
.
*
* @return
* An Integer
representation of the {@link EntityProperty} value.
*
* @throws IllegalArgumentException
* If the value is null
or cannot be parsed as an int
.
*/
public Integer getValueAsIntegerObject() {
return this.getIsNull() ? null : Integer.parseInt(this.value);
}
/**
* Gets the value of this {@link EntityProperty} as a long
.
*
* @return
* A long
representation of the {@link EntityProperty} value.
*
* @throws IllegalArgumentException
* If the value is null
or cannot be parsed as a long
.
*/
public long getValueAsLong() {
if (this.getIsNull()) {
throw new IllegalArgumentException(SR.ENTITY_PROPERTY_CANNOT_BE_NULL_FOR_PRIMITIVES);
}
return Long.parseLong(this.value);
}
/**
* Gets the value of this {@link EntityProperty} as a Long
.
*
* @return
* A long
representation of the {@link EntityProperty} value.
*
* @throws IllegalArgumentException
* If the value is null
or cannot be parsed as a long
.
*/
public Long getValueAsLongObject() {
return this.getIsNull() ? null : Long.parseLong(this.value);
}
/**
* Gets the value of this {@link EntityProperty} as a String
.
*
* @return
* A String
representation of the {@link EntityProperty} value, or null
.
*/
public String getValueAsString() {
return this.getIsNull() ? null : this.value;
}
/**
* Gets the value of this {@link EntityProperty} as a java.util.UUID
.
*
* @return
* A java.util.UUID
representation of the {@link EntityProperty} value, or null
.
*
* @throws IllegalArgumentException
* If the value cannot be parsed as a java.util.UUID
.
*/
public UUID getValueAsUUID() {
return this.getIsNull() ? null : UUID.fromString(this.value);
}
/**
* Sets this {@link EntityProperty} using the serialized boolean
value.
*
* @param value
* The boolean
value to set as the {@link EntityProperty} value.
*/
public synchronized final void setValue(final boolean value) {
this.edmType = EdmType.BOOLEAN;
this.type = boolean.class;
this.value = value ? Constants.TRUE : Constants.FALSE;
}
/**
* Sets this {@link EntityProperty} using the serialized Boolean
value.
*
* @param value
* The Boolean
value to set as the {@link EntityProperty} value.
*/
public synchronized final void setValue(final Boolean value) {
this.edmType = EdmType.BOOLEAN;
this.type = Boolean.class;
if (value == null) {
this.value = null;
}
else {
this.value = value ? Constants.TRUE : Constants.FALSE;
}
}
/**
* Sets this {@link EntityProperty} using the serialized byte[]
value.
*
* @param value
* The byte[]
value to set as the {@link EntityProperty} value. This value may be
* null
.
*/
public synchronized final void setValue(final byte[] value) {
this.edmType = EdmType.BINARY;
this.type = byte[].class;
this.value = value == null ? null : Base64.encode(value);
}
/**
* Sets this {@link EntityProperty} using the serialized Byte[]
value.
*
* @param value
* The Byte[]
value to set as the {@link EntityProperty} value. This value may be
* null
.
*/
public synchronized final void setValue(final Byte[] value) {
this.edmType = EdmType.BINARY;
this.type = Byte[].class;
this.value = value == null ? null : Base64.encode(value);
}
/**
* Sets this {@link EntityProperty} using the serialized java.util.Date
value.
*
* @param value
* The java.util.Date
value to set as the {@link EntityProperty} value. This value may be
* null
.
*/
public synchronized final void setValue(final Date value) {
this.edmType = EdmType.DATE_TIME;
this.type = Date.class;
this.value = value == null ? null : Utility.getJavaISO8601Time(value);
}
/**
* Sets this {@link EntityProperty} using the serialized double
value.
*
* @param value
* The double
value to set as the {@link EntityProperty} value.
*/
public synchronized final void setValue(final double value) {
this.edmType = EdmType.DOUBLE;
this.type = double.class;
this.value = Double.toString(value);
}
/**
* Sets this {@link EntityProperty} using the serialized Double
value.
*
* @param value
* The Double
value to set as the {@link EntityProperty} value.
*/
public synchronized final void setValue(final Double value) {
this.edmType = EdmType.DOUBLE;
this.type = Double.class;
this.value = value == null ? null : Double.toString(value);
}
/**
* Sets this {@link EntityProperty} using the serialized int
value.
*
* @param value
* The int
value to set as the {@link EntityProperty} value.
*/
public synchronized final void setValue(final int value) {
this.edmType = EdmType.INT32;
this.type = int.class;
this.value = Integer.toString(value);
}
/**
* Sets this {@link EntityProperty} using the serialized Integer
value.
*
* @param value
* The Integer
value to set as the {@link EntityProperty} value.
*/
public synchronized final void setValue(final Integer value) {
this.edmType = EdmType.INT32;
this.type = Integer.class;
this.value = value == null ? null : Integer.toString(value);
}
/**
* Sets this {@link EntityProperty} using the serialized long
value.
*
* @param value
* The long
value to set as the {@link EntityProperty} value.
*/
public synchronized final void setValue(final long value) {
this.edmType = EdmType.INT64;
this.type = long.class;
this.value = Long.toString(value);
}
/**
* Sets this {@link EntityProperty} using the serialized Long
value.
*
* @param value
* The Long
value to set as the {@link EntityProperty} value.
*/
public synchronized final void setValue(final Long value) {
this.edmType = EdmType.INT64;
this.type = Long.class;
this.value = value == null ? null : Long.toString(value);
}
/**
* Sets this {@link EntityProperty} using the String
value.
*
* @param value
* The String
value to set as the {@link EntityProperty} value. This value may be
* null
.
*/
public synchronized final void setValue(final String value) {
this.edmType = EdmType.STRING;
this.type = String.class;
this.value = value;
}
/**
* Sets this {@link EntityProperty} using the serialized java.util.UUID
value.
*
* @param value
* The java.util.UUID
value to set as the {@link EntityProperty} value.
* This value may be null
.
*/
public synchronized final void setValue(final UUID value) {
this.edmType = EdmType.GUID;
this.type = UUID.class;
this.value = value == null ? null : value.toString();
}
/**
* Sets whether the client should look to correct Date values stored on a {@link TableEntity}
* that may have been written using versions of this library prior to 2.0.0.
*
* {@link #dateBackwardCompatibility} is by default false
, indicating a post 2.0.0 version or
* mixed-platform usage.
*
* See here for more details.
*
* @param dateBackwardCompatibility
* true
to enable dateBackwardCompatibility
; otherwise, false
*/
void setDateBackwardCompatibility(boolean dateBackwardCompatibility) {
this.dateBackwardCompatibility = dateBackwardCompatibility;
}
/**
* Sets a flag indicating whether the {@link EntityProperty} value is encrypted.
*
* @param isEncrypted
* A boolean
flag indicating whether the {@link EntityProperty} value is encrypted.
*/
protected void setIsEncrypted(boolean isEncrypted) {
this.isEncrypted = isEncrypted;
}
}