Package org.slim3.datastore

Source Code of org.slim3.datastore.Journal

/*
* Copyright 2004-2010 the Seasar Foundation and the Others.
*
* 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 org.slim3.datastore;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.google.appengine.api.datastore.AsyncDatastoreService;
import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityTranslator;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.apphosting.api.DatastorePb.PutRequest;
import com.google.storage.onestore.v3.OnestoreEntity.EntityProto;

/**
* A class for journal.
*
* @author higa
* @since 1.0.0
*
*/
public class Journal {

    /**
     * The kind of journal entity.
     */
    public static final String KIND = "slim3.Journal";

    /**
     * The globalTransactionKey property name.
     */
    public static final String GLOBAL_TRANSACTION_KEY_PROPERTY =
        "globalTransactionKey";

    /**
     * The content property name.
     */
    public static final String CONTENT_PROPERTY = "content";

    /**
     * The putList property prefix.
     */
    public static final String PUT_LIST_PROPERTY = "putList";

    /**
     * The deleteList property prefix.
     */
    public static final String DELETE_LIST_PROPERTY = "deleteList";

    /**
     * Applies the journals.
     *
     * @param ds
     *            the asynchronous datastore service
     * @param globalTransactionKey
     *            the global transaction key
     * @throws NullPointerException
     *             if the globalTransactionKey parameter is null
     *
     */
    public static void apply(AsyncDatastoreService ds, Key globalTransactionKey)
            throws NullPointerException {
        if (globalTransactionKey == null) {
            throw new NullPointerException(
                "The globalTransactionKey parameter must not be null.");
        }
        List<Entity> entities =
            new EntityQuery(ds, KIND).filter(
                GLOBAL_TRANSACTION_KEY_PROPERTY,
                FilterOperator.EQUAL,
                globalTransactionKey).asList();
        apply(ds, entities);
    }

    /**
     * Applies the journals.
     *
     * @param ds
     *            the asynchronous datastore service
     * @param entities
     *            the entities
     * @throws NullPointerException
     *             if the ds parameter is null or if the entities parameter is
     *             null
     *
     */
    @SuppressWarnings("unchecked")
    public static void apply(AsyncDatastoreService ds, List<Entity> entities)
            throws NullPointerException {
        if (ds == null) {
            throw new NullPointerException("The ds parameter must not be null.");
        }
        if (entities == null) {
            throw new NullPointerException(
                "The entities parameter must not be null.");
        }
        for (Entity entity : entities) {
            PutRequest putReq = new PutRequest();
            List<Blob> putList =
                (List<Blob>) entity.getProperty(PUT_LIST_PROPERTY);
            List<Key> deleteList =
                (List<Key>) entity.getProperty(DELETE_LIST_PROPERTY);
            List<Entity> putEntities = new ArrayList<Entity>();
            if (putList != null) {
                for (Blob blob : putList) {
                    EntityProto proto = putReq.addEntity();
                    proto.mergeFrom(blob.getBytes());
                    putEntities.add(EntityTranslator.createFromPb(proto));
                }
            }
            if (putEntities.size() > 0) {
                DatastoreUtil.put(ds, null, putEntities);
            }
            if (deleteList != null) {
                DatastoreUtil.delete(ds, null, deleteList);
            }
            DatastoreUtil.delete(ds, null, entity.getKey());
        }
    }

    /**
     * Applies the journals.
     *
     * @param ds
     *            the asynchronous datastore service
     * @param tx
     *            the transaction
     * @param journals
     *            the journals
     * @throws NullPointerException
     *             if the ds parameter is null or if the tx parameter is null or
     *             if the journals parameter is null
     *
     */
    public static void apply(AsyncDatastoreService ds, Transaction tx,
            Map<Key, Entity> journals) throws NullPointerException {
        if (ds == null) {
            throw new NullPointerException("The ds parameter must not be null.");
        }
        if (tx == null) {
            throw new NullPointerException("The tx parameter must not be null.");
        }
        if (journals == null) {
            throw new NullPointerException(
                "The journals parameter must not be null.");
        }
        List<Entity> putList = new ArrayList<Entity>();
        List<Key> deleteList = new ArrayList<Key>();
        for (Key key : journals.keySet()) {
            Entity entity = journals.get(key);
            if (entity != null) {
                putList.add(entity);
            } else {
                deleteList.add(key);
            }
        }
        DatastoreUtil.put(ds, tx, putList);
        DatastoreUtil.delete(ds, tx, deleteList);
    }

