PageRenderTime 16ms CodeModel.GetById 1ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/com/google/appengine/datanucleus/jpa/JPATestCase.java

http://datanucleus-appengine.googlecode.com/
Java | 227 lines | 167 code | 31 blank | 29 comment | 18 complexity | 9e2be125e74fd993094c24caa7f0a831 MD5 | raw file
  1/*********************b*************************************************
  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.jpa;
 17
 18import com.google.appengine.api.datastore.*;
 19import com.google.appengine.datanucleus.DatastoreManager;
 20import com.google.appengine.datanucleus.DatastoreTestCase;
 21import com.google.appengine.datanucleus.EntityUtils;
 22import com.google.appengine.datanucleus.StorageVersion;
 23
 24import org.datanucleus.ClassLoaderResolver;
 25import org.datanucleus.NucleusContext;
 26import org.datanucleus.api.jpa.JPAEntityManager;
 27import org.datanucleus.api.jpa.JPAEntityManagerFactory;
 28import org.datanucleus.metadata.MetaDataManager;
 29import org.datanucleus.ExecutionContext;
 30import org.datanucleus.store.mapped.MappedStoreManager;
 31
 32import java.util.List;
 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 JPATestCase 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    originalStorageVersion,
 84  }
 85
 86  /**
 87   * By default we use a datasource that requires txns.
 88   * Override this if your test needs to use a different instance.
 89   */
 90  protected EntityManagerFactoryName getEntityManagerFactoryName() {
 91    return EntityManagerFactoryName.transactional_ds_non_transactional_ops_not_allowed;
 92  }
 93
 94  @Override
 95  protected void tearDown() throws Exception {
 96    try {
 97      if (em.isOpen()) {
 98        if (em.getTransaction().isActive()) {
 99          em.getTransaction().rollback();
100        }
101        em.close();
102      }
103      em = null;
104      // see if anybody closed any of our emfs and if so just remove them from the cache -
105      // we'll rebuild it the next time it's needed.
106      for (Map.Entry<EntityManagerFactoryName, EntityManagerFactory> entry : emfCache.get().entrySet()) {
107        if (!entry.getValue().isOpen()) {
108          emfCache.get().remove(entry.getKey());
109        }
110      }
111      if (!cacheManagers() && emf.isOpen()) {
112        emf.close();
113      }
114      emf = null;
115    } finally {
116      super.tearDown();
117    }
118  }
119
120  protected DatastoreManager getDatastoreManagerForEM(EntityManager em) {
121    return (DatastoreManager) ((JPAEntityManager)em).getExecutionContext().getStoreManager();
122  }
123
124  protected StorageVersion getStorageVersion(EntityManager em) {
125    return getDatastoreManagerForEM(em).getStorageVersion();
126  }
127
128  protected void beginTxn() {
129    em.getTransaction().begin();
130  }
131
132  protected void commitTxn() {
133    em.getTransaction().commit();
134  }
135
136  protected void rollbackTxn() {
137    if (em.getTransaction().isActive()) {
138      em.getTransaction().rollback();
139    }
140  }
141
142  protected void switchDatasource(EntityManagerFactoryName name) {
143    switchDatasource(name, null);
144  }
145
146  protected void switchDatasource(EntityManagerFactoryName name, Map<String, String> props) {
147    em.close();
148    if (!cacheManagers() && emf.isOpen()) {
149      emf.close();
150    }
151    if (props == null) {
152      emf = Persistence.createEntityManagerFactory(name.name());
153    } else {
154      emf = Persistence.createEntityManagerFactory(name.name(), props);
155    }
156    em = emf.createEntityManager();
157  }
158
159  @SuppressWarnings("deprecation")
160  public int countForClass(Class<?> clazz) {
161    String kind = kindForClass(clazz);
162    return ds.prepare(new Query(kind)).countEntities();
163  }
164
165  protected void deleteAll() {
166    List<Entity> entities = ds.prepare(new Query().setKeysOnly()).asList(FetchOptions.Builder.withDefaults());
167    for (Entity entity : entities) {
168      ds.delete(entity.getKey());
169    }
170  }
171
172  protected String kindForClass(Class<?> clazz) {
173    NucleusContext nucContext = ((JPAEntityManagerFactory)emf).getNucleusContext();
174    MetaDataManager mdm = nucContext.getMetaDataManager();
175    MappedStoreManager storeMgr = (MappedStoreManager) nucContext.getStoreManager();
176    ClassLoaderResolver clr = nucContext.getClassLoaderResolver(getClass().getClassLoader());
177    return EntityUtils.determineKind(
178        mdm.getMetaDataForClass(
179            clazz,
180            nucContext.getClassLoaderResolver(getClass().getClassLoader())),
181            storeMgr,
182            clr);
183  }
184
185  protected ExecutionContext getExecutionContext() {
186    return ((JPAEntityManager)em).getExecutionContext();
187  }
188
189  protected String kindForObject(Object obj) {
190    return kindForClass(obj.getClass());
191  }
192
193  private boolean cacheManagers() {
194    return !Boolean.valueOf(System.getProperty("do.not.cache.managers"));
195  }
196
197  interface StartEnd {
198    void start();
199    void end();
200  }
201
202  final StartEnd TXN_START_END = new StartEnd() {
203    public void start() {
204      beginTxn();
205    }
206
207    public void end() {
208      commitTxn();
209    }
210  };
211
212  final StartEnd NEW_EM_START_END = new StartEnd() {
213    public void start() {
214      if (!em.isOpen()) {
215        em = emf.createEntityManager();
216      }
217    }
218
219    public void end() {
220      em.close();
221    }
222  };
223
224  protected DatastoreManager getStoreManager() {
225    return (DatastoreManager) getExecutionContext().getStoreManager();
226  }
227}