Package com.google.appengine.datanucleus

Source Code of com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl$DatastoreManagedConnection

/**********************************************************************
Copyright (c) 2009 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.appengine.datanucleus;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceConfig;

import org.datanucleus.ExecutionContext;
import org.datanucleus.PersistenceConfiguration;
import org.datanucleus.Transaction;
import org.datanucleus.store.StoreManager;
import org.datanucleus.store.connection.AbstractConnectionFactory;
import org.datanucleus.store.connection.ManagedConnection;
import org.datanucleus.store.connection.ManagedConnectionResourceListener;
import org.datanucleus.util.NucleusLogger;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.transaction.xa.XAResource;

/**
* Factory for connections to the datastore. There are two connection factories for a DatastoreManager.
* <ul>
* <li>Transactional : a connection (DatastoreService) is obtained at the start of the transaction and we
* call "beginTransaction" on it. It is closed at the end of the transaction after we call "commit"/"rollback".</li>
* <li>Nontransactional : a connection (DatastoreService) is obtained on the first operation, and is retained
* until PM/EM.close(). All operations are atomic, since we don't call "beginTransaction", hence no need to call
* "commit"/"rollback"</li>
* </ul>
*
* <p>
* By default, when the user invokes transaction.begin() in user-space this will start a DatastoreTransaction.
* If they have the persistence property <i>datanucleus.appengine.autoCreateDatastoreTxns</i> set to false
* then this means it will NOT start a transaction. Why anyone would want to do this is unknown to me
* but anyway it's there.
* </p>
*
* @author Max Ross <maxr@google.com>
*/
public class DatastoreConnectionFactoryImpl extends AbstractConnectionFactory {

  public static final String AUTO_CREATE_TXNS_PROPERTY =
      "datanucleus.appengine.autoCreateDatastoreTxns";

  private final boolean isAutoCreateTransaction;

  /**
   * Constructs a connection factory for the datastore.
   * Provides ManagedConnections to communicate with the datastore.
   *
   * @param storeMgr The store manager
   * @param resourceType Name of the resource ("appengine", "appengine-nontx")
   */
  public DatastoreConnectionFactoryImpl(StoreManager storeMgr, String resourceType) {
    super(storeMgr, resourceType);

    PersistenceConfiguration conf = storeMgr.getNucleusContext().getPersistenceConfiguration();
    if (conf.getProperty(DatastoreConnectionFactoryImpl.AUTO_CREATE_TXNS_PROPERTY) == null) {
        // User hasn't configured the "auto-create" property, so set it
        conf.setProperty(DatastoreConnectionFactoryImpl.AUTO_CREATE_TXNS_PROPERTY, Boolean.TRUE.toString());
    }
    this.isAutoCreateTransaction = conf.getBooleanProperty(AUTO_CREATE_TXNS_PROPERTY);
  }

  public void close() {}

  /**
   * {@inheritDoc}
   */
  public ManagedConnection getConnection(ExecutionContext ec, Transaction txn, Map options) {
    return storeMgr.getConnectionManager().allocateConnection(this, ec, txn, options);
  }

  /**
   * {@inheritDoc}
   */
  public ManagedConnection createManagedConnection(ExecutionContext ec, Map transactionOptions) {
    return new DatastoreManagedConnection(storeMgr, isAutoCreateTransaction());
  }

  boolean isAutoCreateTransaction() {
    return isAutoCreateTransaction;
  }

  // TODO Change this to extend AbstractManagedConnection
  static class DatastoreManagedConnection implements ManagedConnection {
    private boolean managed = false;
    private boolean locked = false;
    private final List<ManagedConnectionResourceListener> listeners =
        new ArrayList<ManagedConnectionResourceListener>();
    private final XAResource datastoreXAResource;

    DatastoreManagedConnection(StoreManager storeMgr, boolean autoCreateTransaction) {
      DatastoreManager datastoreManager = (DatastoreManager) storeMgr;
      DatastoreServiceConfig config = datastoreManager.getDefaultDatastoreServiceConfigForWrites();
      DatastoreService datastoreService = DatastoreServiceFactoryInternal.getDatastoreService(config);
      if (NucleusLogger.CONNECTION.isDebugEnabled()) {
        if (datastoreService instanceof WrappedDatastoreService) {
          NucleusLogger.CONNECTION.debug("Created ManagedConnection using DatastoreService = " +
              ((WrappedDatastoreService)datastoreService).getDelegate());
        } else {
          NucleusLogger.CONNECTION.debug("Created ManagedConnection using DatastoreService = " + datastoreService);
        }
      }
      if (autoCreateTransaction) {
        datastoreXAResource = new DatastoreXAResource(
            datastoreService, datastoreManager.getDefaultDatastoreTransactionOptions());
      } else {
        datastoreXAResource = new EmulatedXAResource(datastoreService);
      }
    }

    /* (non-Javadoc)
     * @see org.datanucleus.store.connection.ManagedConnection#closeAfterTransactionEnd()
     */
    @Override
    public boolean closeAfterTransactionEnd() {
      return true;
    }

    /* (non-Javadoc)
     * @see org.datanucleus.store.connection.ManagedConnection#closeOnRelease()
     */
    @Override
    public boolean closeOnRelease() {
      return false;
    }

    /* (non-Javadoc)
     * @see org.datanucleus.store.connection.ManagedConnection#commitOnRelease()
     */
    @Override
    public boolean commitOnRelease() {
      return false;
    }

    /* (non-Javadoc)
     * @see org.datanucleus.store.connection.ManagedConnection#setCloseOnRelease(boolean)
     */
    @Override
    public void setCloseOnRelease(boolean flag) {
    }

    /* (non-Javadoc)
     * @see org.datanucleus.store.connection.ManagedConnection#setCommitOnRelease(boolean)
     */
    @Override
    public void setCommitOnRelease(boolean flag) {
    }

    public Object getConnection() {
      // Return the DatastoreService
      return ((EmulatedXAResource)datastoreXAResource).getDatastoreService();
    }

    public XAResource getXAResource() {
      return datastoreXAResource;
    }

    public void release() {
      if (!managed) {       
        close();
      }
    }

    public void close() {
      // Take copy since listeners can de-register themselves at close
      List<ManagedConnectionResourceListener> resourceListeners = new ArrayList(listeners);

      for (ManagedConnectionResourceListener listener : resourceListeners) {
        listener.managedConnectionPreClose();
      }
      // nothing to actually close
      for (ManagedConnectionResourceListener listener : resourceListeners) {
        listener.managedConnectionPostClose();
      }
    }

    public void setManagedResource() {
      managed = true;
    }

    public boolean isLocked() {
      return locked;
    }

    public void lock() {
      locked = true;
    }

    public void unlock() {
      locked = false;
    }

    public void transactionFlushed() {
      for (ManagedConnectionResourceListener listener : listeners) {
        listener.transactionFlushed();
      }
    }

    public void transactionPreClose() {
      for (ManagedConnectionResourceListener listener : listeners) {
        listener.transactionPreClose();
      }
    }

    public void addListener(ManagedConnectionResourceListener listener) {
      listeners.add(listener);
    }

    public void removeListener(ManagedConnectionResourceListener listener) {
      listeners.remove(listener);
    }
  }
}
TOP

Related Classes of com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl$DatastoreManagedConnection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.