    /**
     * Puts the journals to the datastore.
     *
     * @param ds
     *            the asynchronous datastore service
     * @param globalTransactionKey
     *            the global transaction key
     * @param journalMap
     *            the map of journals
     * @return journal entities
     * @throws NullPointerException
     *             if the ds parameter is null or if the globalTransactionKey
     *             parameter is null or if the journalMap parameter is null
     *
     */
    public static List<Entity> put(AsyncDatastoreService ds,
            Key globalTransactionKey, Map<Key, Entity> journalMap)
            throws NullPointerException {
        if (ds == null) {
            throw new NullPointerException("The ds parameter must not be null.");
        }
        if (journalMap == null) {
            throw new NullPointerException(
                "The journalMap parameter must not be null.");
        }
        List<Entity> entities = new ArrayList<Entity>();
        if (journalMap.size() == 0) {
            return entities;
        }
        int totalSize = 0;
        Entity entity = createEntity(ds, globalTransactionKey);
        List<Blob> putList = new ArrayList<Blob>();
        List<Key> deleteList = new ArrayList<Key>();
        for (Key key : journalMap.keySet()) {
            Entity targetEntity = journalMap.get(key);
            boolean put = targetEntity != null;
            EntityProto targetProto =
                put ? EntityTranslator.convertToPb(targetEntity) : null;
            int size = put ? targetProto.encodingSize() : 0;
            if (totalSize != 0
                && totalSize + size + DatastoreUtil.EXTRA_SIZE > DatastoreUtil.MAX_ENTITY_SIZE) {
                entity.setUnindexedProperty(PUT_LIST_PROPERTY, putList);
                entity.setUnindexedProperty(DELETE_LIST_PROPERTY, deleteList);
                DatastoreUtil.put(ds, null, entity);
                entities.add(entity);
                entity = createEntity(ds, globalTransactionKey);
                putList = new ArrayList<Blob>();
                deleteList = new ArrayList<Key>();
                totalSize = 0;
            }
            if (put) {
                byte[] content = new byte[targetProto.encodingSize()];
                targetProto.outputTo(content, 0);
                putList.add(new Blob(content));
            } else {
                deleteList.add(key);
            }
            totalSize += size + DatastoreUtil.EXTRA_SIZE;
        }
        entity.setUnindexedProperty(PUT_LIST_PROPERTY, putList);
        entity.setUnindexedProperty(DELETE_LIST_PROPERTY, deleteList);
        DatastoreUtil.put(ds, null, entity);
        entities.add(entity);
        return entities;
    }

    /**
     * Deletes entities specified by the global transaction key in transaction.
     *
     * @param ds
     *            the asynchronous datastore service
     * @param globalTransactionKey
     *            the global transaction key
     * @throws NullPointerException
     *             if the ds parameter is null or if the globalTransactionKey
     *             parameter is null
     */
    public static void deleteInTx(AsyncDatastoreService ds,
            Key globalTransactionKey) throws NullPointerException {
        if (ds == null) {
            throw new NullPointerException("The ds parameter must not be null.");
        }
        if (globalTransactionKey == null) {
            throw new NullPointerException(
                "The globalTransactionKey parameter must not be null.");
        }
        List<Key> keys = getKeys(ds, globalTransactionKey);
        for (Key key : keys) {
            deleteInTx(ds, globalTransactionKey, key);
        }
    }

    /**
     * Returns the keys specified by the global transaction key.
     *
     * @param ds
     *            the asynchronous datastore service
     * @param globalTransactionKey
     *            the global transaction key
     * @return a list of keys
     * @throws NullPointerException
     *             if the ds parameter is null or if the globalTransactionKey
     *             parameter is null
     *
     */
    protected static List<Key> getKeys(AsyncDatastoreService ds,
            Key globalTransactionKey) throws NullPointerException {
        if (ds == null) {
            throw new NullPointerException("The ds parameter must not be null.");
        }
        if (globalTransactionKey == null) {
            throw new NullPointerException(
                "The globalTransactionKey parameter must not be null.");
        }
        return new EntityQuery(ds, KIND).filter(
            GLOBAL_TRANSACTION_KEY_PROPERTY,
            FilterOperator.EQUAL,
            globalTransactionKey).asKeyList();
    }

    /**
     * Creates an entity.
     *
     * @param ds
     *            the asynchronous datastore service
     * @param globalTransactionKey
     *            the global transaction key
     * @return an entity
     * @throws NullPointerException
     *             if the ds parameter is null or if the globalTransactionKey
     *             parameter is null
     */
    protected static Entity createEntity(AsyncDatastoreService ds,
            Key globalTransactionKey) throws NullPointerException {
        if (ds == null) {
            throw new NullPointerException("The ds parameter must not be null.");
        }
        if (globalTransactionKey == null) {
            throw new NullPointerException(
                "The globalTransactionKey parameter must not be null.");
        }
        Entity entity = new Entity(DatastoreUtil.allocateId(ds, KIND));
        entity.setProperty(
            GLOBAL_TRANSACTION_KEY_PROPERTY,
            globalTransactionKey);
        return entity;
    }

    /**
     * Deletes an entity specified by the key in transaction.
     *
     * @param ds
     *            the asynchronous datastore service
     * @param globalTransactionKey
     *            the global transaction key
     * @param key
     *            the key
     *
     * @throws NullPointerException
     *             if the ds parameter is null or if the globalTransactionKey
     *             parameter is null or if the key parameter is null
     */
    protected static void deleteInTx(AsyncDatastoreService ds,
            Key globalTransactionKey, Key key) throws NullPointerException {
        if (ds == null) {
            throw new NullPointerException("The ds parameter must not be null.");
        }
        if (globalTransactionKey == null) {
            throw new NullPointerException(
                "The globalTransactionKey parameter must not be null.");
        }
        if (key == null) {
            throw new NullPointerException(
                "The key parameter must not be null.");
        }
        Transaction tx = DatastoreUtil.beginTransaction(ds);
        try {
            Entity entity = DatastoreUtil.getOrNull(ds, tx, key);
            if (entity != null
                && globalTransactionKey.equals(entity
                    .getProperty(GLOBAL_TRANSACTION_KEY_PROPERTY))) {
                DatastoreUtil.delete(ds, tx, key);
                tx.commit();
            }
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
        }
    }

    /**
     * Constructor.
     *
     */
    private Journal() {
    }
}
TOP

Related Classes of org.slim3.datastore.Journal

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.