Coverage Report - org.apache.maven.archiva.database.jdo.JdoAccess
 
Classes in this File Line Coverage Branch Coverage Complexity
JdoAccess
0%
0/228
0%
0/100
0
 
 1  
 package org.apache.maven.archiva.database.jdo;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *  http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 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  
  * JdoAccess 
 55  
  *
 56  
  * @version $Id: JdoAccess.java 1043850 2010-12-09 07:58:00Z brett $
 57  
  * @plexus.component role="org.apache.maven.archiva.database.jdo.JdoAccess" role-hint="archiva"
 58  
  */
 59  0
 public class JdoAccess
 60  
     implements Initializable, InstanceLifecycleListener, StoreLifecycleListener
 61  
 {
 62  
     /**
 63  
      * @plexus.requirement role-hint="archiva"
 64  
      */
 65  
     private JdoFactory jdoFactory;
 66  
 
 67  
     private PersistenceManagerFactory pmf;
 68  
 
 69  
     public void initialize()
 70  
         throws InitializationException
 71  
     {
 72  0
         pmf = jdoFactory.getPersistenceManagerFactory();
 73  
 
 74  
         /* Primitive (and failed) attempt at creating the schema on startup.
 75  
          Just to prevent the multiple stack trace warnings on auto-gen of schema.
 76  
          
 77  
          // Create the schema (if needed)
 78  
          URL jdoFileUrls[] = new URL[] { getClass().getResource( "/org/apache/maven/archiva/model/package.jdo" ) };
 79  
 
 80  
          File propsFile = null; // intentional
 81  
          boolean verbose = true;
 82  
 
 83  
          try
 84  
          {
 85  
          String connectionFactoryName = pmf.getConnectionFactoryName();
 86  
          if ( StringUtils.isNotBlank( connectionFactoryName ) && connectionFactoryName.startsWith( "java:comp" ) )
 87  
          {
 88  
          // We have a JNDI datasource!
 89  
          String jndiDatasource = connectionFactoryName;
 90  
          System.setProperty( PMFConfiguration.JDO_DATASTORE_URL_PROPERTY, jndiDatasource );
 91  
          }
 92  
          
 93  
          // TODO: figure out how to get the jdbc driver details from JNDI to pass into SchemaTool.
 94  
 
 95  
          SchemaTool.createSchemaTables( jdoFileUrls, new URL[] {}, propsFile, verbose, null );
 96  
          }
 97  
          catch ( Exception e )
 98  
          {
 99  
          getLogger().error( "Unable to create schema: " + e.getMessage(), e );
 100  
          }
 101  
 
 102  
          pmf.getPersistenceManager();
 103  
          */
 104  
 
 105  
         // Add the lifecycle listener.
 106  0
         pmf.addInstanceLifecycleListener( this, null );
 107  0
     }
 108  
 
 109  
     public static void dumpObjectState( PrintStream out, Object o )
 110  
     {
 111  0
         final String STATE = "[STATE] ";
 112  0
         final String INDENT = "        ";
 113  
 
 114  0
         if ( o == null )
 115  
         {
 116  0
             out.println( STATE + "Object is null." );
 117  0
             return;
 118  
         }
 119  
 
 120  0
         out.println( STATE + "Object " + o.getClass().getName() );
 121  
 
 122  0
         if ( !( o instanceof PersistenceCapable ) )
 123  
         {
 124  0
             out.println( INDENT + "is NOT PersistenceCapable (not a jdo object?)" );
 125  0
             return;
 126  
         }
 127  
 
 128  0
         out.println( INDENT + "is PersistenceCapable." );
 129  0
         if ( o instanceof Detachable )
 130  
         {
 131  0
             out.println( INDENT + "is Detachable" );
 132  
         }
 133  
 
 134  0
         out.println( INDENT + "is new : " + Boolean.toString( JDOHelper.isNew( o ) ) );
 135  0
         out.println( INDENT + "is transactional : " + Boolean.toString( JDOHelper.isTransactional( o ) ) );
 136  0
         out.println( INDENT + "is deleted : " + Boolean.toString( JDOHelper.isDeleted( o ) ) );
 137  0
         out.println( INDENT + "is detached : " + Boolean.toString( JDOHelper.isDetached( o ) ) );
 138  0
         out.println( INDENT + "is dirty : " + Boolean.toString( JDOHelper.isDirty( o ) ) );
 139  0
         out.println( INDENT + "is persistent : " + Boolean.toString( JDOHelper.isPersistent( o ) ) );
 140  
 
 141  0
         out.println( INDENT + "object id : " + JDOHelper.getObjectId( o ) );
 142  0
     }
 143  
 
 144  
     public PersistenceManager getPersistenceManager()
 145  
     {
 146  0
         PersistenceManager pm = pmf.getPersistenceManager();
 147  
 
 148  0
         pm.getFetchPlan().setMaxFetchDepth( -1 );
 149  
 
 150  0
         return pm;
 151  
     }
 152  
 
 153  
     public void enableCache( Class<?> clazz )
 154  
     {
 155  0
         DataStoreCache cache = pmf.getDataStoreCache();
 156  0
         cache.pinAll( clazz, false ); // Pin all objects of type clazz from now on
 157  0
     }
 158  
 
 159  
     public Object saveObject( Object object )
 160  
     {
 161  0
         return saveObject( object, null );
 162  
     }
 163  
 
 164  
     public Object saveObject( Object object, String[] fetchGroups )
 165  
     {
 166  0
         PersistenceManager pm = getPersistenceManager();
 167  0
         Transaction tx = pm.currentTransaction();
 168  
 
 169  
         try
 170  
         {
 171  0
             tx.begin();
 172  
 
 173  0
             if ( ( JDOHelper.getObjectId( object ) != null ) && !JDOHelper.isDetached( object ) )
 174  
             {
 175  
                 // This is a fatal error that means we need to fix our code.
 176  
                 // Leave it as a JDOUserException, it's intentional.
 177  0
                 throw new JDOUserException( "Existing object is not detached: " + object, object );
 178  
             }
 179  
 
 180  0
             if ( fetchGroups != null )
 181  
             {
 182  0
                 for ( int i = 0; i >= fetchGroups.length; i++ )
 183  
                 {
 184  0
                     pm.getFetchPlan().addGroup( fetchGroups[i] );
 185  
                 }
 186  
             }
 187  
 
 188  0
             pm.makePersistent( object );
 189  
 
 190  0
             object = pm.detachCopy( object );
 191  
 
 192  0
             tx.commit();
 193  
 
 194  0
             return object;
 195  
         }
 196  
         finally
 197  
         {
 198  0
             rollbackIfActive( tx );
 199  
         }
 200  
     }
 201  
 
 202  
     public List<?> getAllObjects( Class<?> clazz )
 203  
     {
 204  0
         return queryObjects( clazz, null );
 205  
     }
 206  
 
 207  
     public List<?> queryObjects( Class<?> clazz, Constraint constraint )
 208  
     {
 209  0
         PersistenceManager pm = getPersistenceManager();
 210  0
         Transaction tx = pm.currentTransaction();
 211  
 
 212  0
         List<?> result = null;
 213  
 
 214  
         try
 215  
         {
 216  0
             tx.begin();
 217  
 
 218  0
             if ( constraint != null )
 219  
             {
 220  0
                 if ( constraint instanceof DeclarativeConstraint )
 221  
                 {
 222  0
                     result = processConstraint( pm, clazz, (DeclarativeConstraint) constraint );
 223  
                 }
 224  0
                 else if ( constraint instanceof AbstractSimpleConstraint )
 225  
                 {
 226  0
                     result = processConstraint( pm, (SimpleConstraint) constraint );
 227  
                 }
 228  
                 else
 229  
                 {
 230  0
                     result = processUnconstrained( pm, clazz );
 231  
                 }
 232  
             }
 233  
             else
 234  
             {
 235  0
                 result = processUnconstrained( pm, clazz );
 236  
             }
 237  
 
 238  0
             result = (List<?>) pm.detachCopyAll( result );
 239  
 
 240  0
             tx.commit();
 241  
         }
 242  
         finally
 243  
         {
 244  0
             rollbackIfActive( tx );
 245  0
         }
 246  
 
 247  0
         return result;
 248  
     }
 249  
 
 250  
     public List<?> queryObjects( SimpleConstraint constraint )
 251  
     {
 252  0
         PersistenceManager pm = getPersistenceManager();
 253  0
         Transaction tx = pm.currentTransaction();
 254  
 
 255  
         try
 256  
         {
 257  0
             tx.begin();
 258  
 
 259  0
             List<?> result = processConstraint( pm, constraint );
 260  
 
 261  
             // Only detach if results are known to be persistable.
 262  0
             if ( constraint.isResultsPersistable() )
 263  
             {
 264  0
                 result = (List<?>) pm.detachCopyAll( result );
 265  
             }
 266  
             else
 267  
             {
 268  0
                 List<Object> copiedResults = new ArrayList<Object>();
 269  0
                 copiedResults.addAll( result );
 270  0
                 result = copiedResults;
 271  
             }
 272  
 
 273  0
             tx.commit();
 274  
 
 275  0
             return result;
 276  
         }
 277  
         finally
 278  
         {
 279  0
             rollbackIfActive( tx );
 280  
         }
 281  
     }
 282  
 
 283  
     private List<?> processUnconstrained( PersistenceManager pm, Class<?> clazz )
 284  
     {
 285  0
         Extent extent = pm.getExtent( clazz, true );
 286  0
         Query query = pm.newQuery( extent );
 287  0
         return (List<?>) query.execute();
 288  
     }
 289  
 
 290  
     private List<?> processConstraint( PersistenceManager pm, SimpleConstraint constraint )
 291  
     {
 292  0
         Query query = pm.newQuery( constraint.getSelectSql() );
 293  
 
 294  0
         if ( constraint.getResultClass() == null )
 295  
         {
 296  0
             throw new IllegalStateException( "Unable to use a SimpleConstraint with a null result class." );
 297  
         }
 298  
 
 299  0
         query.setResultClass( constraint.getResultClass() );
 300  
 
 301  0
         if ( constraint.getFetchLimits() != null )
 302  
         {
 303  0
             pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
 304  
         }
 305  
 
 306  
         List<?> objects;
 307  0
         if ( constraint.getParameters() != null )
 308  
         {
 309  0
             objects = processParameterizedQuery( query, constraint.getParameters() );
 310  
         }
 311  
         else
 312  
         {
 313  0
             objects = (List<?>) query.execute();
 314  
         }
 315  0
         return objects;
 316  
     }
 317  
 
 318  
     private List<?> processConstraint( PersistenceManager pm, Class<?> clazz, DeclarativeConstraint constraint )
 319  
     {
 320  0
         Extent extent = pm.getExtent( clazz, true );
 321  0
         Query query = pm.newQuery( extent );
 322  
 
 323  0
         if ( constraint.getFilter() != null )
 324  
         {
 325  0
             query.setFilter( constraint.getFilter() );
 326  
         }
 327  
 
 328  0
         if ( constraint.getVariables() != null )
 329  
         {
 330  0
             query.declareVariables( StringUtils.join( constraint.getVariables(), ";  " ) );
 331  
         }
 332  
 
 333  0
         if ( constraint.getSortColumn() != null )
 334  
         {
 335  0
             String ordering = constraint.getSortColumn();
 336  
 
 337  0
             if ( constraint.getSortDirection() != null )
 338  
             {
 339  0
                 ordering += " " + constraint.getSortDirection();
 340  
             }
 341  
 
 342  0
             query.setOrdering( ordering );
 343  
         }
 344  
 
 345  0
         if ( constraint.getFetchLimits() != null )
 346  
         {
 347  0
             pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
 348  
         }
 349  
 
 350  0
         if ( constraint.getWhereCondition() != null )
 351  
         {
 352  0
             query.setFilter( constraint.getWhereCondition() );
 353  
         }
 354  
 
 355  0
         if ( constraint.getDeclaredImports() != null )
 356  
         {
 357  0
             query.declareImports( StringUtils.join( constraint.getDeclaredImports(), ", " ) );
 358  
         }
 359  
 
 360  0
         if ( constraint.getRange() != null )
 361  
         {
 362  0
                 query.setRange( constraint.getRange()[0], constraint.getRange()[1] );
 363  
         }
 364  
 
 365  0
         if ( constraint.getDeclaredParameters() != null )
 366  
         {
 367  0
             if ( constraint.getParameters() == null )
 368  
             {
 369  0
                 throw new JDOException( "Unable to use query, there are declared parameters, "
 370  
                     + "but no parameter objects to use." );
 371  
             }
 372  
 
 373  0
             if ( constraint.getParameters().length != constraint.getDeclaredParameters().length )
 374  
             {
 375  0
                 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  0
             query.declareParameters( StringUtils.join( constraint.getDeclaredParameters(), ", " ) );
 381  
 
 382  0
             return processParameterizedQuery( query, constraint.getParameters() );
 383  
         }
 384  
         else
 385  
         {
 386  0
             return (List<?>) query.execute();
 387  
         }
 388  
     }
 389  
 
 390  
     private List<?> processParameterizedQuery( Query query, Object parameters[] )
 391  
     {
 392  0
         switch ( parameters.length )
 393  
         {
 394  
             case 1:
 395  0
                 return (List<?>) query.execute( parameters[0] );
 396  
             case 2:
 397  0
                 return (List<?>) query.execute( parameters[0], parameters[1] );
 398  
             case 3:
 399  0
                 return (List<?>) query.execute( parameters[0], parameters[1], parameters[2] );
 400  
             default:
 401  0
                 return (List<?>) query.executeWithArray( parameters );                
 402  
         }
 403  
     }
 404  
 
 405  
     public Object getObjectById( Class<?> clazz, Object id, String fetchGroup )
 406  
         throws ObjectNotFoundException, ArchivaDatabaseException
 407  
     {
 408  0
         if ( id == null )
 409  
         {
 410  0
             throw new ObjectNotFoundException( "Unable to get object '" + clazz.getName() + "' from jdo using null id." );
 411  
         }
 412  
 
 413  0
         PersistenceManager pm = getPersistenceManager();
 414  0
         Transaction tx = pm.currentTransaction();
 415  
 
 416  
         try
 417  
         {
 418  0
             tx.begin();
 419  
 
 420  0
             if ( fetchGroup != null )
 421  
             {
 422  0
                 pm.getFetchPlan().addGroup( fetchGroup );
 423  
             }
 424  
 
 425  0
             Object objectId = null;
 426  
 
 427  0
             if ( id instanceof CompoundKey )
 428  
             {
 429  0
                 objectId = pm.newObjectIdInstance( clazz, id.toString() );
 430  
             }
 431  
             else
 432  
             {
 433  0
                 objectId = pm.newObjectIdInstance( clazz, id );
 434  
             }
 435  
 
 436  0
             Object object = pm.getObjectById( objectId );
 437  
 
 438  0
             object = pm.detachCopy( object );
 439  
 
 440  0
             tx.commit();
 441  
 
 442  0
             return object;
 443  
         }
 444  0
         catch ( JDOObjectNotFoundException e )
 445  
         {
 446  0
             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  0
         catch ( JDOException e )
 451  
         {
 452  0
             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  0
             rollbackIfActive( tx );
 459  
         }
 460  
     }
 461  
 
 462  
     public Object getObjectById( Class<?> clazz, String id, String fetchGroup )
 463  
         throws ObjectNotFoundException, ArchivaDatabaseException
 464  
     {
 465  0
         if ( StringUtils.isEmpty( id ) )
 466  
         {
 467  0
             throw new ObjectNotFoundException( "Unable to get object '" + clazz.getName()
 468  
                 + "' from jdo using null/empty id." );
 469  
         }
 470  
 
 471  0
         return getObjectById( clazz, (Object) id, fetchGroup );
 472  
     }
 473  
 
 474  
     public boolean objectExists( Object object )
 475  
     {
 476  0
         return ( JDOHelper.getObjectId( object ) != null );
 477  
     }
 478  
 
 479  
     public boolean objectExistsById( Class<?> clazz, String id )
 480  
         throws ArchivaDatabaseException
 481  
     {
 482  
         try
 483  
         {
 484  0
             Object o = getObjectById( clazz, id, null );
 485  0
             return ( o != null );
 486  
         }
 487  0
         catch ( ObjectNotFoundException e )
 488  
         {
 489  0
             return false;
 490  
         }
 491  
     }
 492  
 
 493  
     public void removeObject( Object o )
 494  
         throws ArchivaDatabaseException
 495  
     {
 496  0
         if ( o == null )
 497  
         {
 498  0
             throw new ArchivaDatabaseException( "Unable to remove null object" );
 499  
         }
 500  
 
 501  0
         PersistenceManager pm = getPersistenceManager();
 502  0
         Transaction tx = pm.currentTransaction();
 503  
 
 504  
         try
 505  
         {
 506  0
             tx.begin();
 507  
 
 508  0
             o = pm.getObjectById( pm.getObjectId( o ) );
 509  
 
 510  0
             pm.deletePersistent( o );
 511  
 
 512  0
             tx.commit();
 513  
         }
 514  
         finally
 515  
         {
 516  0
             rollbackIfActive( tx );
 517  0
         }
 518  0
     }
 519  
 
 520  
     public void rollbackIfActive( Transaction tx )
 521  
     {
 522  0
         PersistenceManager pm = tx.getPersistenceManager();
 523  
 
 524  
         try
 525  
         {
 526  0
             if ( tx.isActive() )
 527  
             {
 528  0
                 tx.rollback();
 529  
             }
 530  
         }
 531  
         finally
 532  
         {
 533  0
             closePersistenceManager( pm );
 534  0
         }
 535  0
     }
 536  
 
 537  
     public void closePersistenceManager( PersistenceManager pm )
 538  
     {
 539  
         try
 540  
         {
 541  0
             pm.close();
 542  
         }
 543  0
         catch ( JDOUserException e )
 544  
         {
 545  
             // ignore
 546  0
         }
 547  0
     }
 548  
 
 549  
     public void postDelete( InstanceLifecycleEvent evt )
 550  
     {
 551  0
         PersistenceCapable obj = ( (PersistenceCapable) evt.getSource() );
 552  
 
 553  0
         if ( obj == null )
 554  
         {
 555  
             // Do not track null objects.
 556  
             // These events are typically a product of an internal lifecycle event.
 557  0
             return;
 558  
         }
 559  0
     }
 560  
 
 561  
     public void preDelete( InstanceLifecycleEvent evt )
 562  
     {
 563  
         // ignore
 564  0
     }
 565  
 
 566  
     public void postStore( InstanceLifecycleEvent evt )
 567  
     {
 568  
         // PersistenceCapable obj = ( (PersistenceCapable) evt.getSource() );
 569  0
     }
 570  
 
 571  
     public void preStore( InstanceLifecycleEvent evt )
 572  
     {
 573  
         // ignore
 574  0
     }
 575  
 
 576  
     public void removeAll( Class<?> aClass )
 577  
     {
 578  0
         PersistenceManager pm = getPersistenceManager();
 579  0
         Transaction tx = pm.currentTransaction();
 580  
 
 581  
         try
 582  
         {
 583  0
             tx.begin();
 584  
 
 585  0
             Query query = pm.newQuery( aClass );
 586  0
             query.deletePersistentAll();
 587  
 
 588  0
             tx.commit();
 589  
         }
 590  
         finally
 591  
         {
 592  0
             rollbackIfActive( tx );
 593  0
         }
 594  0
     }
 595  
 
 596  
     public JdoFactory getJdoFactory()
 597  
     {
 598  0
         return jdoFactory;
 599  
     }
 600  
 
 601  
     public long countObjects( SimpleConstraint constraint )
 602  
     {
 603  0
         PersistenceManager pm = getPersistenceManager();
 604  0
         Transaction tx = pm.currentTransaction();
 605  
 
 606  
         try
 607  
         {
 608  0
             tx.begin();
 609  
 
 610  0
             Query query = pm.newQuery( constraint.getCountSql() );
 611  
 
 612  0
             if ( constraint.getFetchLimits() != null )
 613  
             {
 614  0
                 pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
 615  
             }
 616  
 
 617  
             List<?> objects;
 618  0
             if ( constraint.getParameters() != null )
 619  
             {
 620  0
                 objects = processParameterizedQuery( query, constraint.getParameters() );
 621  
             }
 622  
             else
 623  
             {
 624  0
                 objects = (List<?>) query.execute();
 625  
             }
 626  
 
 627  0
             Long result = !objects.isEmpty() ? (Long) objects.get( 0 ) : 0;
 628  
 
 629  0
             tx.commit();
 630  
 
 631  0
             return result;
 632  
         }
 633  
         finally
 634  
         {
 635  0
             rollbackIfActive( tx );
 636  
         }
 637  
     }
 638  
 
 639  
     public long countObjects( Class<?> clazz, DeclarativeConstraint constraint )
 640  
     {
 641  0
         PersistenceManager pm = getPersistenceManager();
 642  0
         Transaction tx = pm.currentTransaction();
 643  
 
 644  0
         Long result = null;
 645  
 
 646  
         try
 647  
         {
 648  0
             tx.begin();
 649  
 
 650  0
             Extent extent = pm.getExtent( clazz, true );
 651  0
             Query query = pm.newQuery( extent );
 652  
 
 653  0
             if ( constraint.getFilter() != null )
 654  
             {
 655  0
                 query.setFilter( constraint.getFilter() );
 656  
             }
 657  
 
 658  0
             if ( constraint.getVariables() != null )
 659  
             {
 660  0
                 query.declareVariables( StringUtils.join( constraint.getVariables(), ";  " ) );
 661  
             }
 662  
 
 663  0
             if ( constraint.getFetchLimits() != null )
 664  
             {
 665  0
                 pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
 666  
             }
 667  
 
 668  0
             if ( constraint.getWhereCondition() != null )
 669  
             {
 670  0
                 query.setFilter( constraint.getWhereCondition() );
 671  
             }
 672  
 
 673  0
             if ( constraint.getDeclaredImports() != null )
 674  
             {
 675  0
                 query.declareImports( StringUtils.join( constraint.getDeclaredImports(), ", " ) );
 676  
             }
 677  
 
 678  0
             if ( constraint.getRange() != null )
 679  
             {
 680  0
                 query.setRange( constraint.getRange()[0], constraint.getRange()[1] );
 681  
             }
 682  
 
 683  0
             query.setResult( "count(this)" );
 684  
 
 685  0
             if ( constraint.getDeclaredParameters() != null )
 686  
             {
 687  0
                 if ( constraint.getParameters() == null )
 688  
                 {
 689  0
                     throw new JDOException( "Unable to use query, there are declared parameters, "
 690  
                         + "but no parameter objects to use." );
 691  
                 }
 692  
 
 693  0
                 if ( constraint.getParameters().length != constraint.getDeclaredParameters().length )
 694  
                 {
 695  0
                     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  0
                 query.declareParameters( StringUtils.join( constraint.getDeclaredParameters(), ", " ) );
 701  
 
 702  0
                 result = (Long) query.executeWithArray( constraint.getParameters() );
 703  
             }
 704  
             else
 705  
             {
 706  0
                 result = (Long) query.execute();
 707  
             }
 708  0
             tx.commit();
 709  
         }
 710  
         finally
 711  
         {
 712  0
             rollbackIfActive( tx );
 713  0
         }
 714  
 
 715  0
         return result;
 716  
     }
 717  
 }