/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.openjpa.persistence; import java.sql.Connection; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import javax.persistence.Query; import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.sql.DerbyDictionary; import org.apache.openjpa.kernel.QueryLanguages; import org.apache.openjpa.lib.jdbc.DelegatingConnection; import org.apache.openjpa.persistence.test.SingleEMFTestCase; public class TestUnwrap extends SingleEMFTestCase { /** * Tests a query can be unwrapped as an instance of a series of class or * interface. */ public void testValidQueryUnwrap() { OpenJPAEntityManager em = emf.createEntityManager(); Query query = em.createQuery(QueryLanguages.LANG_SQL,""); Class[] validCasts = new Class[] { org.apache.openjpa.persistence.OpenJPAQuery.class, org.apache.openjpa.persistence.OpenJPAQuerySPI.class, org.apache.openjpa.kernel.DelegatingQuery.class, org.apache.openjpa.kernel.Query.class, org.apache.openjpa.kernel.QueryImpl.class }; for (Class<?> c : validCasts) { Object unwrapped = query.unwrap(c); assertTrue(c.isInstance(unwrapped)); } em.close(); } /** * Tests a EntityManager can be unwrapped as an instance of a series of * class or interface. */ public void testValidEntityManagerUnwrap() { EntityManager em = emf.createEntityManager(); Class<?>[] validCasts = new Class[] { org.apache.openjpa.persistence.OpenJPAEntityManager.class, org.apache.openjpa.persistence.OpenJPAEntityManagerSPI.class, org.apache.openjpa.kernel.DelegatingBroker.class, org.apache.openjpa.kernel.Broker.class }; for (Class<?> c : validCasts) { Object unwrapped = em.unwrap(c); assertTrue(c.isInstance(unwrapped)); } em.close(); } /** * Tests a EntityManager can be unwrapped as an instance of a series of * class or interface. */ public void testValidOtherUnwrap() { EntityManager em = emf.createEntityManager(); Class<?>[] validCasts = new Class[] { java.sql.Connection.class }; for (Class<?> c : validCasts) { Object unwrapped = em.unwrap(c); assertTrue(c.isInstance(unwrapped)); } em.close(); } public void testConnectionUnwrap() throws Exception { String dbDict = ((JDBCConfiguration) emf.getConfiguration()).getDBDictionaryInstance().getClass().getName(); EntityManager em = emf.createEntityManager(); OpenJPAEntityManager oem = em.unwrap(OpenJPAEntityManager.class); try { Connection c = (Connection) oem.getConnection(); assertNotNull(c); assertTrue(DelegatingConnection.class.isAssignableFrom(c.getClass())); List<Class> acceptedConnectionClassTypes = new ArrayList<Class>(); if (DerbyDictionary.class.getName().equals(dbDict)) { // Connection type can be network or embedded String[] connectionTypes = { "org.apache.derby.impl.jdbc.EmbedConnection40", "org.apache.derby.impl.jdbc.EmbedConnection30", "org.apache.derby.iapi.jdbc.BrokeredConnection40", "org.apache.derby.iapi.jdbc.BrokeredConnection30" }; for (String ct : connectionTypes) { try { Class cls = Class.forName(ct); acceptedConnectionClassTypes.add(cls); } catch (ClassNotFoundException cnfe) { // Swallow } } } if (!acceptedConnectionClassTypes.isEmpty()) { boolean pass = false; for (Class cls : acceptedConnectionClassTypes) { try { Connection castC = (Connection) c.unwrap(cls); assertNotNull(castC); assertEquals(cls, castC.getClass()); pass = true; break; } catch (Throwable t) { // Swallow } assertTrue(pass); } } } finally { em.close(); } } public void testNegativeConnectionUnwrap() { EntityManager em = emf.createEntityManager(); OpenJPAEntityManager oem = em.unwrap(OpenJPAEntityManager.class); try { Connection c = (Connection) oem.getConnection(); assertNotNull(c); assertTrue(DelegatingConnection.class.isAssignableFrom(c.getClass())); // Make a completely bogus unwrap() attempt try { c.unwrap(TestUnwrap.class); fail("Bogus unwrap should have thrown a SQLException."); } catch (java.sql.SQLException se) { // Expected } } finally { em.close(); } } /** * Tests a EntityManager can not be unwrapped as Object class, null or an interface. * And each such failure raises a Persistence Exception and causes an active transaction * to rollback. */ public void testInvalidEntityManagerUnwrap() { EntityManager em = emf.createEntityManager(); Class<?>[] invalidCasts = new Class[] { Object.class, Properties.class, Map.class, null, }; for (Class<?> c : invalidCasts) { try { em.getTransaction().begin(); em.unwrap(c); fail("Expected to fail to unwarp with invalid " + c); } catch (PersistenceException e) { EntityTransaction txn = em.getTransaction(); assertTrue(txn.getRollbackOnly()); txn.rollback(); } } em.close(); } /** * Tests a Query can not be unwrapped as Object class, null or an interface. * And each such failure raises a Persistence Exception and causes an active transaction * to rollback. */ public void testInvalidQueryUnwrap() { OpenJPAEntityManager em = emf.createEntityManager(); Class<?>[] invalidCasts = new Class[] { Object.class, Properties.class, Map.class, null, }; for (Class<?> c : invalidCasts) { try { em.getTransaction().begin(); Query query = em.createQuery(QueryLanguages.LANG_SQL,""); query.unwrap(c); fail("Expected to fail to unwarp with invalid " + c); } catch (PersistenceException e) { EntityTransaction txn = em.getTransaction(); assertTrue(txn.getRollbackOnly()); txn.rollback(); } } em.close(); } }