This project has retired. For details please refer to its
Attic page.
JdoAccess xref
1 package org.apache.maven.archiva.database.jdo;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.lang.StringUtils;
23 import org.apache.maven.archiva.database.ArchivaDatabaseException;
24 import org.apache.maven.archiva.database.Constraint;
25 import org.apache.maven.archiva.database.DeclarativeConstraint;
26 import org.apache.maven.archiva.database.ObjectNotFoundException;
27 import org.apache.maven.archiva.database.SimpleConstraint;
28 import org.apache.maven.archiva.database.constraints.AbstractSimpleConstraint;
29 import org.apache.maven.archiva.model.CompoundKey;
30 import org.codehaus.plexus.jdo.JdoFactory;
31 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
32 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
33
34 import java.io.PrintStream;
35 import java.util.ArrayList;
36 import java.util.List;
37 import javax.jdo.Extent;
38 import javax.jdo.JDOException;
39 import javax.jdo.JDOHelper;
40 import javax.jdo.JDOObjectNotFoundException;
41 import javax.jdo.JDOUserException;
42 import javax.jdo.PersistenceManager;
43 import javax.jdo.PersistenceManagerFactory;
44 import javax.jdo.Query;
45 import javax.jdo.Transaction;
46 import javax.jdo.datastore.DataStoreCache;
47 import javax.jdo.listener.InstanceLifecycleEvent;
48 import javax.jdo.listener.InstanceLifecycleListener;
49 import javax.jdo.listener.StoreLifecycleListener;
50 import javax.jdo.spi.Detachable;
51 import javax.jdo.spi.PersistenceCapable;
52
53
54
55
56
57
58
59 public class JdoAccess
60 implements Initializable, InstanceLifecycleListener, StoreLifecycleListener
61 {
62
63
64
65 private JdoFactory jdoFactory;
66
67 private PersistenceManagerFactory pmf;
68
69 public void initialize()
70 throws InitializationException
71 {
72 pmf = jdoFactory.getPersistenceManagerFactory();
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 pmf.addInstanceLifecycleListener( this, null );
107 }
108
109 public static void dumpObjectState( PrintStream out, Object o )
110 {
111 final String STATE = "[STATE] ";
112 final String INDENT = " ";
113
114 if ( o == null )
115 {
116 out.println( STATE + "Object is null." );
117 return;
118 }
119
120 out.println( STATE + "Object " + o.getClass().getName() );
121
122 if ( !( o instanceof PersistenceCapable ) )
123 {
124 out.println( INDENT + "is NOT PersistenceCapable (not a jdo object?)" );
125 return;
126 }
127
128 out.println( INDENT + "is PersistenceCapable." );
129 if ( o instanceof Detachable )
130 {
131 out.println( INDENT + "is Detachable" );
132 }
133
134 out.println( INDENT + "is new : " + Boolean.toString( JDOHelper.isNew( o ) ) );
135 out.println( INDENT + "is transactional : " + Boolean.toString( JDOHelper.isTransactional( o ) ) );
136 out.println( INDENT + "is deleted : " + Boolean.toString( JDOHelper.isDeleted( o ) ) );
137 out.println( INDENT + "is detached : " + Boolean.toString( JDOHelper.isDetached( o ) ) );
138 out.println( INDENT + "is dirty : " + Boolean.toString( JDOHelper.isDirty( o ) ) );
139 out.println( INDENT + "is persistent : " + Boolean.toString( JDOHelper.isPersistent( o ) ) );
140
141 out.println( INDENT + "object id : " + JDOHelper.getObjectId( o ) );
142 }
143
144 public PersistenceManager getPersistenceManager()
145 {
146 PersistenceManager pm = pmf.getPersistenceManager();
147
148 pm.getFetchPlan().setMaxFetchDepth( -1 );
149
150 return pm;
151 }
152
153 public void enableCache( Class<?> clazz )
154 {
155 DataStoreCache cache = pmf.getDataStoreCache();
156 cache.pinAll( clazz, false );
157 }
158
159 public Object saveObject( Object object )
160 {
161 return saveObject( object, null );
162 }
163
164 public Object saveObject( Object object, String[] fetchGroups )
165 {
166 PersistenceManager pm = getPersistenceManager();
167 Transaction tx = pm.currentTransaction();
168
169 try
170 {
171 tx.begin();
172
173 if ( ( JDOHelper.getObjectId( object ) != null ) && !JDOHelper.isDetached( object ) )
174 {
175
176
177 throw new JDOUserException( "Existing object is not detached: " + object, object );
178 }
179
180 if ( fetchGroups != null )
181 {
182 for ( int i = 0; i >= fetchGroups.length; i++ )
183 {
184 pm.getFetchPlan().addGroup( fetchGroups[i] );
185 }
186 }
187
188 pm.makePersistent( object );
189
190 object = pm.detachCopy( object );
191
192 tx.commit();
193
194 return object;
195 }
196 finally
197 {
198 rollbackIfActive( tx );
199 }
200 }
201
202 public List<?> getAllObjects( Class<?> clazz )
203 {
204 return queryObjects( clazz, null );
205 }
206
207 public List<?> queryObjects( Class<?> clazz, Constraint constraint )
208 {
209 PersistenceManager pm = getPersistenceManager();
210 Transaction tx = pm.currentTransaction();
211
212 List<?> result = null;
213
214 try
215 {
216 tx.begin();
217
218 if ( constraint != null )
219 {
220 if ( constraint instanceof DeclarativeConstraint )
221 {
222 result = processConstraint( pm, clazz, (DeclarativeConstraint) constraint );
223 }
224 else if ( constraint instanceof AbstractSimpleConstraint )
225 {
226 result = processConstraint( pm, (SimpleConstraint) constraint );
227 }
228 else
229 {
230 result = processUnconstrained( pm, clazz );
231 }
232 }
233 else
234 {
235 result = processUnconstrained( pm, clazz );
236 }
237
238 result = (List<?>) pm.detachCopyAll( result );
239
240 tx.commit();
241 }
242 finally
243 {
244 rollbackIfActive( tx );
245 }
246
247 return result;
248 }
249
250 public List<?> queryObjects( SimpleConstraint constraint )
251 {
252 PersistenceManager pm = getPersistenceManager();
253 Transaction tx = pm.currentTransaction();
254
255 try
256 {
257 tx.begin();
258
259 List<?> result = processConstraint( pm, constraint );
260
261
262 if ( constraint.isResultsPersistable() )
263 {
264 result = (List<?>) pm.detachCopyAll( result );
265 }
266 else
267 {
268 List<Object> copiedResults = new ArrayList<Object>();
269 copiedResults.addAll( result );
270 result = copiedResults;
271 }
272
273 tx.commit();
274
275 return result;
276 }
277 finally
278 {
279 rollbackIfActive( tx );
280 }
281 }
282
283 private List<?> processUnconstrained( PersistenceManager pm, Class<?> clazz )
284 {
285 Extent extent = pm.getExtent( clazz, true );
286 Query query = pm.newQuery( extent );
287 return (List<?>) query.execute();
288 }
289
290 private List<?> processConstraint( PersistenceManager pm, SimpleConstraint constraint )
291 {
292 Query query = pm.newQuery( constraint.getSelectSql() );
293
294 if ( constraint.getResultClass() == null )
295 {
296 throw new IllegalStateException( "Unable to use a SimpleConstraint with a null result class." );
297 }
298
299 query.setResultClass( constraint.getResultClass() );
300
301 if ( constraint.getFetchLimits() != null )
302 {
303 pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
304 }
305
306 List<?> objects;
307 if ( constraint.getParameters() != null )
308 {
309 objects = processParameterizedQuery( query, constraint.getParameters() );
310 }
311 else
312 {
313 objects = (List<?>) query.execute();
314 }
315 return objects;
316 }
317
318 private List<?> processConstraint( PersistenceManager pm, Class<?> clazz, DeclarativeConstraint constraint )
319 {
320 Extent extent = pm.getExtent( clazz, true );
321 Query query = pm.newQuery( extent );
322
323 if ( constraint.getFilter() != null )
324 {
325 query.setFilter( constraint.getFilter() );
326 }
327
328 if ( constraint.getVariables() != null )
329 {
330 query.declareVariables( StringUtils.join( constraint.getVariables(), "; " ) );
331 }
332
333 if ( constraint.getSortColumn() != null )
334 {
335 String ordering = constraint.getSortColumn();
336
337 if ( constraint.getSortDirection() != null )
338 {
339 ordering += " " + constraint.getSortDirection();
340 }
341
342 query.setOrdering( ordering );
343 }
344
345 if ( constraint.getFetchLimits() != null )
346 {
347 pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
348 }
349
350 if ( constraint.getWhereCondition() != null )
351 {
352 query.setFilter( constraint.getWhereCondition() );
353 }
354
355 if ( constraint.getDeclaredImports() != null )
356 {
357 query.declareImports( StringUtils.join( constraint.getDeclaredImports(), ", " ) );
358 }
359
360 if ( constraint.getRange() != null )
361 {
362 query.setRange( constraint.getRange()[0], constraint.getRange()[1] );
363 }
364
365 if ( constraint.getDeclaredParameters() != null )
366 {
367 if ( constraint.getParameters() == null )
368 {
369 throw new JDOException( "Unable to use query, there are declared parameters, "
370 + "but no parameter objects to use." );
371 }
372
373 if ( constraint.getParameters().length != constraint.getDeclaredParameters().length )
374 {
375 throw new JDOException( "Unable to use query, there are <" + constraint.getDeclaredParameters().length
376 + "> declared parameters, yet there are <" + constraint.getParameters().length
377 + "> parameter objects to use. This should be equal." );
378 }
379
380 query.declareParameters( StringUtils.join( constraint.getDeclaredParameters(), ", " ) );
381
382 return processParameterizedQuery( query, constraint.getParameters() );
383 }
384 else
385 {
386 return (List<?>) query.execute();
387 }
388 }
389
390 private List<?> processParameterizedQuery( Query query, Object parameters[] )
391 {
392 switch ( parameters.length )
393 {
394 case 1:
395 return (List<?>) query.execute( parameters[0] );
396 case 2:
397 return (List<?>) query.execute( parameters[0], parameters[1] );
398 case 3:
399 return (List<?>) query.execute( parameters[0], parameters[1], parameters[2] );
400 default:
401 return (List<?>) query.executeWithArray( parameters );
402 }
403 }
404
405 public Object getObjectById( Class<?> clazz, Object id, String fetchGroup )
406 throws ObjectNotFoundException, ArchivaDatabaseException
407 {
408 if ( id == null )
409 {
410 throw new ObjectNotFoundException( "Unable to get object '" + clazz.getName() + "' from jdo using null id." );
411 }
412
413 PersistenceManager pm = getPersistenceManager();
414 Transaction tx = pm.currentTransaction();
415
416 try
417 {
418 tx.begin();
419
420 if ( fetchGroup != null )
421 {
422 pm.getFetchPlan().addGroup( fetchGroup );
423 }
424
425 Object objectId = null;
426
427 if ( id instanceof CompoundKey )
428 {
429 objectId = pm.newObjectIdInstance( clazz, id.toString() );
430 }
431 else
432 {
433 objectId = pm.newObjectIdInstance( clazz, id );
434 }
435
436 Object object = pm.getObjectById( objectId );
437
438 object = pm.detachCopy( object );
439
440 tx.commit();
441
442 return object;
443 }
444 catch ( JDOObjectNotFoundException e )
445 {
446 throw new ObjectNotFoundException( "Unable to find Database Object [" + id + "] of type " + clazz.getName()
447 + " using " + ( ( fetchGroup == null ) ? "no fetch-group" : "a fetch-group of [" + fetchGroup + "]" ),
448 e, id );
449 }
450 catch ( JDOException e )
451 {
452 throw new ArchivaDatabaseException( "Error in JDO during get of Database object id [" + id + "] of type "
453 + clazz.getName() + " using "
454 + ( ( fetchGroup == null ) ? "no fetch-group" : "a fetch-group of [" + fetchGroup + "]" ), e );
455 }
456 finally
457 {
458 rollbackIfActive( tx );
459 }
460 }
461
462 public Object getObjectById( Class<?> clazz, String id, String fetchGroup )
463 throws ObjectNotFoundException, ArchivaDatabaseException
464 {
465 if ( StringUtils.isEmpty( id ) )
466 {
467 throw new ObjectNotFoundException( "Unable to get object '" + clazz.getName()
468 + "' from jdo using null/empty id." );
469 }
470
471 return getObjectById( clazz, (Object) id, fetchGroup );
472 }
473
474 public boolean objectExists( Object object )
475 {
476 return ( JDOHelper.getObjectId( object ) != null );
477 }
478
479 public boolean objectExistsById( Class<?> clazz, String id )
480 throws ArchivaDatabaseException
481 {
482 try
483 {
484 Object o = getObjectById( clazz, id, null );
485 return ( o != null );
486 }
487 catch ( ObjectNotFoundException e )
488 {
489 return false;
490 }
491 }
492
493 public void removeObject( Object o )
494 throws ArchivaDatabaseException
495 {
496 if ( o == null )
497 {
498 throw new ArchivaDatabaseException( "Unable to remove null object" );
499 }
500
501 PersistenceManager pm = getPersistenceManager();
502 Transaction tx = pm.currentTransaction();
503
504 try
505 {
506 tx.begin();
507
508 o = pm.getObjectById( pm.getObjectId( o ) );
509
510 pm.deletePersistent( o );
511
512 tx.commit();
513 }
514 finally
515 {
516 rollbackIfActive( tx );
517 }
518 }
519
520 public void rollbackIfActive( Transaction tx )
521 {
522 PersistenceManager pm = tx.getPersistenceManager();
523
524 try
525 {
526 if ( tx.isActive() )
527 {
528 tx.rollback();
529 }
530 }
531 finally
532 {
533 closePersistenceManager( pm );
534 }
535 }
536
537 public void closePersistenceManager( PersistenceManager pm )
538 {
539 try
540 {
541 pm.close();
542 }
543 catch ( JDOUserException e )
544 {
545
546 }
547 }
548
549 public void postDelete( InstanceLifecycleEvent evt )
550 {
551 PersistenceCapable obj = ( (PersistenceCapable) evt.getSource() );
552
553 if ( obj == null )
554 {
555
556
557 return;
558 }
559 }
560
561 public void preDelete( InstanceLifecycleEvent evt )
562 {
563
564 }
565
566 public void postStore( InstanceLifecycleEvent evt )
567 {
568
569 }
570
571 public void preStore( InstanceLifecycleEvent evt )
572 {
573
574 }
575
576 public void removeAll( Class<?> aClass )
577 {
578 PersistenceManager pm = getPersistenceManager();
579 Transaction tx = pm.currentTransaction();
580
581 try
582 {
583 tx.begin();
584
585 Query query = pm.newQuery( aClass );
586 query.deletePersistentAll();
587
588 tx.commit();
589 }
590 finally
591 {
592 rollbackIfActive( tx );
593 }
594 }
595
596 public JdoFactory getJdoFactory()
597 {
598 return jdoFactory;
599 }
600
601 public long countObjects( SimpleConstraint constraint )
602 {
603 PersistenceManager pm = getPersistenceManager();
604 Transaction tx = pm.currentTransaction();
605
606 try
607 {
608 tx.begin();
609
610 Query query = pm.newQuery( constraint.getCountSql() );
611
612 if ( constraint.getFetchLimits() != null )
613 {
614 pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
615 }
616
617 List<?> objects;
618 if ( constraint.getParameters() != null )
619 {
620 objects = processParameterizedQuery( query, constraint.getParameters() );
621 }
622 else
623 {
624 objects = (List<?>) query.execute();
625 }
626
627 Long result = !objects.isEmpty() ? (Long) objects.get( 0 ) : 0;
628
629 tx.commit();
630
631 return result;
632 }
633 finally
634 {
635 rollbackIfActive( tx );
636 }
637 }
638
639 public long countObjects( Class<?> clazz, DeclarativeConstraint constraint )
640 {
641 PersistenceManager pm = getPersistenceManager();
642 Transaction tx = pm.currentTransaction();
643
644 Long result = null;
645
646 try
647 {
648 tx.begin();
649
650 Extent extent = pm.getExtent( clazz, true );
651 Query query = pm.newQuery( extent );
652
653 if ( constraint.getFilter() != null )
654 {
655 query.setFilter( constraint.getFilter() );
656 }
657
658 if ( constraint.getVariables() != null )
659 {
660 query.declareVariables( StringUtils.join( constraint.getVariables(), "; " ) );
661 }
662
663 if ( constraint.getFetchLimits() != null )
664 {
665 pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
666 }
667
668 if ( constraint.getWhereCondition() != null )
669 {
670 query.setFilter( constraint.getWhereCondition() );
671 }
672
673 if ( constraint.getDeclaredImports() != null )
674 {
675 query.declareImports( StringUtils.join( constraint.getDeclaredImports(), ", " ) );
676 }
677
678 if ( constraint.getRange() != null )
679 {
680 query.setRange( constraint.getRange()[0], constraint.getRange()[1] );
681 }
682
683 query.setResult( "count(this)" );
684
685 if ( constraint.getDeclaredParameters() != null )
686 {
687 if ( constraint.getParameters() == null )
688 {
689 throw new JDOException( "Unable to use query, there are declared parameters, "
690 + "but no parameter objects to use." );
691 }
692
693 if ( constraint.getParameters().length != constraint.getDeclaredParameters().length )
694 {
695 throw new JDOException( "Unable to use query, there are <" + constraint.getDeclaredParameters().length
696 + "> declared parameters, yet there are <" + constraint.getParameters().length
697 + "> parameter objects to use. This should be equal." );
698 }
699
700 query.declareParameters( StringUtils.join( constraint.getDeclaredParameters(), ", " ) );
701
702 result = (Long) query.executeWithArray( constraint.getParameters() );
703 }
704 else
705 {
706 result = (Long) query.execute();
707 }
708 tx.commit();
709 }
710 finally
711 {
712 rollbackIfActive( tx );
713 }
714
715 return result;
716 }
717 }