| // Copyright 2008 Google Inc. |
| // |
| // 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 com.google.gwtorm.client.impl; |
| |
| import com.google.gwtorm.client.Key; |
| import com.google.gwtorm.client.OrmException; |
| import com.google.gwtorm.client.Transaction; |
| |
| import java.util.LinkedHashMap; |
| import java.util.LinkedHashSet; |
| import java.util.Map; |
| import java.util.Set; |
| |
| public abstract class AbstractTransaction implements Transaction { |
| private static LinkedHashMap<Object, Action<?, Key<?>, AbstractTransaction>> newMap() { |
| return new LinkedHashMap<Object, Action<?, Key<?>, AbstractTransaction>>(); |
| } |
| |
| protected final Map<Object, Action<?, Key<?>, AbstractTransaction>> pendingInsert; |
| protected final Map<Object, Action<?, Key<?>, AbstractTransaction>> pendingUpdate; |
| protected final Map<Object, Action<?, Key<?>, AbstractTransaction>> pendingDelete; |
| |
| protected AbstractTransaction() { |
| pendingInsert = newMap(); |
| pendingUpdate = newMap(); |
| pendingDelete = newMap(); |
| } |
| |
| public void commit() throws OrmException { |
| for (Action<?, Key<?>, AbstractTransaction> a : pendingDelete.values()) { |
| a.doDelete(this); |
| } |
| for (Action<?, Key<?>, AbstractTransaction> a : pendingInsert.values()) { |
| a.doInsert(this); |
| } |
| for (Action<?, Key<?>, AbstractTransaction> a : pendingUpdate.values()) { |
| a.doUpdate(this); |
| } |
| } |
| |
| <E, K extends Key<?>, T extends AbstractTransaction> void queueInsert( |
| final AbstractAccess<E, ?, T> access, final Iterable<E> list) { |
| queue(pendingInsert, access, list); |
| } |
| |
| <E, K extends Key<?>, T extends AbstractTransaction> void queueUpdate( |
| final AbstractAccess<E, ?, T> access, final Iterable<E> list) { |
| queue(pendingUpdate, access, list); |
| } |
| |
| <E, K extends Key<?>, T extends AbstractTransaction> void queueDelete( |
| final AbstractAccess<E, ?, T> access, final Iterable<E> list) { |
| queue(pendingDelete, access, list); |
| } |
| |
| private static <E, K extends Key<?>, T extends AbstractTransaction> void queue( |
| final Map<Object, Action<?, Key<?>, AbstractTransaction>> queue, |
| final AbstractAccess<E, K, T> access, final Iterable<E> list) { |
| Action<E, K, T> c = get(queue, access); |
| if (c == null) { |
| c = new Action<E, K, T>(access); |
| put(queue, c); |
| } |
| c.addAll(list); |
| } |
| |
| @SuppressWarnings("unchecked") |
| private static <E, K extends Key<?>, T extends AbstractTransaction> Action<E, K, T> get( |
| final Map<Object, Action<?, Key<?>, AbstractTransaction>> q, |
| final AbstractAccess<E, K, T> access) { |
| return (Action<E, K, T>) q.get(access); |
| } |
| |
| @SuppressWarnings("unchecked") |
| private static <E, K extends Key<?>, T extends AbstractTransaction> void put( |
| final Map queue, Action<E, K, T> c) { |
| // This silly little method was needed to defeat the Java compiler's |
| // generic type checking. Somehow we got lost in the anonymous types |
| // from all the ? in our Map definition and the compiler just won't let |
| // us do a put into the map. |
| // |
| queue.put(c.access, c); |
| } |
| |
| private static class Action<E, K extends Key<?>, T extends AbstractTransaction> { |
| private final AbstractAccess<E, K, T> access; |
| private final Set<E> instances; |
| |
| Action(final AbstractAccess<E, K, T> a) { |
| access = a; |
| instances = new LinkedHashSet<E>(); |
| } |
| |
| void addAll(final Iterable<E> list) { |
| for (final E o : list) { |
| instances.add(o); |
| } |
| } |
| |
| void doInsert(final T t) throws OrmException { |
| access.doInsert(instances, t); |
| } |
| |
| void doUpdate(final T t) throws OrmException { |
| access.doUpdate(instances, t); |
| } |
| |
| void doDelete(final T t) throws OrmException { |
| access.doDelete(instances, t); |
| } |
| } |
| } |