com.microsoft.azure.storage.table.TableEntitySerializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of azure-storage Show documentation
Show all versions of azure-storage Show documentation
SDK for Microsoft Azure Storage Clients
/**
* 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.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.microsoft.azure.storage.OperationContext;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.core.Utility;
/**
* RESERVED FOR INTERNAL USE. A class used to serialize table entities to a byte array.
*/
final class TableEntitySerializer {
/**
* Reserved for internal use. Writes an entity to the stream as a JSON resource, leaving the stream open
* for additional writing.
*
* @param outStream
* The OutputStream
to write the entity to.
* @param options
* The {@link TableRequestOptions} to use for serializing.
* @param entity
* The instance implementing {@link TableEntity} to write to the output stream.
* @param isTableEntry
* A flag indicating the entity is a reference to a table at the top level of the storage service when
* true and a reference to an entity within a table when false
.
* @param opContext
* An {@link OperationContext} object used to track the execution of the operation.
*
* @throws StorageException
* if a Storage service error occurs.
* @throws IOException
* if an error occurs while accessing the stream.
*/
static void writeSingleEntityToStream(final OutputStream outStream, final TableRequestOptions options,
final TableEntity entity, final boolean isTableEntry, final OperationContext opContext)
throws StorageException, IOException {
JsonGenerator generator = Utility.getJsonGenerator(outStream);
try {
// write to stream
writeJsonEntity(generator, options, entity, isTableEntry, opContext);
}
finally {
generator.close();
}
}
/**
* Reserved for internal use. Writes an entity to the stream as a JSON resource, leaving the stream open
* for additional writing.
*
* @param strWriter
* The StringWriter
to write the entity to.
* @param options
* The {@link TableRequestOptions} to use for serializing.
* @param entity
* The instance implementing {@link TableEntity} to write to the output stream.
* @param isTableEntry
* A flag indicating the entity is a reference to a table at the top level of the storage service when
* true and a reference to an entity within a table when false
.
* @param opContext
* An {@link OperationContext} object used to track the execution of the operation.
*
* @throws StorageException
* if a Storage service error occurs.
* @throws IOException
* if an error occurs while accessing the stream.
*/
static void writeSingleEntityToString(final StringWriter strWriter, final TableRequestOptions options,
final TableEntity entity, final boolean isTableEntry, final OperationContext opContext)
throws StorageException, IOException {
JsonGenerator generator = Utility.getJsonGenerator(strWriter);
try {
// write to stream
writeJsonEntity(generator, options, entity, isTableEntry, opContext);
}
finally {
generator.close();
}
}
/**
* Reserved for internal use. Writes an entity to the specified JsonGenerator
as a JSON resource
*
* @param generator
* The JsonGenerator
to write the entity to.
* @param options
* The {@link TableRequestOptions} to use for serializing.
* @param entity
* The instance implementing {@link TableEntity} to write to the output stream.
* @param isTableEntry
* A flag indicating the entity is a reference to a table at the top level of the storage service when
* true and a reference to an entity within a table when false
.
* @param opContext
* An {@link OperationContext} object used to track the execution of the operation.
*
* @throws StorageException
* if a Storage service error occurs.
* @throws IOException
* if an error occurs while accessing the stream.
*/
private static void writeJsonEntity(final JsonGenerator generator, final TableRequestOptions options,
final TableEntity entity, final boolean isTableEntry, final OperationContext opContext)
throws StorageException, IOException {
Map properties = getPropertiesFromDictionary(entity, options, opContext);
// start object
generator.writeStartObject();
if (!isTableEntry) {
Utility.assertNotNull(TableConstants.PARTITION_KEY, entity.getPartitionKey());
Utility.assertNotNull(TableConstants.ROW_KEY, entity.getRowKey());
Utility.assertNotNull(TableConstants.TIMESTAMP, entity.getTimestamp());
// PartitionKey
generator.writeStringField(TableConstants.PARTITION_KEY, entity.getPartitionKey());
// RowKey
generator.writeStringField(TableConstants.ROW_KEY, entity.getRowKey());
// Timestamp
generator.writeStringField(TableConstants.TIMESTAMP, Utility.getJavaISO8601Time(entity.getTimestamp()));
}
for (final Entry ent : properties.entrySet()) {
if (ent.getKey().equals(TableConstants.PARTITION_KEY) || ent.getKey().equals(TableConstants.ROW_KEY)
|| ent.getKey().equals(TableConstants.TIMESTAMP) || ent.getKey().equals("Etag")) {
continue;
}
EntityProperty currProp = ent.getValue();
if (currProp.getEdmType().mustAnnotateType()) {
final String edmTypeString = currProp.getEdmType().toString();
// property type
generator.writeStringField(ent.getKey() + ODataConstants.ODATA_TYPE_SUFFIX, edmTypeString);
// property key and value
generator.writeStringField(ent.getKey(), ent.getValue().getValueAsString());
}
else if (currProp.getEdmType() == EdmType.DOUBLE && currProp.getIsNull() == false) {
final String edmTypeString = currProp.getEdmType().toString();
final Double value = currProp.getValueAsDouble();
// property type, if needed
if (value.equals(Double.POSITIVE_INFINITY) || value.equals(Double.NEGATIVE_INFINITY)
|| value.equals(Double.NaN)) {
generator.writeStringField(ent.getKey() + ODataConstants.ODATA_TYPE_SUFFIX, edmTypeString);
// property key and value
generator.writeStringField(ent.getKey(), ent.getValue().getValueAsString());
}
else {
writeJsonProperty(generator, ent);
}
}
else {
writeJsonProperty(generator, ent);
}
}
// end object
generator.writeEndObject();
}
private static void writeJsonProperty(JsonGenerator generator, Entry prop)
throws JsonGenerationException, IOException {
EdmType edmType = prop.getValue().getEdmType();
if (prop.getValue().getIsNull()) {
generator.writeNullField(prop.getKey());
}
else if (edmType == EdmType.BOOLEAN) {
generator.writeBooleanField(prop.getKey(), prop.getValue().getValueAsBoolean());
}
else if (edmType == EdmType.DOUBLE) {
generator.writeNumberField(prop.getKey(), prop.getValue().getValueAsDouble());
}
else if (edmType == EdmType.INT32) {
generator.writeNumberField(prop.getKey(), prop.getValue().getValueAsInteger());
}
else {
generator.writeStringField(prop.getKey(), prop.getValue().getValueAsString());
}
}
private static Map getPropertiesFromDictionary(TableEntity entity,
TableRequestOptions options, final OperationContext opContext) throws IOException, StorageException {
Map properties = entity.writeEntity(opContext);
if (properties == null) {
properties = new HashMap();
}
options.assertPolicyIfRequired();
// Check if encryption policy is set and invoke EncryptEnity if it is set.
if (options.getEncryptionPolicy() != null) {
properties = options.getEncryptionPolicy().encryptEntity(properties, entity.getPartitionKey(),
entity.getRowKey(), options.getEncryptionResolver());
}
return properties;
}
}