PageRenderTime 32ms CodeModel.GetById 19ms app.highlight 9ms RepoModel.GetById 2ms app.codeStats 0ms

/src/com/google/appengine/datanucleus/EmulatedXAResource.java

http://datanucleus-appengine.googlecode.com/
Java | 125 lines | 67 code | 22 blank | 36 comment | 6 complexity | 4414ba05c4582425cdb89ea3912637fc MD5 | raw file
  1/**********************************************************************
  2Copyright (c) 2009 Google Inc.
  3
  4Licensed under the Apache License, Version 2.0 (the "License");
  5you may not use this file except in compliance with the License.
  6You may obtain a copy of the License at
  7
  8http://www.apache.org/licenses/LICENSE-2.0
  9
 10Unless required by applicable law or agreed to in writing, software
 11distributed under the License is distributed on an "AS IS" BASIS,
 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13See the License for the specific language governing permissions and
 14limitations under the License.
 15**********************************************************************/
 16package com.google.appengine.datanucleus;
 17
 18import javax.transaction.xa.XAException;
 19import javax.transaction.xa.XAResource;
 20import javax.transaction.xa.Xid;
 21
 22import org.datanucleus.util.Localiser;
 23
 24import com.google.appengine.api.datastore.DatastoreService;
 25
 26/**
 27 * This emulated XAResource only supports a small subset of XA functionality.
 28 * There's no underlying transaction, just some simple state management.
 29 * Instances of this class are instantiated and used when the datasource has
 30 * been configured as nontransactional and the user is not explicitly doing
 31 * any transaction management.
 32 *
 33 * @author Erick Armbrust <earmbrust@google.com>
 34 * @author Max Ross <maxr@google.com>
 35 */
 36class EmulatedXAResource implements XAResource {
 37  protected static final Localiser LOCALISER = Localiser.getInstance(
 38      "com.google.appengine.datanucleus.Localisation", DatastoreManager.class.getClassLoader());
 39
 40  private enum State {NEW, ACTIVE, INACTIVE}
 41
 42  private State state = State.NEW;
 43
 44  private final KeyRegistry keyRegistry = new KeyRegistry();
 45
 46  /** The datastore service we'll use to perform datastore operations. */
 47  protected final DatastoreService datastoreService;
 48
 49  public EmulatedXAResource(DatastoreService ds) {
 50    this.datastoreService = ds;
 51  }
 52
 53  public void start(Xid xid, int flags) throws XAException {
 54    if (state != State.NEW) {
 55      throw new XAException("Nested transactions are not supported");
 56    }
 57    state = State.ACTIVE;
 58  }
 59
 60  public void commit(Xid xid, boolean onePhase) throws XAException {
 61    if (state != State.ACTIVE) {
 62      throw new XAException(LOCALISER.msg("AppEngine.Transaction.CommitInvalid"));
 63    }
 64    keyRegistry.clearParentKeys();
 65    keyRegistry.clearUnownedObjects();
 66    state = State.INACTIVE;
 67  }
 68
 69  public void rollback(Xid xid) throws XAException {
 70    if (state != State.ACTIVE) {
 71      throw new XAException(LOCALISER.msg("AppEngine.Transaction.RollbackInvalid"));
 72    }
 73    keyRegistry.clearParentKeys();
 74    keyRegistry.clearUnownedObjects();
 75    state = State.INACTIVE;
 76  }
 77
 78  public int prepare(Xid xid) throws XAException {
 79    return XA_OK;
 80  }
 81
 82  public Xid[] recover(int flag) throws XAException {
 83    throw new XAException("Unsupported operation");
 84  }
 85
 86  public void end(Xid xid, int flags) throws XAException {
 87    // TODO (earmbrust): Should we throw an unsupported error?
 88  }
 89
 90  public void forget(Xid xid) throws XAException {
 91    // TODO (earmbrust): Should we throw an unsupported error?
 92  }
 93
 94  public int getTransactionTimeout() throws XAException {
 95    return 0;
 96  }
 97
 98  public boolean setTransactionTimeout(int seconds) throws XAException {
 99    return false;
100  }
101  
102  public boolean isSameRM(XAResource xares) throws XAException {
103    // We only support a single datastore, so this should always be true.
104    return true;
105  }
106
107  KeyRegistry getKeyRegistry() {
108    return keyRegistry;
109  }
110
111  /**
112   * Accessor for the DatastoreService of this connection.
113   * @return DatastoreService being used
114   */
115  DatastoreService getDatastoreService() {
116    return datastoreService;
117  }
118
119  /**
120   * @return The current transaction, or {@code null} if the datasource does not support transactions.
121   */
122  DatastoreTransaction getCurrentTransaction() {
123    return null;
124  }
125}