001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.persistence;
020:
021: import java.math.BigDecimal;
022: import java.math.BigInteger;
023: import java.util.ArrayList;
024: import java.util.Collection;
025: import java.util.Iterator;
026: import javax.persistence.EntityManager;
027: import javax.persistence.EntityManagerFactory;
028:
029: import org.apache.openjpa.kernel.Broker;
030: import org.apache.openjpa.kernel.BrokerFactory;
031: import org.apache.openjpa.meta.ClassMetaData;
032: import org.apache.openjpa.util.BigDecimalId;
033: import org.apache.openjpa.util.BigIntegerId;
034: import org.apache.openjpa.util.ByteId;
035: import org.apache.openjpa.util.CharId;
036: import org.apache.openjpa.util.DoubleId;
037: import org.apache.openjpa.util.FloatId;
038: import org.apache.openjpa.util.Id;
039: import org.apache.openjpa.util.ImplHelper;
040: import org.apache.openjpa.util.IntId;
041: import org.apache.openjpa.util.LongId;
042: import org.apache.openjpa.util.ObjectId;
043: import org.apache.openjpa.util.OpenJPAId;
044: import org.apache.openjpa.util.ShortId;
045: import org.apache.openjpa.util.StringId;
046: import org.apache.openjpa.lib.util.Localizer;
047:
048: /**
049: * Helper class for switching between OpenJPA's JPA facade and the underlying
050: * Broker kernel.
051: *
052: * @since 1.0.0
053: * @nojavadoc
054: */
055: public class JPAFacadeHelper {
056:
057: public static final String EM_KEY = "org.apache.openjpa.persistence.EntityManager";
058: public static final String EMF_KEY = "org.apache.openjpa.persistence.EntityManagerFactory";
059:
060: private static final Localizer _loc = Localizer
061: .forPackage(JPAFacadeHelper.class);
062:
063: public static OpenJPAEntityManagerFactory toEntityManagerFactory(
064: BrokerFactory factory) {
065: if (factory == null)
066: return null;
067:
068: factory.lock();
069: try {
070: OpenJPAEntityManagerFactory emf = (OpenJPAEntityManagerFactory) factory
071: .getUserObject(EMF_KEY);
072: if (emf == null) {
073: emf = EntityManagerFactoryValue.newFactory(factory);
074: factory.putUserObject(EMF_KEY, emf);
075: }
076: return emf;
077: } catch (Exception e) {
078: throw PersistenceExceptions.toPersistenceException(e);
079: } finally {
080: factory.unlock();
081: }
082: }
083:
084: /**
085: * Return the underlying broker factory for the given persistence manager
086: * factory facade.
087: */
088: public static BrokerFactory toBrokerFactory(EntityManagerFactory emf) {
089: if (emf == null)
090: return null;
091: if (!(emf instanceof EntityManagerFactoryImpl)) {
092: Class c = emf.getClass();
093: try {
094: // either cast here may fail
095: emf = (EntityManagerFactoryImpl) ((OpenJPAEntityManagerFactory) emf)
096: .getUserObject(EMF_KEY);
097: } catch (ClassCastException cce) {
098: throw new ArgumentException(_loc.get(
099: "cant-convert-brokerfactory", c), null, null,
100: false);
101: }
102: }
103: return ((EntityManagerFactoryImpl) emf).getBrokerFactory();
104: }
105:
106: /**
107: * Return a persistence manager facade to the given broker retaining
108: * previously associated persistence context type.
109: */
110: public static OpenJPAEntityManager toEntityManager(Broker broker) {
111: if (broker == null)
112: return null;
113:
114: broker.lock();
115: try {
116: OpenJPAEntityManager em = (OpenJPAEntityManager) broker
117: .getUserObject(EM_KEY);
118: if (em == null) {
119: EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl) toEntityManagerFactory(broker
120: .getBrokerFactory());
121: em = emf.newEntityManagerImpl(broker);
122: broker.putUserObject(EM_KEY, em);
123: }
124: return em;
125: } catch (Exception e) {
126: throw PersistenceExceptions.toPersistenceException(e);
127: } finally {
128: broker.unlock();
129: }
130: }
131:
132: /**
133: * Return the underlying broker for the given entity manager facade.
134: */
135: public static Broker toBroker(EntityManager em) {
136: if (em == null)
137: return null;
138: if (!(em instanceof EntityManagerImpl)) {
139: Class c = em.getClass();
140: try {
141: // either cast here may fail
142: em = (EntityManagerImpl) ((OpenJPAEntityManager) em)
143: .getUserObject(EM_KEY);
144: } catch (ClassCastException cce) {
145: throw new ArgumentException(_loc.get(
146: "cant-convert-broker", c),
147: new Throwable[] { cce }, null, false);
148: }
149: }
150: return ((EntityManagerImpl) em).getBroker();
151: }
152:
153: /**
154: * Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated with the
155: * persistent object <code>o</code>.
156: */
157: public static ClassMetaData getMetaData(Object o) {
158: if (o == null)
159: return null;
160: EntityManager em = OpenJPAPersistence.getEntityManager(o);
161: return (em == null) ? null : getMetaData(em, ImplHelper
162: .getManagedInstance(o).getClass());
163: }
164:
165: /**
166: * Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated
167: * with the persistent type <code>cls</code>.
168: */
169: public static ClassMetaData getMetaData(EntityManager em, Class cls) {
170: if (em == null)
171: throw new NullPointerException("em == null");
172:
173: OpenJPAEntityManagerSPI kem = (OpenJPAEntityManagerSPI) OpenJPAPersistence
174: .cast(em);
175: try {
176: return kem.getConfiguration()
177: .getMetaDataRepositoryInstance().getMetaData(cls,
178: kem.getClassLoader(), false);
179: } catch (Exception e) {
180: throw PersistenceExceptions.toPersistenceException(e);
181: }
182: }
183:
184: /**
185: * Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated
186: * with the persistent type <code>cls</code>.
187: */
188: public static ClassMetaData getMetaData(EntityManagerFactory emf,
189: Class cls) {
190: if (emf == null)
191: throw new NullPointerException("emf == null");
192:
193: OpenJPAEntityManagerFactorySPI emfSPI = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence
194: .cast(emf);
195: try {
196: return emfSPI.getConfiguration()
197: .getMetaDataRepositoryInstance().getMetaData(cls,
198: null, false);
199: } catch (Exception e) {
200: throw PersistenceExceptions.toPersistenceException(e);
201: }
202: }
203:
204: /**
205: * Translate from a OpenJPA identity object to a Persistence one.
206: */
207: public static Object fromOpenJPAObjectId(Object oid) {
208: if (oid instanceof OpenJPAId)
209: return ((OpenJPAId) oid).getIdObject();
210: return oid;
211: }
212:
213: /**
214: * Translate from a Persistence identity object to a OpenJPA one.
215: */
216: public static Object toOpenJPAObjectId(ClassMetaData meta,
217: Object oid) {
218: if (oid == null || meta == null)
219: return null;
220:
221: Class cls = meta.getDescribedType();
222: if (meta.getIdentityType() == ClassMetaData.ID_DATASTORE)
223: return new Id(cls, ((Number) oid).longValue());
224:
225: if (oid instanceof Byte)
226: return new ByteId(cls, (Byte) oid);
227: if (oid instanceof Character)
228: return new CharId(cls, (Character) oid);
229: if (oid instanceof Double)
230: return new DoubleId(cls, (Double) oid);
231: if (oid instanceof Float)
232: return new FloatId(cls, (Float) oid);
233: if (oid instanceof Integer)
234: return new IntId(cls, (Integer) oid);
235: if (oid instanceof Long)
236: return new LongId(cls, (Long) oid);
237: if (oid instanceof Short)
238: return new ShortId(cls, (Short) oid);
239: if (oid instanceof String)
240: return new StringId(cls, (String) oid);
241: if (oid instanceof BigDecimal)
242: return new BigDecimalId(cls, (BigDecimal) oid);
243: if (oid instanceof BigInteger)
244: return new BigIntegerId(cls, (BigInteger) oid);
245: return new ObjectId(cls, oid);
246: }
247:
248: /**
249: * Return an array of OpenJPA oids for the given native oid array.
250: */
251: public static Object[] toOpenJPAObjectIds(ClassMetaData meta,
252: Object... oids) {
253: if (oids == null || oids.length == 0)
254: return oids;
255:
256: // since the class if fixed for all oids, we can tell if we have to
257: // translate the array based on whether the first oid needs translating
258: Object oid = toOpenJPAObjectId(meta, oids[0]);
259: if (oid == oids[0])
260: return oids;
261:
262: Object[] copy = new Object[oids.length];
263: copy[0] = oid;
264: for (int i = 1; i < oids.length; i++)
265: copy[i] = toOpenJPAObjectId(meta, oids[i]);
266: return copy;
267: }
268:
269: /**
270: * Return a collection of OpenJPA oids for the given native oid collection.
271: */
272: public static Collection toOpenJPAObjectIds(ClassMetaData meta,
273: Collection oids) {
274: if (oids == null || oids.isEmpty())
275: return oids;
276:
277: // since the class if fixed for all oids, we can tell if we have to
278: // translate the array based on whether the first oid needs translating
279: Iterator itr = oids.iterator();
280: Object orig = itr.next();
281: Object oid = toOpenJPAObjectId(meta, orig);
282: if (oid == orig)
283: return oids;
284:
285: Collection copy = new ArrayList(oids.size());
286: copy.add(oid);
287: while (itr.hasNext())
288: copy.add(toOpenJPAObjectId(meta, itr.next()));
289: return copy;
290: }
291:
292: /**
293: * Translate from a OpenJPA identity class to a native one.
294: */
295: public static Class fromOpenJPAObjectIdClass(Class oidClass) {
296: if (oidClass == null)
297: return null;
298: if (oidClass == Id.class)
299: return Long.class;
300: if (oidClass == ByteId.class)
301: return Byte.class;
302: if (oidClass == CharId.class)
303: return Character.class;
304: if (oidClass == DoubleId.class)
305: return Double.class;
306: if (oidClass == FloatId.class)
307: return Float.class;
308: if (oidClass == IntId.class)
309: return Integer.class;
310: if (oidClass == LongId.class)
311: return Long.class;
312: if (oidClass == ShortId.class)
313: return Short.class;
314: if (oidClass == StringId.class)
315: return String.class;
316: if (oidClass == BigDecimalId.class)
317: return BigDecimal.class;
318: if (oidClass == BigIntegerId.class)
319: return BigInteger.class;
320: return oidClass;
321: }
322: }
|