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

com.google.appengine.api.blobstore.BlobInfoFactory Maven / Gradle / Ivy

Go to download

API for Google App Engine standard environment with some of the dependencies shaded (repackaged)

There is a newer version: 2.0.27
Show newest version
/*
 * 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.blobstore;

import static java.util.Objects.requireNonNull;

import com.google.appengine.api.NamespaceManager;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import java.util.Date;
import java.util.Iterator;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * {@code BlobInfoFactory} provides a trivial interface for retrieving
 * {@link BlobInfo} metadata.
 *
 * 

BlobInfo metadata is stored in read-only {@code __BlobInfo__} * entities in the datastore. This class provides an easy way to * access these entities. For more complex queries, you can use the * datastore directly. * */ public class BlobInfoFactory { public static final String KIND = "__BlobInfo__"; public static final String CONTENT_TYPE = "content_type"; public static final String CREATION = "creation"; public static final String FILENAME = "filename"; public static final String SIZE = "size"; public static final String MD5_HASH = "md5_hash"; public static final String GS_OBJECT_NAME = "gs_object_name"; private final DatastoreService datastoreService; /** * Creates a {@code BlobInfoFactory} that uses the default * implementation of {@link DatastoreService}. */ public BlobInfoFactory() { this(DatastoreServiceFactory.getDatastoreService()); } /** * Creates a {@code BlobInfoFactory} with the specified * implementation of {@link DatastoreService}. */ public BlobInfoFactory(DatastoreService datastoreService) { this.datastoreService = datastoreService; } /** * Loads the {@link BlobInfo} metadata for {@code blobKey}. Returns * {@code null} if no matching blob is found. */ public @Nullable BlobInfo loadBlobInfo(BlobKey blobKey) { try { return createBlobInfo(datastoreService.get(getMetadataKeyForBlobKey(blobKey))); } catch (EntityNotFoundException ex) { return null; } } /** * Queries for {@link BlobInfo} instances, beginning with the {@link * BlobKey} that appears first in lexicographic order. */ public Iterator queryBlobInfos() { return queryBlobInfosAfter(null); } /** * Queries for {@link BlobInfo} instances, beginning at the blob * following {@code previousBlob} in lexicographic order. If {@code * previousBlob} is null, the first blob will be returned. * *

This is useful for displaying discrete pages of blobs. */ public Iterator queryBlobInfosAfter(@Nullable BlobKey previousBlob) { String origNamespace = NamespaceManager.get(); Query query; try { NamespaceManager.set(""); query = new Query(KIND, null); } finally { NamespaceManager.set(origNamespace); } if (previousBlob != null) { query.setFilter(new Query.FilterPredicate( Entity.KEY_RESERVED_PROPERTY, Query.FilterOperator.GREATER_THAN, getMetadataKeyForBlobKey(previousBlob))); } final Iterator parent = datastoreService.prepare(query).asIterator(); return new Iterator() { @Override public boolean hasNext() { return parent.hasNext(); } @Override public BlobInfo next() { return createBlobInfo(parent.next()); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } /** * Creates a {@link BlobInfo} by extracting content from the * specified {@link Entity}. */ public BlobInfo createBlobInfo(Entity entity) { // Recently created __BlobInfo__ entities will have a md5 hash property, // while older blobs will not. Ensure we construct the BlobInfo object // accordingly. Similarly, only __BlobInfo__ entities stored in Google // Cloud Storage have a gs_object_name. // TODO : Remove this check once b/3483289 is fixed. String md5Hash = BlobInfo.DEFAULT_MD5_HASH; if (entity.hasProperty(MD5_HASH)) { md5Hash = (String) entity.getProperty(MD5_HASH); } String gsObjectName = BlobInfo.DEFAULT_GS_OBJECT_NAME; if (entity.hasProperty(GS_OBJECT_NAME)) { gsObjectName = (String) entity.getProperty(GS_OBJECT_NAME); } return new BlobInfo( new BlobKey(requireNonNull(entity.getKey().getName())), (String) entity.getProperty(CONTENT_TYPE), (Date) entity.getProperty(CREATION), (String) entity.getProperty(FILENAME), (Long) entity.getProperty(SIZE), md5Hash, gsObjectName); } private Key getMetadataKeyForBlobKey(BlobKey blobKey) { String origNamespace = NamespaceManager.get(); try { NamespaceManager.set(""); return KeyFactory.createKey(null, KIND, blobKey.getKeyString()); } finally { NamespaceManager.set(origNamespace); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy