/*
* 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.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.apache.openjpa.kernel.Broker;
import org.apache.openjpa.kernel.BrokerFactory;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.util.BigDecimalId;
import org.apache.openjpa.util.BigIntegerId;
import org.apache.openjpa.util.ByteId;
import org.apache.openjpa.util.CharId;
import org.apache.openjpa.util.DoubleId;
import org.apache.openjpa.util.FloatId;
import org.apache.openjpa.util.Id;
import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.IntId;
import org.apache.openjpa.util.LongId;
import org.apache.openjpa.util.ObjectId;
import org.apache.openjpa.util.OpenJPAId;
import org.apache.openjpa.util.ShortId;
import org.apache.openjpa.util.StringId;
import org.apache.openjpa.lib.util.Localizer;
/**
* Helper class for switching between OpenJPA's JPA facade and the underlying
* Broker kernel.
*
* @since 1.0.0
* @nojavadoc
*/
public class JPAFacadeHelper {
public static final String EM_KEY =
"org.apache.openjpa.persistence.EntityManager";
public static final String EMF_KEY =
"org.apache.openjpa.persistence.EntityManagerFactory";
private static final Localizer _loc =
Localizer.forPackage(JPAFacadeHelper.class);
public static OpenJPAEntityManagerFactory toEntityManagerFactory(
BrokerFactory factory) {
if (factory == null)
return null;
factory.lock();
try {
OpenJPAEntityManagerFactory emf = (OpenJPAEntityManagerFactory)
factory.getUserObject(EMF_KEY);
if (emf == null) {
emf = EntityManagerFactoryValue.newFactory(factory);
factory.putUserObject(EMF_KEY, emf);
}
return emf;
} catch (Exception e) {
throw PersistenceExceptions.toPersistenceException(e);
} finally {
factory.unlock();
}
}
/**
* Return the underlying broker factory for the given persistence manager
* factory facade.
*/
public static BrokerFactory toBrokerFactory(EntityManagerFactory emf) {
if (emf == null)
return null;
if (!(emf instanceof EntityManagerFactoryImpl)) {
Class c = emf.getClass();
try {
// either cast here may fail
emf = (EntityManagerFactoryImpl) ((OpenJPAEntityManagerFactory)
emf).getUserObject(EMF_KEY);
} catch (ClassCastException cce) {
throw new ArgumentException(_loc.get(
"cant-convert-brokerfactory", c), null, null, false);
}
}
return ((EntityManagerFactoryImpl) emf).getBrokerFactory();
}
/**
* Return a persistence manager facade to the given broker retaining
* previously associated persistence context type.
*/
public static OpenJPAEntityManager toEntityManager(Broker broker) {
if (broker == null)
return null;
broker.lock();
try {
OpenJPAEntityManager em = (OpenJPAEntityManager)
broker.getUserObject(EM_KEY);
if (em == null) {
EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl)
toEntityManagerFactory(broker.getBrokerFactory());
em = emf.newEntityManagerImpl(broker);
broker.putUserObject(EM_KEY, em);
}
return em;
} catch (Exception e) {
throw PersistenceExceptions.toPersistenceException(e);
} finally {
broker.unlock();
}
}
/**
* Return the underlying broker for the given entity manager facade.
*/
public static Broker toBroker(EntityManager em) {
if (em == null)
return null;
if (!(em instanceof EntityManagerImpl)) {
Class c = em.getClass();
try {
// either cast here may fail
em = (EntityManagerImpl) ((OpenJPAEntityManager) em).
getUserObject(EM_KEY);
} catch (ClassCastException cce) {
throw new ArgumentException(_loc.get("cant-convert-broker", c),
new Throwable[] { cce }, null, false);
}
}
return ((EntityManagerImpl) em).getBroker();
}
/**
* Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated with the
* persistent object <code>o</code>.
*/
public static ClassMetaData getMetaData(Object o) {
if (o == null)
return null;
EntityManager em = OpenJPAPersistence.getEntityManager(o);
return (em == null) ? null : getMetaData(em,
ImplHelper.getManagedInstance(o).getClass());
}
/**
* Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated
* with the persistent type <code>cls</code>.
*/
public static ClassMetaData getMetaData(EntityManager em, Class cls) {
if (em == null)
throw new NullPointerException("em == null");
OpenJPAEntityManagerSPI kem = (OpenJPAEntityManagerSPI)
OpenJPAPersistence.cast(em);
try {
return kem.getConfiguration().getMetaDataRepositoryInstance().
getMetaData(cls, kem.getClassLoader(), false);
} catch (Exception e) {
throw PersistenceExceptions.toPersistenceException(e);
}
}
/**
* Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated
* with the persistent type <code>cls</code>.
*/
public static ClassMetaData getMetaData(EntityManagerFactory emf,
Class cls) {
if (emf == null)
throw new NullPointerException("emf == null");
OpenJPAEntityManagerFactorySPI emfSPI =
(OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf);
try {
return emfSPI.getConfiguration().getMetaDataRepositoryInstance().
getMetaData(cls, null, false);
} catch (Exception e) {
throw PersistenceExceptions.toPersistenceException(e);
}
}
/**
* Translate from a OpenJPA identity object to a Persistence one.
*/
public static Object fromOpenJPAObjectId(Object oid) {
if (oid instanceof OpenJPAId)
return ((OpenJPAId) oid).getIdObject();
return oid;
}
/**
* Translate from a Persistence identity object to a OpenJPA one.
*/
public static Object toOpenJPAObjectId(ClassMetaData meta, Object oid) {
if (oid == null || meta == null)
return null;
Class cls = meta.getDescribedType();
if (meta.getIdentityType() == ClassMetaData.ID_DATASTORE)
return new Id(cls, ((Number) oid).longValue());
if (oid instanceof Byte)
return new ByteId(cls, (Byte) oid);
if (oid instanceof Character)
return new CharId(cls, (Character) oid);
if (oid instanceof Double)
return new DoubleId(cls, (Double) oid);
if (oid instanceof Float)
return new FloatId(cls, (Float) oid);
if (oid instanceof Integer)
return new IntId(cls, (Integer) oid);
if (oid instanceof Long)
return new LongId(cls, (Long) oid);
if (oid instanceof Short)
return new ShortId(cls, (Short) oid);
if (oid instanceof String)
return new StringId(cls, (String) oid);
if (oid instanceof BigDecimal)
return new BigDecimalId(cls, (BigDecimal) oid);
if (oid instanceof BigInteger)
return new BigIntegerId(cls, (BigInteger) oid);
return new ObjectId(cls, oid);
}
/**
* Return an array of OpenJPA oids for the given native oid array.
*/
public static Object[] toOpenJPAObjectIds(ClassMetaData meta,
Object... oids) {
if (oids == null || oids.length == 0)
return oids;
// since the class if fixed for all oids, we can tell if we have to
// translate the array based on whether the first oid needs translating
Object oid = toOpenJPAObjectId(meta, oids[0]);
if (oid == oids[0])
return oids;
Object[] copy = new Object[oids.length];
copy[0] = oid;
for (int i = 1; i < oids.length; i++)
copy[i] = toOpenJPAObjectId(meta, oids[i]);
return copy;
}
/**
* Return a collection of OpenJPA oids for the given native oid collection.
*/
public static Collection toOpenJPAObjectIds(ClassMetaData meta,
Collection oids) {
if (oids == null || oids.isEmpty())
return oids;
// since the class if fixed for all oids, we can tell if we have to
// translate the array based on whether the first oid needs translating
Iterator itr = oids.iterator();
Object orig = itr.next();
Object oid = toOpenJPAObjectId(meta, orig);
if (oid == orig)
return oids;
Collection copy = new ArrayList(oids.size());
copy.add(oid);
while (itr.hasNext())
copy.add(toOpenJPAObjectId(meta, itr.next()));
return copy;
}
/**
* Translate from a OpenJPA identity class to a native one.
*/
public static Class fromOpenJPAObjectIdClass(Class oidClass) {
if (oidClass == null)
return null;
if (oidClass == Id.class)
return Long.class;
if (oidClass == ByteId.class)
return Byte.class;
if (oidClass == CharId.class)
return Character.class;
if (oidClass == DoubleId.class)
return Double.class;
if (oidClass == FloatId.class)
return Float.class;
if (oidClass == IntId.class)
return Integer.class;
if (oidClass == LongId.class)
return Long.class;
if (oidClass == ShortId.class)
return Short.class;
if (oidClass == StringId.class)
return String.class;
if (oidClass == BigDecimalId.class)
return BigDecimal.class;
if (oidClass == BigIntegerId.class)
return BigInteger.class;
return oidClass;
}
}