/* * Copyright 2010 Niclas Hedhman. * * 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.qi4j.entitystore.gae; import com.google.appengine.api.datastore.*; import java.util.LinkedList; import org.qi4j.api.entity.EntityDescriptor; import org.qi4j.api.entity.EntityReference; import org.qi4j.api.structure.Module; import org.qi4j.api.value.ValueSerialization; import org.qi4j.spi.entity.EntityState; import org.qi4j.spi.entity.EntityStatus; import org.qi4j.spi.entitystore.EntityNotFoundException; import org.qi4j.spi.entitystore.EntityStoreException; import org.qi4j.spi.entitystore.EntityStoreUnitOfWork; import org.qi4j.spi.entitystore.StateCommitter; public class GaeEntityStoreUnitOfWork implements EntityStoreUnitOfWork { private final DatastoreService datastore; private final ValueSerialization valueSerialization; private final String identity; private final Module module; private final long currentTime; private final LinkedList<GaeEntityState> states; public GaeEntityStoreUnitOfWork( DatastoreService datastore, ValueSerialization valueSerialization, String identity, Module module, long currentTime ) { this.datastore = datastore; this.valueSerialization = valueSerialization; this.identity = identity; this.module = module; this.currentTime = currentTime; states = new LinkedList<GaeEntityState>(); } @Override public String identity() { return identity; } @Override public long currentTime() { return currentTime; } @Override public EntityState newEntityState( EntityReference anIdentity, EntityDescriptor entityDescriptor ) throws EntityStoreException { Key key = KeyFactory.createKey( "qi4j-entity", anIdentity.identity() ); GaeEntityState state = new GaeEntityState( this, valueSerialization, key, entityDescriptor, module ); states.add( state ); return state; } @Override public EntityState entityStateOf( EntityReference reference ) throws EntityStoreException, EntityNotFoundException { Key key = KeyFactory.createKey( "qi4j-entity", reference.identity() ); try { Entity entity = datastore.get( key ); GaeEntityState state = new GaeEntityState( this, valueSerialization, entity, module ); states.add( state ); return state; } catch( com.google.appengine.api.datastore.EntityNotFoundException e ) { throw new EntityNotFoundException( reference ); } } @Override public StateCommitter applyChanges() throws EntityStoreException { Transaction transaction = datastore.beginTransaction(); for( GaeEntityState state : states ) { Entity entity = state.entity(); if( state.status() == EntityStatus.NEW || state.status() == EntityStatus.UPDATED ) { datastore.put( transaction, entity ); } if( state.status() == EntityStatus.REMOVED ) { datastore.delete( transaction, entity.getKey() ); } } return new GaeStateCommitter( transaction ); } @Override public void discard() { // nothing to do?? } private static class GaeStateCommitter implements StateCommitter { private Transaction transaction; public GaeStateCommitter( Transaction transaction ) { this.transaction = transaction; } @Override public void commit() { transaction.commit(); } @Override public void cancel() { transaction.rollback(); } } }