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

com.google.appengine.api.datastore.RawValue Maven / Gradle / Ivy

/*
 * Copyright 2021 Google LLC
 *
 * 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
 *
 *     https://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.google.appengine.api.datastore;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.Objects.requireNonNull;

import com.google.appengine.api.users.User;
import com.google.datastore.v1.Value;
import com.google.datastore.v1.client.DatastoreHelper;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.storage.onestore.v3.OnestoreEntity.Property.Meaning;
import com.google.storage.onestore.v3.OnestoreEntity.PropertyValue;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * A raw datastore value.
 *
 * 

These are returned by projection queries when a {@link PropertyProjection} does not specify a * type. * * @see Query#getProjections() */ public final class RawValue implements Serializable { private static final long serialVersionUID = 8176992854378814427L; private transient @Nullable PropertyValue valueV3 = null; private transient @Nullable Value valueV1 = null; RawValue(PropertyValue propertyValue) { this.valueV3 = checkNotNull(propertyValue); } RawValue(Value value) { this.valueV1 = checkNotNull(value); } /** * Returns an object of the exact type passed in. * * @param type the class object for the desired type * @return an object of type T or {@code null} * @throws IllegalArgumentException if the raw value cannot be converted into the given type */ @SuppressWarnings("unchecked") public @Nullable T asStrictType(Class type) { Object value = asType(type); if (value != null) { checkArgument(type.isAssignableFrom(value.getClass()), "Unsupported type: %s", type); } return type.cast(value); } /** * Returns the object normally returned by the datastore if given type is passed in. * *

All integer values are returned as {@link Long}. All floating point values are returned as * {@link Double}. * * @param type the class object for the desired type * @return an object of type T or {@code null} * @throws IllegalArgumentException if the raw value cannot be converted into the given type */ public @Nullable Object asType(Class type) { DataTypeTranslator.Type typeAdapter = DataTypeTranslator.getTypeMap().get(type); checkArgument(typeAdapter != null, "Unsupported type: %s", type); if (valueV3 != null) { if (typeAdapter.hasValue(valueV3)) { return typeAdapter.getValue(valueV3); } } else if (valueV1 != null) { if (typeAdapter.hasValue(valueV1)) { return typeAdapter.getValue(valueV1); } } checkArgument(getValue() == null, "Type mismatch."); return null; } /** * Returns the raw value. * * @return An object of type {@link Boolean}, {@link Double}, {@link GeoPt}, {@link Key}, {@code * byte[]}, {@link User} or {@code null}. */ public @Nullable Object getValue() { if (valueV3 != null) { if (valueV3.hasBooleanValue()) { return valueV3.isBooleanValue(); } else if (valueV3.hasDoubleValue()) { return valueV3.getDoubleValue(); } else if (valueV3.hasInt64Value()) { return valueV3.getInt64Value(); } else if (valueV3.hasPointValue()) { return asType(GeoPt.class); } else if (valueV3.hasReferenceValue()) { return asType(Key.class); } else if (valueV3.hasStringValue()) { return valueV3.getStringValueAsBytes(); } else if (valueV3.hasUserValue()) { return asType(User.class); } } else if (valueV1 != null) { switch (valueV1.getValueTypeCase()) { case BOOLEAN_VALUE: return valueV1.getBooleanValue(); case DOUBLE_VALUE: return valueV1.getDoubleValue(); case INTEGER_VALUE: return valueV1.getIntegerValue(); case ENTITY_VALUE: if (valueV1.getMeaning() == 20) { return asType(User.class); } throw new IllegalStateException("Raw entity value is not supported."); case KEY_VALUE: return asType(Key.class); case STRING_VALUE: return valueV1.getStringValueBytes().toByteArray(); case BLOB_VALUE: // TODO: return a short blob? (not currently possible to get here). return valueV1.getBlobValue().toByteArray(); case TIMESTAMP_VALUE: // TODO: return a Date? (not currently possible to get here). return DatastoreHelper.getTimestamp(valueV1); case GEO_POINT_VALUE: if (valueV1.getMeaning() == 0 || valueV1.getMeaning() == Meaning.INDEX_VALUE.getValue()) { return asType(GeoPt.class); } break; // GeoPt with meaning becomes null. case ARRAY_VALUE: throw new IllegalStateException("Raw array value is not supported."); case NULL_VALUE: default: return null; } } return null; } // Serialization functions private void writeObject(ObjectOutputStream out) throws IOException { if (valueV3 != null) { out.write(1); // Writing version valueV3.writeTo(out); } else { out.write(2); // Writing version requireNonNull(valueV1).writeTo(out); } out.defaultWriteObject(); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { int version = in.read(); if (version == 1) { valueV3 = new PropertyValue(); boolean parsed = valueV3.parseFrom(in); if (!parsed || !valueV3.isInitialized()) { throw new InvalidProtocolBufferException("Could not parse PropertyValue"); } } else if (version == 2) { valueV1 = Value.parseFrom(in); } else { throw new IllegalArgumentException("unknown RawValue format"); } in.defaultReadObject(); } @Override public int hashCode() { Object value = getValue(); return value == null ? 0 : value.hashCode(); } @Override public boolean equals(@Nullable Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } RawValue other = (RawValue) obj; Object value = getValue(); Object otherValue = other.getValue(); if (value != null) { if (otherValue != null) { if (value instanceof byte[]) { if (otherValue instanceof byte[]) { return Arrays.equals((byte[]) value, (byte[]) otherValue); } } else { return value.equals(otherValue); } } } else if (otherValue == null) { return true; } return false; } @Override public String toString() { return "RawValue [value=" + getValue() + "]"; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy