Source Code Cross Referenced for Ammentos.java in  » Database-ORM » Ammentos » it » biobytes » ammentos » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » Ammentos » it.biobytes.ammentos 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *   Copyright 2006 Davide Deidda
003:         *
004:         *  Licensed under the Apache License, Version 2.0 (the "License");
005:         *  you may not use this file except in compliance with the License.
006:         *  You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         *  Unless required by applicable law or agreed to in writing, software
011:         *  distributed under the License is distributed on an "AS IS" BASIS,
012:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         *  See the License for the specific language governing permissions and
014:         *  limitations under the License.
015:         */
016:
017:        /*
018:         * Ammentos.java
019:         *
020:         * Created on 8 aprile 2005, 19.35
021:         */
022:
023:        package it.biobytes.ammentos;
024:
025:        import it.biobytes.ammentos.util.*;
026:        import it.biobytes.ammentos.query.*;
027:        import it.biobytes.ammentos.validation.*;
028:        import it.biobytes.ammentos.cache.*;
029:        import it.biobytes.ammentos.event.*;
030:        import java.util.*;
031:        import java.util.logging.*;
032:        import javax.sql.*;
033:        import java.sql.*;
034:
035:        /**
036:         * This class represents the persistence framework itself.
037:         * Provides all methods for managing objects persistence: save, load, lookup
038:         * by primary key and delete operations. These operations can be atomic or can be
039:         * performed into a transaction by using the transaction related methods such as
040:         * openTransaction(), commitTransaction() and rollbackTransaction().
041:         * An internal caching mechanism dramatically optimizes direct lookup() calls.
042:         * Furthermore is possible to receive persistence events by registering
043:         * PersistenceListeners objects to the Framework.
044:         * @author Davide Deidda
045:         */
046:        public class Ammentos {
047:
048:            private static MetadataInspector m_metadataInspector = new MetadataInspector();
049:            private static Map<Class, Metadata> m_metadatas = new HashMap<Class, Metadata>();
050:            private static ThreadLocal<PersistenceContext> m_context = new ThreadLocal<PersistenceContext>();
051:
052:            private static EventDispatcher m_eventDispatcher = new EventDispatcher();
053:
054:            private static final FrameworkState STATE_NORMAL = new NormalState();
055:            private static final FrameworkState STATE_TRANSACTION = new TransactionState();
056:
057:            private static PersistenceContext m_defaultContext = new PersistenceContext(
058:                    null);
059:            private static Logger m_logger = Logger.getLogger("ammentos");
060:            static {
061:                Thread t = new Thread(m_eventDispatcher);
062:                t.setDaemon(true);
063:                t.start();
064:
065:                m_defaultContext.setState(STATE_NORMAL);
066:                m_logger.setLevel(Level.OFF);
067:            }
068:
069:            private static class NormalState extends FrameworkState {
070:
071:                public <T> void doSave(Class<T> c, T obj)
072:                        throws PersistenceException {
073:                    getPersistor(c).save(c, obj);
074:                    m_eventDispatcher.dispatchEvent(new PersistenceEvent(obj,
075:                            EventType.OBJECT_SAVED));
076:                    currentContext().getCache().remove(obj);
077:                }
078:
079:                public <T> void doDelete(Class<T> c, T obj)
080:                        throws PersistenceException {
081:                    getPersistor(c).delete(c, obj);
082:                    m_eventDispatcher.dispatchEvent(new PersistenceEvent(obj,
083:                            EventType.OBJECT_DELETED));
084:                    currentContext().getCache().remove(obj);
085:                }
086:
087:                public <T> boolean doLoad(Class<T> c, T obj, Object primaryKey)
088:                        throws PersistenceException {
089:                    return getPersistor(c).load(c, obj, primaryKey);
090:                }
091:
092:                public <T> List<T> doLoad(Class<T> c, Query qry)
093:                        throws PersistenceException {
094:                    List<T> res = new ArrayList<T>();
095:                    EntityIterable<T> items = null;
096:
097:                    try {
098:                        items = loadIterable(c, qry);
099:                        for (T item : items) {
100:                            res.add(item);
101:                        }
102:                    } finally {
103:                        items.close();
104:                    }
105:
106:                    return res;
107:                }
108:
109:                public <T> EntityIterable<T> loadIterable(Class<T> c, Query qry)
110:                        throws PersistenceException {
111:                    return getPersistor(c).loadIterable(c, qry);
112:                }
113:
114:                @Override
115:                public <T> int count(Class<T> c, Query qry)
116:                        throws PersistenceException {
117:                    return getPersistor(c).count(c, qry);
118:                }
119:            }
120:
121:            private static class TransactionState extends FrameworkState {
122:
123:                public <T> void doSave(Class<T> c, T obj)
124:                        throws PersistenceException {
125:                    getPersistor(c).save(c, obj, currentTransaction());
126:                    currentTransaction().involveSavedObject(obj);
127:                }
128:
129:                public <T> void doDelete(Class<T> c, T obj)
130:                        throws PersistenceException {
131:                    getPersistor(c).delete(c, obj, currentTransaction());
132:                    currentTransaction().involveDeletedObject(obj);
133:                }
134:
135:                public <T> boolean doLoad(Class<T> c, T obj, Object primaryKey)
136:                        throws PersistenceException {
137:                    return getPersistor(c).load(c, obj, primaryKey,
138:                            currentTransaction());
139:                }
140:
141:                public <T> List<T> doLoad(Class<T> c, Query qry)
142:                        throws PersistenceException {
143:                    List<T> res = new ArrayList<T>();
144:                    EntityIterable<T> items = null;
145:
146:                    try {
147:                        items = loadIterable(c, qry);
148:                        for (T item : items) {
149:                            res.add(item);
150:                        }
151:                    } finally {
152:                        items.close();
153:                    }
154:                    return res;
155:                }
156:
157:                public <T> EntityIterable<T> loadIterable(Class<T> c, Query qry)
158:                        throws PersistenceException {
159:                    return getPersistor(c).loadIterable(c, qry,
160:                            currentTransaction());
161:                }
162:
163:                @Override
164:                public <T> int count(Class<T> c, Query qry)
165:                        throws PersistenceException {
166:                    return getPersistor(c).count(c, qry, currentTransaction());
167:                }
168:            }
169:
170:            private static FrameworkState getState() {
171:                FrameworkState res = currentContext().getState();
172:                if (res == null) {
173:                    res = STATE_NORMAL;
174:                    currentContext().setState(res);
175:                }
176:                return res;
177:            }
178:
179:            /**
180:             * Returns the metadata for the objects that belong to the provided class.
181:             * @param c The class to get metadata for
182:             * @throws it.biobytes.ammentos.PersistenceException If the provided class does not contain valid metadata
183:             * information
184:             * @return The metadata for the provided class
185:             */
186:            public static Metadata getMetadata(Class c)
187:                    throws PersistenceException {
188:                if (c == null) {
189:                    throw new PersistenceException("Invalid class: null");
190:                }
191:
192:                Metadata res = m_metadatas.get(c);
193:
194:                // If metadata are not present in cache
195:                if (res == null) {
196:                    // Try loading with inspector
197:                    try {
198:                        res = m_metadataInspector.loadMetadata(c);
199:                    } catch (PersistenceException e) {
200:                        try {
201:                            // If the class is subclass of an entity type tries loading
202:                            // the same metadata
203:                            if (c.getAnnotation(PersistentEntity.class) == null) {
204:                                // Try with superclass
205:                                Class super Class = c.getSuperclass();
206:                                res = getMetadata(super Class);
207:                            } else {
208:                                throw e;
209:                            }
210:                        } catch (Exception ex) {
211:                            e.fillInStackTrace();
212:                            throw e;
213:                        }
214:                    }
215:                    m_metadatas.put(c, res);
216:                }
217:                return res;
218:            }
219:
220:            private static Persistor getPersistor(Class c)
221:                    throws PersistenceException {
222:                return getMetadata(c).getPersistor();
223:            }
224:
225:            /**
226:             * Creates a new instance of the provided object.
227:             * @param c The class of the object to create
228:             * @throws it.biobytes.ammentos.PersistenceException If any errors occurred while trying to create the instance
229:             * @return An instance of the provided class
230:             */
231:            public static <T> T createInstance(Class<T> c)
232:                    throws PersistenceException {
233:                T res;
234:                try {
235:                    // Getting default constructor
236:                    java.lang.reflect.Constructor<T> constr = c
237:                            .getDeclaredConstructor();
238:                    if (constr == null) {
239:                        throw new PersistenceException(
240:                                "Default constructor not found for class " + c);
241:                    }
242:                    if (!constr.isAccessible()) {
243:                        constr.setAccessible(true);
244:                    }
245:                    res = constr.newInstance();
246:                    m_logger.info("created instance: " + res + " for class: "
247:                            + c);
248:                } catch (PersistenceException e) {
249:                    throw e;
250:                } catch (Exception e) {
251:                    throw new PersistenceException(e);
252:                }
253:                return res;
254:            }
255:
256:            /**
257:             * Saves the provided object instance. If a transaction is opened this operation
258:             * will be actually performed when the commitTransaction() method will be called
259:             * @param obj The object to save
260:             * @throws it.biobytes.ammentos.PersistenceException If any errors occurr while saving the object
261:             */
262:            public static <T> void save(T obj) throws PersistenceException {
263:                // getState().save( ( Class<T> )obj.getClass(), obj );
264:                saveDeeply((Class<T>) obj.getClass(), obj);
265:            }
266:
267:            /**
268:             * Saves the provided object instance, regardless the object is already present
269:             * into the target domain. If the object is already present the call corresponds to
270:             * a normale save() method, otherwise a delete() method followed by a new save() method
271:             * is called.
272:             *
273:             * @param obj The object to override
274:             * @throws it.biobytes.ammentos.PersistenceException If any errors occurr while saving the object
275:             */
276:            public static <T> void override(T obj) throws PersistenceException {
277:                try {
278:                    save(obj);
279:                } catch (PersistenceException e) {
280:                    delete(obj);
281:                    save(obj);
282:                }
283:            }
284:
285:            /**
286:             * Deletes the object. If a transaction is opened this operation will be actually
287:             * performed when the commitTransaction() method will be called
288:             * @param obj The object to delete
289:             * @throws it.biobytes.ammentos.PersistenceException
290:             */
291:            public static <T> void delete(T obj) throws PersistenceException {
292:                //getState().delete( ( Class<T> )obj.getClass(), obj );
293:                deleteDeeply((Class<T>) obj.getClass(), obj);
294:            }
295:
296:            /**
297:             * Deletes all the objects of class c matching the provided QueryFilter.
298:             * If a transaction is opened this operation will be actually
299:             * performed when the commitTransaction() method will be called
300:             */
301:            public static <T> void delete(Class<T> c, QueryFilter filter)
302:                    throws PersistenceException {
303:                Query qry = new Query(filter);
304:                qry.setMaxResults(50);
305:                List<T> objs = load(c, qry);
306:
307:                while (objs.size() > 0) {
308:                    for (T obj : objs) {
309:                        delete(obj);
310:                    }
311:                    objs = load(c, qry);
312:                }
313:            }
314:
315:            /**
316:             * Loads the object whith the provided primary key
317:             * @param c
318:             * @param primaryKey
319:             * @throws it.biobytes.ammentos.PersistenceException
320:             * @return
321:             */
322:            public static <T> T load(Class<T> c, Object primaryKey)
323:                    throws PersistenceException {
324:                T res = createInstance(c);
325:                if (!loadDeeply(c, res, primaryKey)) {
326:                    res = null;
327:                }
328:                return res;
329:            }
330:
331:            /**
332:             * This method represents a shortcut for loading objects with queries when the
333:             * expected return value is only one object. A persistenceException will 
334:             * be thrown if the query returns more than one value.
335:             * 
336:             * @param c
337:             * @param query
338:             * @return
339:             * @throws it.biobytes.ammentos.PersistenceException
340:             */
341:            public static <T> T loadUnique(Class<T> c, Query query)
342:                    throws PersistenceException {
343:                T res = null;
344:                List<T> objs = load(c, query);
345:                if (objs.size() > 1) {
346:                    throw new PersistenceException(
347:                            "Not unique result for provided query");
348:                } else if (objs.size() > 0) {
349:                    res = objs.get(0);
350:                }
351:                return res;
352:            }
353:
354:            /**
355:             * This method represents a shortcut for loading objects with queries when the
356:             * expected return value is only one object. A persistenceException will 
357:             * be thrown if the query returns more than one value.
358:             * 
359:             * @param c
360:             * @param query
361:             * @return
362:             * @throws it.biobytes.ammentos.PersistenceException
363:             */
364:            public static <T> T loadUnique(Class<T> c, QueryFilter filter)
365:                    throws PersistenceException {
366:                return loadUnique(c, new Query(filter));
367:            }
368:
369:            /**
370:             * Loads the object with the provided composite primary key. Values must be
371:             * passed in the same order as in PersistentEntity declaration.
372:             *
373:             *
374:             */
375:            public static <T> T load(Class<T> c, Object... primaryKeys)
376:                    throws PersistenceException {
377:                T res = null;
378:                try {
379:                    Field[] keys = getMetadata(c).getPrimaryKeyFields();
380:                    if (keys.length != primaryKeys.length) {
381:                        throw new Exception();
382:                    }
383:                    Query qry = new Query();
384:
385:                    for (int i = 0; i < primaryKeys.length; i++) {
386:                        SimpleQueryFilter filter = new SimpleQueryFilter(
387:                                keys[i].getName());
388:                        filter.setObject(primaryKeys[i], keys[i].getType());
389:                        qry.appendFilter(filter);
390:                    }
391:
392:                    List<T> objs = load(c, qry);
393:                    if (objs != null && objs.size() > 0) {
394:                        res = objs.get(0);
395:                    }
396:                } catch (PersistenceException ex) {
397:                    throw ex;
398:                } catch (Exception ex) {
399:                    throw new PersistenceException(
400:                            "Invalid composite primary key. Please check number and types of parameters");
401:                }
402:                return res;
403:            }
404:
405:            /**
406:             * Loads the objects which match the provided query. The returned list is
407:             * unmodifiabale.
408:             * @param c
409:             * @param qry
410:             * @throws it.biobytes.ammentos.PersistenceException
411:             * @return
412:             */
413:            public static <T> List<T> load(Class<T> c, Query qry)
414:                    throws PersistenceException {
415:                //return Collections.unmodifiableList(doLoad(c, qry));
416:                return doLoad(c, qry);
417:            }
418:
419:            /**
420:             * Loads the objects which match the provided query. 
421:             * 
422:             * @param c
423:             * @param filter
424:             * @throws it.biobytes.ammentos.PersistenceException
425:             * @return
426:             */
427:            public static <T> List<T> load(Class<T> c, QueryFilter filter)
428:                    throws PersistenceException {
429:                //return Collections.unmodifiableList(doLoad(c, new Query(filter)));
430:                return doLoad(c, new Query(filter));
431:            }
432:
433:            /**
434:             * Counts the objects which match the provided query.
435:             * 
436:             * @param c
437:             * @param qry
438:             * @return
439:             * @throws it.biobytes.ammentos.PersistenceException
440:             */
441:            public static <T> int count(Class<T> c, Query qry)
442:                    throws PersistenceException {
443:                return getState().count(c, qry);
444:            }
445:
446:            /**
447:             * Counts the objects which match the provided queryfilter.
448:             * 
449:             * @param c
450:             * @param filter
451:             * @return
452:             * @throws it.biobytes.ammentos.PersistenceException
453:             */
454:            public static <T> int count(Class<T> c, QueryFilter filter)
455:                    throws PersistenceException {
456:                return getState().count(c, new Query(filter));
457:            }
458:
459:            /**
460:             * Returns an updatable list of objects which match the provided query. By
461:             * calling add() and remove() method on this list the objects will be
462:             * respectively saved or removed from their persistor.
463:             */
464:            public static <T> List<T> loadUpdatable(Class<T> c, Query qry)
465:                    throws PersistenceException {
466:                return new UpdatableList(doLoad(c, qry));
467:            }
468:
469:            public static <T> Iterable<T> iterate(Class<T> c, Query qry)
470:                    throws PersistenceException {
471:                if (currentContext().getIterable() != null) {
472:                    throw new PersistenceException(
473:                            "Iterable already opened in current context, Please call closeIteration() first.");
474:                }
475:                EntityIterable<T> res = getState().loadIterable(c, qry);
476:                currentContext().setIterable(res);
477:                return res;
478:            }
479:
480:            public static void closeIteration() {
481:                EntityIterable eit = currentContext().getIterable();
482:                if (eit != null) {
483:                    eit.close();
484:                    currentContext().setIterable(null);
485:                }
486:            }
487:
488:            /**
489:             * Performs the load operation for the provided query, returning a normal
490:             * list
491:             */
492:            private static <T> List<T> doLoad(Class<T> c, Query qry)
493:                    throws PersistenceException {
494:                // First loading objects as "c" items
495:                List<T> res = getState().load(c, qry);
496:                return res;
497:            }
498:
499:            /**
500:             * Gets the primary key field for the objects of the provided class
501:             * @param c
502:             * @throws it.biobytes.ammentos.PersistenceException
503:             * @return
504:             */
505:            public static Field getPrimaryKeyField(Class c)
506:                    throws PersistenceException {
507:                return getMetadata(c).getPrimaryKeyField();
508:            }
509:
510:            private static Field getSuperKeyField(Class c)
511:                    throws PersistenceException {
512:                return getMetadata(c).getSuperKeyField();
513:            }
514:
515:            /**
516:             * Lookup the object of the provided class whith the specified primary key.
517:             * This methods uses an internal caching mechanism which dramatically increases
518:             * the performance, so use this method instead of load(Class,String) whenever
519:             * is possible to obtain the best performance in retrieving objects.
520:             * @param c
521:             * @param primaryKey
522:             * @throws it.biobytes.ammentos.PersistenceException
523:             * @return
524:             */
525:            public static <T> T lookup(Class<T> c, Object primaryKey)
526:                    throws PersistenceException {
527:                T res = null;
528:
529:                res = currentContext().getCache().lookup(c, primaryKey);
530:                if (res == null) {
531:                    res = load(c, primaryKey);
532:                    if (res != null) {
533:                        currentContext().getCache().store(res);
534:                    }
535:                }
536:
537:                return res;
538:            }
539:
540:            /**
541:             * Sets the default datasource for this framework
542:             * @param source
543:             */
544:            public static void setDataSource(DataSource source) {
545:                m_defaultContext.setDataSource(source);
546:            }
547:
548:            /**
549:             * Returns the default datasource for this framework
550:             * 
551:             * @return The default datasource
552:             */
553:            public static DataSource getDataSource() {
554:                return m_defaultContext.getDataSource();
555:            }
556:
557:            /**
558:             * Opens a transaction to the datatabse. Each next call to save() method in
559:             * the same thread will save objects into this transaction, until one between
560:             * commitTransaction() or rollbackTransaction() is called.
561:             *
562:             * The isolation level for the created transaction is TRANSACTION_READ_UNCOMMITTED,
563:             * what means that dirty reads are allowed.
564:             */
565:            public static void openTransaction() throws PersistenceException {
566:                openTransaction(Connection.TRANSACTION_READ_UNCOMMITTED);
567:            }
568:
569:            /**
570:             * Opens a transaction to the datatabse. Each next call to save() method in
571:             * the same thread will save objects into this transaction, until one between
572:             * commitTransaction() or rollbackTransaction() is called.
573:             *
574:             * The isolation level for the created transaction must be one between the
575:             * constants defined for java.sql.Connection.
576:             */
577:            public static void openTransaction(int isolationLevel)
578:                    throws PersistenceException {
579:                currentContext().setTransaction(
580:                        new Transaction(isolationLevel, currentContext()));
581:                currentContext().setState(STATE_TRANSACTION);
582:            }
583:
584:            /**
585:             * Rolls back the current transaction. The cache of the objects involved in
586:             * the transaction will not be removed.
587:             */
588:            public static void rollbackTransaction()
589:                    throws PersistenceException {
590:                try {
591:                    currentTransaction().rollback();
592:                } catch (Exception e) {
593:                    throw new PersistenceException(e);
594:                }
595:
596:                currentContext().setTransaction(null);
597:                currentContext().setState(STATE_NORMAL);
598:            }
599:
600:            /**
601:             * Commits the current transaction. If the commit ends successfully all the
602:             * objects involved in the transaction are removed from the cache.
603:             */
604:            public static void commitTransaction() throws PersistenceException {
605:                try {
606:                    currentTransaction().commit();
607:                    for (Object obj : currentTransaction().savedObjects()) {
608:                        m_eventDispatcher.dispatchEvent(new PersistenceEvent(
609:                                obj, EventType.OBJECT_SAVED));
610:                        currentContext().getCache().remove(obj);
611:                    }
612:
613:                    for (Object obj : currentTransaction().deletedObjects()) {
614:                        m_eventDispatcher.dispatchEvent(new PersistenceEvent(
615:                                obj, EventType.OBJECT_DELETED));
616:                        currentContext().getCache().remove(obj);
617:                    }
618:                } catch (Exception e) {
619:                    throw new PersistenceException(e);
620:                }
621:
622:                currentContext().setTransaction(null);
623:                currentContext().setState(STATE_NORMAL);
624:            }
625:
626:            /**
627:             * Returns a connection to the underlying database. The connection will belong
628:             * to the currently used persistence context
629:             *
630:             * @throws it.biobytes.ammentos.PersistenceException
631:             * @return
632:             */
633:            public static Connection getDbConnection()
634:                    throws PersistenceException {
635:                Connection res = null;
636:                try {
637:                    if (m_context.get() == null) {
638:                        res = m_defaultContext.getDataSource().getConnection();
639:                    } else {
640:                        res = m_context.get().getDataSource().getConnection();
641:                    }
642:                    m_logger.info("Returning connection: " + res);
643:                } catch (SQLException e) {
644:                    throw new PersistenceException(e);
645:                }
646:                return res;
647:            }
648:
649:            /**
650:             * Validates the provided Object using its related validator
651:             * @param obj
652:             * @throws it.biobytes.ammentos.PersistenceException
653:             * @return
654:             */
655:            public static <T> void validate(Class<T> c, T obj)
656:                    throws PersistenceException {
657:                Validator validator = getMetadata(c).getValidator();
658:                ValidationReport report = null;
659:                if (validator != null) {
660:                    report = validator.validate(obj);
661:                }
662:
663:                if ((report != null) && !report.isEmpty()) {
664:                    throw new PersistenceException(report.getErrors()[0]);
665:                }
666:            }
667:
668:            /**
669:             * Returns a "diff" report for the provided objects
670:             */
671:            public static <T> List<Field> diff(T obj1, T obj2)
672:                    throws PersistenceException {
673:                List<Field> res = new ArrayList<Field>();
674:                diffDeeply(res, (Class<T>) obj1.getClass(), obj1, obj2);
675:                return res;
676:            }
677:
678:            /**
679:             * Similarly to java.lang.String.intern() method, returns the internal, cached
680:             * version of the provided object, if present; otherwise returns the same
681:             * object and puts the provided one into the cache.
682:             */
683:            public static <T> T intern(T obj) throws PersistenceException {
684:                T res = obj;
685:                if (obj != null) {
686:                    Class<T> c = (Class<T>) obj.getClass();
687:                    Object pKey = getPrimaryKeyField(c).get(obj);
688:                    T cachedObj = currentContext().getCache().lookup(c, pKey);
689:                    if (cachedObj != null) {
690:                        res = cachedObj;
691:                    } else {
692:                        currentContext().getCache().store(obj);
693:                    }
694:                }
695:                return res;
696:            }
697:
698:            /**
699:             * Adds a PersistenceListener to the framework.
700:             * @param listener
701:             */
702:            public static void addPersistenceListener(
703:                    PersistenceListener listener) {
704:                m_eventDispatcher.addPersistenceListener(listener);
705:            }
706:
707:            public static void removePersistenceListener(
708:                    PersistenceListener listener) {
709:                m_eventDispatcher.removePersistenceListener(listener);
710:            }
711:
712:            private static <T> void saveDeeply(Class<T> c, T obj)
713:                    throws PersistenceException {
714:                Class[] parents = getInheritancePath(c);
715:                // Superclasses are saved in top down way
716:                for (int i = parents.length - 1; i >= 0; i--) {
717:                    Class currentClass = parents[i];
718:                    validate(currentClass, obj);
719:                    getState().save(currentClass, obj);
720:                }
721:            }
722:
723:            private static <T> void deleteDeeply(Class<T> c, T obj)
724:                    throws PersistenceException {
725:                Class[] parents = getInheritancePath(c);
726:                // Superclasses are deleted in down top way
727:                for (int i = 0; i < parents.length; i++) {
728:                    Class currentClass = parents[i];
729:                    getState().delete(currentClass, obj);
730:                }
731:            }
732:
733:            protected static <T> boolean loadDeeply(Class<T> c, T obj,
734:                    Object primaryKey) throws PersistenceException {
735:                boolean res = true;
736:                Class[] parents = getInheritancePath(c);
737:
738:                // Superclasses are loaded in down top way
739:                Object key = primaryKey;
740:                for (int i = 0; i < parents.length; i++) {
741:                    Class currentClass = parents[i];
742:                    res = getState().load(currentClass, obj, key);
743:                    key = getSuperKeyField(currentClass).get(obj);
744:                    if (!res) {
745:                        break;
746:                    }
747:                }
748:
749:                return res;
750:            }
751:
752:            private static <T> void diffDeeply(List<Field> res, Class<T> c,
753:                    T obj1, T obj2) throws PersistenceException {
754:                Class[] parents = getInheritancePath(c);
755:                for (Class currentClass : parents) {
756:                    res.addAll(Diff.diff(currentClass, obj1, obj2));
757:                }
758:            }
759:
760:            /**
761:             * Returns the inheritance path of an object, no matter if the object's
762:             * declaring class is persistence or not. This allows non-persistent objects
763:             * to be persisted even if they are just subclasses of persistent classes.
764:             */
765:            private static Class[] getInheritancePath(Class c)
766:                    throws PersistenceException {
767:                return getMetadata(c).inheritancePath();
768:            }
769:
770:            protected static void openContext(PersistenceContext context)
771:                    throws PersistenceException {
772:                if (m_context.get() != null) {
773:                    throw new PersistenceException(
774:                            "Context already set in the current thread. Please close current context before calling this method");
775:                }
776:                m_context.set(context);
777:            }
778:
779:            protected static void closeContext() {
780:                m_context.set(null);
781:            }
782:
783:            public static PersistenceContext createContext(DataSource source) {
784:                return new PersistenceContext(source);
785:            }
786:
787:            public static PersistenceContext currentContext() {
788:                PersistenceContext res = null;
789:                res = m_context.get();
790:                if (res == null) {
791:                    res = m_defaultContext;
792:                }
793:                return res;
794:            }
795:
796:            public static Transaction currentTransaction() {
797:                return currentContext().getTransaction();
798:            }
799:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.