PageRenderTime 47ms CodeModel.GetById 9ms app.highlight 33ms RepoModel.GetById 2ms app.codeStats 0ms

/tests_bugs/com/google/appengine/datanucleus/bugs/jpa/JPABugTestCase.java

http://datanucleus-appengine.googlecode.com/
Java | 211 lines | 154 code | 28 blank | 29 comment | 17 complexity | 007253bb6a39f6cbc57f13342202be95 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.bugs.jpa;
 17
 18import com.google.appengine.api.datastore.DatastoreService;
 19import com.google.appengine.api.datastore.DatastoreServiceFactory;
 20import com.google.appengine.api.datastore.Query;
 21import com.google.appengine.datanucleus.DatastoreManager;
 22import com.google.appengine.datanucleus.bugs.DatastoreTestCase;
 23import com.google.appengine.datanucleus.EntityUtils;
 24
 25import org.datanucleus.ClassLoaderResolver;
 26import org.datanucleus.NucleusContext;
 27import org.datanucleus.api.jpa.JPAEntityManager;
 28import org.datanucleus.api.jpa.JPAEntityManagerFactory;
 29import org.datanucleus.metadata.MetaDataManager;
 30import org.datanucleus.ExecutionContext;
 31import org.datanucleus.store.mapped.MappedStoreManager;
 32
 33import java.util.Map;
 34import java.util.concurrent.ConcurrentHashMap;
 35
 36import javax.persistence.EntityManager;
 37import javax.persistence.EntityManagerFactory;
 38import javax.persistence.Persistence;
 39
 40/**
 41 * @author Max Ross <maxr@google.com>
 42 */
 43public class JPABugTestCase extends DatastoreTestCase {
 44
 45  private static
 46  ThreadLocal<Map<EntityManagerFactoryName, EntityManagerFactory>> emfCache =
 47      new ThreadLocal<Map<EntityManagerFactoryName, EntityManagerFactory>>() {
 48        @Override
 49        protected Map<EntityManagerFactoryName, EntityManagerFactory> initialValue() {
 50          // this shouldn't be necessary but I get concurrent mod exceptions
 51          return new ConcurrentHashMap<EntityManagerFactoryName, EntityManagerFactory>();
 52        }
 53      };
 54
 55  protected EntityManagerFactory emf;
 56  protected EntityManager em;
 57
 58  protected DatastoreService ds;
 59
 60  @Override
 61  protected void setUp() throws Exception {
 62    super.setUp();
 63    ds = DatastoreServiceFactory.getDatastoreService();
 64    emf = emfCache.get().get(getEntityManagerFactoryName());
 65    if (emf == null || !emf.isOpen()) {
 66      emf = Persistence.createEntityManagerFactory(getEntityManagerFactoryName().name());
 67      if (cacheManagers()) {
 68        emfCache.get().put(getEntityManagerFactoryName(), emf);
 69      }
 70    }
 71    em = emf.createEntityManager();
 72  }
 73
 74  public enum EntityManagerFactoryName {
 75    // nonTransactionalRead and nonTransactionalWrite are true
 76    transactional_ds_non_transactional_ops_allowed,
 77    // nonTransactionalRead and nonTransactionalWrite are false
 78    transactional_ds_non_transactional_ops_not_allowed,
 79    // nonTransactionalRead and nonTransactionalWrite are true
 80    nontransactional_ds_non_transactional_ops_allowed,
 81    // nonTransactionalRead and nonTransactionalWrite are false
 82    nontransactional_ds_non_transactional_ops_not_allowed
 83  }
 84
 85  /**
 86   * By default we use a datasource that requires txns.
 87   * Override this if your test needs to use a different instance.
 88   */
 89  protected EntityManagerFactoryName getEntityManagerFactoryName() {
 90    return EntityManagerFactoryName.transactional_ds_non_transactional_ops_not_allowed;
 91  }
 92
 93  @Override
 94  protected void tearDown() throws Exception {
 95    try {
 96      if (em.isOpen()) {
 97        if (em.getTransaction().isActive()) {
 98          em.getTransaction().rollback();
 99        }
100        em.close();
101      }
102      em = null;
103      // see if anybody closed any of our emfs and if so just remove them from the cache -
104      // we'll rebuild it the next time it's needed.
105      for (Map.Entry<EntityManagerFactoryName, EntityManagerFactory> entry : emfCache.get().entrySet()) {
106        if (!entry.getValue().isOpen()) {
107          emfCache.get().remove(entry.getKey());
108        }
109      }
110      if (!cacheManagers() && emf.isOpen()) {
111        emf.close();
112      }
113      emf = null;
114    } finally {
115      super.tearDown();
116    }
117  }
118
119  protected void beginTxn() {
120    em.getTransaction().begin();
121  }
122
123  protected void commitTxn() {
124    em.getTransaction().commit();
125  }
126
127  protected void rollbackTxn() {
128    if (em.getTransaction().isActive()) {
129      em.getTransaction().rollback();
130    }
131  }
132
133  protected void switchDatasource(EntityManagerFactoryName name) {
134    switchDatasource(name, null);
135  }
136
137  protected void switchDatasource(EntityManagerFactoryName name, Map<String, String> props) {
138    em.close();
139    if (!cacheManagers() && emf.isOpen()) {
140      emf.close();
141    }
142    if (props == null) {
143      emf = Persistence.createEntityManagerFactory(name.name());
144    } else {
145      emf = Persistence.createEntityManagerFactory(name.name(), props);
146    }
147    em = emf.createEntityManager();
148  }
149
150  @SuppressWarnings("deprecation")
151  public int countForClass(Class<?> clazz) {
152    String kind = kindForClass(clazz);
153    return ds.prepare(new Query(kind)).countEntities();
154  }
155
156  protected String kindForClass(Class<?> clazz) {
157    NucleusContext nucContext = ((JPAEntityManagerFactory)emf).getNucleusContext();
158    MetaDataManager mdm = nucContext.getMetaDataManager();
159    MappedStoreManager storeMgr = (MappedStoreManager) nucContext.getStoreManager();
160    ClassLoaderResolver clr = nucContext.getClassLoaderResolver(getClass().getClassLoader());
161    return EntityUtils.determineKind(
162        mdm.getMetaDataForClass(
163            clazz,
164            nucContext.getClassLoaderResolver(getClass().getClassLoader())),
165            storeMgr,
166            clr);
167  }
168
169  protected ExecutionContext getExecutionContext() {
170    return ((JPAEntityManager)em).getExecutionContext();
171  }
172
173  protected String kindForObject(Object obj) {
174    return kindForClass(obj.getClass());
175  }
176
177  private boolean cacheManagers() {
178    return !Boolean.valueOf(System.getProperty("do.not.cache.managers"));
179  }
180
181  interface StartEnd {
182    void start();
183    void end();
184  }
185
186  final StartEnd TXN_START_END = new StartEnd() {
187    public void start() {
188      beginTxn();
189    }
190
191    public void end() {
192      commitTxn();
193    }
194  };
195
196  final StartEnd NEW_EM_START_END = new StartEnd() {
197    public void start() {
198      if (!em.isOpen()) {
199        em = emf.createEntityManager();
200      }
201    }
202
203    public void end() {
204      em.close();
205    }
206  };
207
208  protected DatastoreManager getStoreManager() {
209    return (DatastoreManager) getExecutionContext().getStoreManager();
210  }
211}