| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.apache.openjpa.kernel; |
| |
| import java.io.Serializable; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| /** |
| * Represents a savepoint where operations afterwards can be rolled |
| * back and restored to this point |
| * |
| * @author Steve Kim |
| * @since 0.3.4 |
| */ |
| public class OpenJPASavepoint implements Serializable { |
| private static final long serialVersionUID = 1L; |
| private final Broker _broker; |
| private final String _name; |
| private final boolean _copy; |
| |
| private Map<StateManagerImpl, SavepointFieldManager> _saved; |
| |
| /** |
| * Constructor. Indicate whether to copy field data into memory. |
| */ |
| public OpenJPASavepoint(Broker broker, String name, boolean copy) { |
| _broker = broker; |
| _name = name; |
| _copy = copy; |
| } |
| |
| /** |
| * Return the Broker associated with this savepoint. |
| */ |
| public Broker getBroker() { |
| return _broker; |
| } |
| |
| /** |
| * Return the name for this savepoint. |
| */ |
| public String getName() { |
| return _name; |
| } |
| |
| /** |
| * Whether this savepoint copies the field values of retained instances. |
| */ |
| public boolean getCopyFieldState() { |
| return _copy; |
| } |
| |
| /** |
| * Return the map of states to savepoint data. |
| */ |
| protected Map<StateManagerImpl, SavepointFieldManager> getStates() { |
| return _saved; |
| } |
| |
| /** |
| * Set this savepoint, saving any state for the passed-in |
| * {@link OpenJPAStateManager}s as necessary. |
| */ |
| public void save(Collection<StateManagerImpl> states) { |
| if (_saved != null) |
| throw new IllegalStateException(); |
| |
| _saved = new HashMap<>((int) (states.size() * 1.33 + 1)); |
| for (StateManagerImpl sm : states) { |
| _saved.put(sm, new SavepointFieldManager(sm, _copy)); |
| } |
| } |
| |
| /** |
| * Release this savepoint and any associated resources. Releases |
| * will happen in reverse order of creation. |
| * |
| * @param user if true, user initiated, otherwise a side effect of |
| * another savepoint's release/rollback |
| */ |
| public void release(boolean user) { |
| _saved = null; |
| } |
| |
| /** |
| * Handle the rolled back state, returning saved data. |
| * Subclasses should return the collection returned from this method. |
| * |
| * @param previous previous savepoints set in the transaction |
| */ |
| public Collection<SavepointFieldManager> rollback(Collection<OpenJPASavepoint> previous) { |
| Map<StateManagerImpl, SavepointFieldManager> saved; |
| if (previous.isEmpty()) |
| saved = _saved; |
| else { |
| // merge all changes into one collection, allowing for later |
| // SavepointFieldManagers to replace previous ones. |
| saved = new HashMap<>(); |
| for (OpenJPASavepoint savepoint : previous) |
| saved.putAll(savepoint.getStates()); |
| saved.putAll(_saved); |
| } |
| _saved = null; |
| return saved.values (); |
| } |
| } |