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

org.springframework.cloud.gcp.data.datastore.core.convert.DatastoreServiceObjectToKeyFactory Maven / Gradle / Ivy

/*
 * Copyright 2017-2019 the original author or authors.
 *
 * 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 org.springframework.cloud.gcp.data.datastore.core.convert;

import java.util.function.Supplier;

import com.google.cloud.datastore.Datastore;
import com.google.cloud.datastore.IncompleteKey;
import com.google.cloud.datastore.Key;
import com.google.cloud.datastore.KeyFactory;

import org.springframework.cloud.gcp.data.datastore.core.DatastoreTemplate;
import org.springframework.cloud.gcp.data.datastore.core.mapping.DatastoreDataException;
import org.springframework.cloud.gcp.data.datastore.core.mapping.DatastorePersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.util.Assert;

/**
 * Implementation of {@link ObjectToKeyFactory} where the key factories are provided by
 * the Datastore Service.
 *
 * @author Chengyuan Zhao
 *
 * @since 1.1
 */
public class DatastoreServiceObjectToKeyFactory implements ObjectToKeyFactory {

	private final Supplier datastore;

	public DatastoreServiceObjectToKeyFactory(Supplier datastore) {
		Assert.notNull(datastore, "A non-null Datastore service is required.");
		this.datastore = datastore;
	}

	@Override
	public IncompleteKey getIncompleteKey(String kindName) {
		return this.datastore.get().newKeyFactory().setKind(kindName).newKey();
	}

	@Override
	public Key getKeyFromId(Object id, String kindName) {
		Assert.notNull(id, "Cannot get key for null ID value.");
		if (id instanceof Key) {
			return (Key) id;
		}
		KeyFactory keyFactory = getKeyFactory();
		keyFactory.setKind(kindName);
		Key key;
		if (id instanceof String) {
			key = keyFactory.newKey((String) id);
		}
		else if (id instanceof Long) {
			key = keyFactory.newKey((long) id);
		}
		else {
			// We will use configurable custom converters to try to convert other types to
			// String or long
			// in the future.
			throw new DatastoreDataException(
					"Keys can only be created using String or long values.");
		}
		return key;
	}

	@Override
	public Key getKeyFromObject(Object entity, DatastorePersistentEntity datastorePersistentEntity) {
		Assert.notNull(entity, "Cannot get key for null entity object.");
		Assert.notNull(datastorePersistentEntity, "Persistent entity must not be null.");
		PersistentProperty idProp = datastorePersistentEntity.getIdPropertyOrFail();
		Object idVal = datastorePersistentEntity.getPropertyAccessor(entity).getProperty(idProp);
		if (idVal == null) {
			return null;
		}
		else {
			return getKeyFromId(idVal, datastorePersistentEntity.kindName());
		}
	}

	@Override
	public Key allocateKeyForObject(Object entity,
			DatastorePersistentEntity datastorePersistentEntity, Key... ancestors) {
		Assert.notNull(entity, "Cannot get key for null entity object.");
		Assert.notNull(datastorePersistentEntity, "Persistent entity must not be null.");
		PersistentProperty idProp = datastorePersistentEntity.getIdPropertyOrFail();

		Class idPropType = idProp.getType();

		if (!idPropType.equals(Key.class) && !idPropType.equals(Long.class)) {
			throw new DatastoreDataException("Cloud Datastore can only allocate IDs for Long and Key properties. " +
					"Cannot allocate for type: " + idPropType);
		}

		KeyFactory keyFactory = getKeyFactory().setKind(datastorePersistentEntity.kindName());
		if (ancestors != null && ancestors.length > 0) {
			if (!idPropType.equals(Key.class)) {
				throw new DatastoreDataException("Only Key types are allowed for descendants id");
			}
			for (Key ancestor : ancestors) {
				keyFactory.addAncestor(DatastoreTemplate.keyToPathElement(ancestor));
			}
		}
		Key allocatedKey = this.datastore.get().allocateId(keyFactory.newKey());

		Object value;
		if (idPropType.equals(Key.class)) {
			value = allocatedKey;
		}
		else if (idPropType.equals(Long.class)) {
			value = allocatedKey.getId();
		}
		else {
			value = allocatedKey.getId().toString();
		}

		datastorePersistentEntity.getPropertyAccessor(entity).setProperty(idProp, value);
		return allocatedKey;
	}

	private KeyFactory getKeyFactory() {
		return this.datastore.get().newKeyFactory();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy