001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.kernel;
020:
021: import java.io.Serializable;
022: import java.util.Collection;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.Map;
026:
027: /**
028: * Represents a savepoint where operations afterwards can be rolled
029: * back and restored to this point
030: *
031: * @author Steve Kim
032: * @since 0.3.4
033: */
034: public class OpenJPASavepoint implements Serializable {
035:
036: private final Broker _broker;
037: private final String _name;
038: private final boolean _copy;
039:
040: // <StateManagerImpl, SavepointFieldManager>
041: private Map _saved;
042:
043: /**
044: * Constructor. Indicate whether to copy field data into memory.
045: */
046: public OpenJPASavepoint(Broker broker, String name, boolean copy) {
047: _broker = broker;
048: _name = name;
049: _copy = copy;
050: }
051:
052: /**
053: * Return the Broker associated with this savepoint.
054: */
055: public Broker getBroker() {
056: return _broker;
057: }
058:
059: /**
060: * Return the name for this savepoint.
061: */
062: public String getName() {
063: return _name;
064: }
065:
066: /**
067: * Whether this savepoint copies the field values of retained instances.
068: */
069: public boolean getCopyFieldState() {
070: return _copy;
071: }
072:
073: /**
074: * Return the map of states to savepoint data.
075: */
076: protected Map getStates() {
077: return _saved;
078: }
079:
080: /**
081: * Set this savepoint, saving any state for the passed-in
082: * {@link OpenJPAStateManager}s as necessary.
083: */
084: public void save(Collection states) {
085: if (_saved != null)
086: throw new IllegalStateException();
087:
088: _saved = new HashMap((int) (states.size() * 1.33 + 1));
089: StateManagerImpl sm;
090: for (Iterator i = states.iterator(); i.hasNext();) {
091: sm = (StateManagerImpl) i.next();
092: _saved.put(sm, new SavepointFieldManager(sm, _copy));
093: }
094: }
095:
096: /**
097: * Release this savepoint and any associated resources. Releases
098: * will happen in reverse order of creation.
099: *
100: * @param user if true, user initiated, otherwise a side effect of
101: * another savepoint's release/rollback
102: */
103: public void release(boolean user) {
104: _saved = null;
105: }
106:
107: /**
108: * Handle the rolled back state, returning saved data.
109: * Subclasses should return the collection returned from this method.
110: *
111: * @param previous previous savepoints set in the transaction
112: */
113: public Collection rollback(Collection previous) {
114: Map saved;
115: if (previous.isEmpty())
116: saved = _saved;
117: else {
118: // merge all changes into one collection, allowing for later
119: // SavepointFieldManagers to replace previous ones.
120: saved = new HashMap();
121: for (Iterator i = previous.iterator(); i.hasNext();)
122: saved.putAll(((OpenJPASavepoint) i.next()).getStates());
123: saved.putAll(_saved);
124: }
125: _saved = null;
126: return saved.values();
127: }
128: }
|