View Javadoc

1   package org.apache.continuum.dao;
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.maven.continuum.model.project.BuildResult;
23  import org.apache.maven.continuum.model.project.Project;
24  import org.apache.maven.continuum.project.ContinuumProjectState;
25  import org.apache.maven.continuum.store.ContinuumStoreException;
26  import org.springframework.stereotype.Repository;
27  
28  import java.util.Calendar;
29  import java.util.Date;
30  import java.util.HashMap;
31  import java.util.List;
32  import java.util.Map;
33  import javax.jdo.Extent;
34  import javax.jdo.JDOHelper;
35  import javax.jdo.PersistenceManager;
36  import javax.jdo.Query;
37  import javax.jdo.Transaction;
38  
39  /**
40   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
41   * @version $Id: BuildResultDaoImpl.java 1372260 2012-08-13 04:29:09Z brett $
42   * @plexus.component role="org.apache.continuum.dao.BuildResultDao"
43   */
44  @Repository( "buildResultDao" )
45  public class BuildResultDaoImpl
46      extends AbstractDao
47      implements BuildResultDao
48  {
49      public void updateBuildResult( BuildResult build )
50          throws ContinuumStoreException
51      {
52          PersistenceManager pm = getPersistenceManager();
53  
54          Transaction tx = pm.currentTransaction();
55  
56          Project project = build.getProject();
57          try
58          {
59              tx.begin();
60  
61              if ( !JDOHelper.isDetached( build ) )
62              {
63                  throw new ContinuumStoreException( "Not detached: " + build );
64              }
65  
66              pm.makePersistent( build );
67  
68              if ( !JDOHelper.isDetached( project ) )
69              {
70                  throw new ContinuumStoreException( "Not detached: " + project );
71              }
72  
73              project.setState( build.getState() );
74  
75              //TODO: Use projectDao
76              pm.makePersistent( project );
77  
78              tx.commit();
79          }
80          finally
81          {
82              rollback( tx );
83          }
84      }
85  
86      public void addBuildResult( Project project, BuildResult build )
87          throws ContinuumStoreException
88      {
89          PersistenceManager pm = getPersistenceManager();
90  
91          Transaction tx = pm.currentTransaction();
92  
93          try
94          {
95              tx.begin();
96  
97              pm.getFetchPlan().addGroup( PROJECT_WITH_BUILDS_FETCH_GROUP );
98  
99              Object objectId = pm.newObjectIdInstance( Project.class, project.getId() );
100 
101             project = (Project) pm.getObjectById( objectId );
102 
103             build = (BuildResult) makePersistent( pm, build, false );
104 
105             // TODO: these are in the wrong spot - set them on success (though
106             // currently some depend on latest build being the one in progress)
107             project.setLatestBuildId( build.getId() );
108 
109             project.setState( build.getState() );
110 
111             project.addBuildResult( build );
112 
113             tx.commit();
114         }
115         finally
116         {
117             rollback( tx );
118         }
119     }
120 
121     public BuildResult getLatestBuildResultForProject( int projectId )
122     {
123         PersistenceManager pm = getPersistenceManager();
124 
125         Transaction tx = pm.currentTransaction();
126 
127         try
128         {
129             tx.begin();
130 
131             Extent extent = pm.getExtent( BuildResult.class, true );
132 
133             Query query = pm.newQuery( extent );
134 
135             query.declareParameters( "int projectId" );
136 
137             query.setFilter( "this.project.id == projectId && this.project.latestBuildId == this.id" );
138 
139             List<BuildResult> result = (List<BuildResult>) query.execute( projectId );
140 
141             result = (List<BuildResult>) pm.detachCopyAll( result );
142 
143             tx.commit();
144 
145             if ( result != null && !result.isEmpty() )
146             {
147                 return result.get( 0 );
148             }
149         }
150         finally
151         {
152             rollback( tx );
153         }
154         return null;
155     }
156 
157     public BuildResult getLatestBuildResultForProjectWithDetails( int projectId )
158     {
159         PersistenceManager pm = getPersistenceManager();
160 
161         Transaction tx = pm.currentTransaction();
162 
163         try
164         {
165             tx.begin();
166 
167             pm.getFetchPlan().addGroup( BUILD_RESULT_WITH_DETAILS_FETCH_GROUP );
168 
169             Extent extent = pm.getExtent( BuildResult.class, true );
170 
171             Query query = pm.newQuery( extent );
172 
173             query.declareParameters( "int projectId" );
174 
175             query.setFilter( "this.project.id == projectId && this.project.latestBuildId == this.id" );
176 
177             List<BuildResult> result = (List<BuildResult>) query.execute( projectId );
178 
179             result = (List<BuildResult>) pm.detachCopyAll( result );
180 
181             tx.commit();
182 
183             if ( result != null && !result.isEmpty() )
184             {
185                 return result.get( 0 );
186             }
187         }
188         finally
189         {
190             rollback( tx );
191         }
192         return null;
193     }
194 
195     public BuildResult getLatestBuildResultForBuildDefinition( int projectId, int buildDefinitionId )
196     {
197         PersistenceManager pm = getPersistenceManager();
198 
199         Transaction tx = pm.currentTransaction();
200 
201         try
202         {
203             tx.begin();
204 
205             Extent extent = pm.getExtent( BuildResult.class, true );
206 
207             Query query = pm.newQuery( extent );
208 
209             query.declareParameters( "int projectId, int buildDefinitionId" );
210 
211             query.setFilter( "this.project.id == projectId && this.buildDefinition.id == buildDefinitionId" );
212             query.setOrdering( "id descending" );
213 
214             Object[] params = new Object[2];
215             params[0] = projectId;
216             params[1] = buildDefinitionId;
217 
218             List<BuildResult> result = (List<BuildResult>) query.executeWithArray( params );
219 
220             result = (List<BuildResult>) pm.detachCopyAll( result );
221 
222             tx.commit();
223 
224             if ( result != null && !result.isEmpty() )
225             {
226                 return result.get( 0 );
227             }
228         }
229         finally
230         {
231             rollback( tx );
232         }
233         return null;
234     }
235 
236     public Map<Integer, BuildResult> getLatestBuildResultsByProjectGroupId( int projectGroupId )
237     {
238         PersistenceManager pm = getPersistenceManager();
239 
240         Transaction tx = pm.currentTransaction();
241 
242         try
243         {
244             tx.begin();
245 
246             Extent extent = pm.getExtent( BuildResult.class, true );
247 
248             Query query = pm.newQuery( extent );
249 
250             String filter = "this.project.latestBuildId == this.id";
251 
252             if ( projectGroupId > 0 )
253             {
254                 query.declareParameters( "int projectGroupId" );
255                 filter += " && this.project.projectGroup.id == projectGroupId";
256             }
257 
258             query.setFilter( filter );
259 
260             List<BuildResult> result;
261             if ( projectGroupId > 0 )
262             {
263                 result = (List<BuildResult>) query.execute( projectGroupId );
264             }
265             else
266             {
267                 result = (List<BuildResult>) query.execute();
268             }
269 
270             result = (List<BuildResult>) pm.detachCopyAll( result );
271 
272             tx.commit();
273 
274             if ( result != null && !result.isEmpty() )
275             {
276                 Map<Integer, BuildResult> builds = new HashMap<Integer, BuildResult>();
277 
278                 for ( BuildResult br : result )
279                 {
280                     builds.put( br.getProject().getId(), br );
281                 }
282 
283                 return builds;
284             }
285         }
286         finally
287         {
288             rollback( tx );
289         }
290 
291         return null;
292     }
293 
294     public void removeBuildResult( BuildResult buildResult )
295     {
296         removeObject( buildResult );
297     }
298 
299     public List<BuildResult> getAllBuildsForAProjectByDate( int projectId )
300     {
301         PersistenceManager pm = getPersistenceManager();
302 
303         Transaction tx = pm.currentTransaction();
304 
305         try
306         {
307             tx.begin();
308 
309             Query query = pm.newQuery( "SELECT FROM " + BuildResult.class.getName() +
310                                            " WHERE project.id == projectId PARAMETERS int projectId ORDER BY endTime DESC" );
311 
312             query.declareImports( "import java.lang.Integer" );
313 
314             query.declareParameters( "Integer projectId" );
315 
316             List<BuildResult> result = (List<BuildResult>) query.execute( projectId );
317 
318             result = (List<BuildResult>) pm.detachCopyAll( result );
319 
320             tx.commit();
321 
322             return result;
323         }
324         finally
325         {
326             rollback( tx );
327         }
328     }
329 
330     public BuildResult getBuildResult( int buildId )
331         throws ContinuumStoreException
332     {
333         return (BuildResult) getObjectById( BuildResult.class, buildId, BUILD_RESULT_WITH_DETAILS_FETCH_GROUP );
334     }
335 
336     public List<BuildResult> getBuildResultByBuildNumber( int projectId, int buildNumber )
337     {
338         PersistenceManager pm = getPersistenceManager();
339 
340         Transaction tx = pm.currentTransaction();
341 
342         try
343         {
344             tx.begin();
345 
346             Extent extent = pm.getExtent( BuildResult.class, true );
347 
348             Query query = pm.newQuery( extent );
349 
350             query.declareParameters( "int projectId, int buildNumber" );
351 
352             query.setFilter( "this.project.id == projectId && this.buildNumber == buildNumber" );
353 
354             List<BuildResult> result = (List<BuildResult>) query.execute( projectId, buildNumber );
355 
356             result = (List<BuildResult>) pm.detachCopyAll( result );
357 
358             tx.commit();
359 
360             return result;
361         }
362         finally
363         {
364             rollback( tx );
365         }
366     }
367 
368     public List<BuildResult> getBuildResultsByBuildDefinition( int projectId, int buildDefinitionId )
369     {
370         return getBuildResultsByBuildDefinition( projectId, buildDefinitionId, -1, -1 );
371     }
372 
373     public List<BuildResult> getBuildResultsByBuildDefinition( int projectId, int buildDefinitionId, long startIndex,
374                                                                long endIndex )
375     {
376         PersistenceManager pm = getPersistenceManager();
377 
378         Transaction tx = pm.currentTransaction();
379 
380         try
381         {
382             tx.begin();
383 
384             Extent extent = pm.getExtent( BuildResult.class, true );
385 
386             Query query = pm.newQuery( extent );
387 
388             if ( startIndex >= 0 && endIndex >= 0 )
389             {
390                 query.setRange( startIndex, endIndex );
391             }
392 
393             query.declareParameters( "int projectId, int buildDefinitionId" );
394 
395             query.setFilter( "this.project.id == projectId && this.buildDefinition.id == buildDefinitionId" );
396 
397             query.setOrdering( "this.id descending" );
398 
399             List<BuildResult> result = (List<BuildResult>) query.execute( projectId, buildDefinitionId );
400 
401             result = (List<BuildResult>) pm.detachCopyAll( result );
402 
403             tx.commit();
404 
405             return result;
406         }
407         finally
408         {
409             rollback( tx );
410         }
411     }
412 
413     public long getNbBuildResultsForProject( int projectId )
414     {
415         PersistenceManager pm = getPersistenceManager();
416 
417         Transaction tx = pm.currentTransaction();
418 
419         try
420         {
421             tx.begin();
422 
423             Query query = pm.newQuery( BuildResult.class, "project.id == projectId" );
424 
425             query.declareParameters( "int projectId" );
426 
427             query.setResult( "count(this)" );
428 
429             long result = (Long) query.execute( projectId );
430 
431             tx.commit();
432 
433             return result;
434         }
435         finally
436         {
437             rollback( tx );
438         }
439     }
440 
441     public long getNbBuildResultsInSuccessForProject( int projectId, long fromDate )
442     {
443         PersistenceManager pm = getPersistenceManager();
444 
445         Transaction tx = pm.currentTransaction();
446 
447         try
448         {
449             tx.begin();
450 
451             Extent extent = pm.getExtent( BuildResult.class, true );
452 
453             Query query = pm.newQuery( extent );
454 
455             query.declareParameters( "int projectId, long fromDate, int state" );
456 
457             query.setFilter( "this.project.id == projectId && this.startTime > fromDate && this.state == state" );
458 
459             query.setResult( "count(this)" );
460 
461             long result = (Long) query.execute( projectId, fromDate, ContinuumProjectState.OK );
462 
463             tx.commit();
464 
465             return result;
466         }
467         finally
468         {
469             rollback( tx );
470         }
471     }
472 
473     public List<BuildResult> getBuildResultsForProjectWithDetails( int projectId, long fromDate, int tobuildResultId )
474     {
475         PersistenceManager pm = getPersistenceManager();
476 
477         Transaction tx = pm.currentTransaction();
478 
479         try
480         {
481             tx.begin();
482 
483             Extent extent = pm.getExtent( BuildResult.class, true );
484             pm.getFetchPlan().addGroup( BUILD_RESULT_WITH_DETAILS_FETCH_GROUP );
485 
486             Query query = pm.newQuery( extent );
487 
488             String parameters = "int projectId, long fromDate";
489             String filter = "this.project.id == projectId && this.startTime > fromDate";
490 
491             if ( tobuildResultId > 0 )
492             {
493                 parameters += ", int buildResultId";
494                 filter += " && this.id < buildResultId";
495             }
496             query.declareParameters( parameters );
497 
498             query.setFilter( filter );
499 
500             query.setOrdering( "this.id descending" );
501 
502             List<BuildResult> result;
503 
504             if ( tobuildResultId > 0 )
505             {
506                 result = (List<BuildResult>) query.execute( projectId, fromDate, tobuildResultId );
507             }
508             else
509             {
510                 result = (List<BuildResult>) query.execute( projectId, fromDate );
511             }
512 
513             result = (List<BuildResult>) pm.detachCopyAll( result );
514 
515             tx.commit();
516 
517             return result;
518         }
519         finally
520         {
521             rollback( tx );
522         }
523     }
524 
525     public List<BuildResult> getBuildResultsForProject( int projectId )
526     {
527         return getBuildResultsForProjectWithDetails( projectId, -1, -1 );
528     }
529 
530     public List<BuildResult> getBuildResultsForProject( int projectId, long startIndex, long endIndex )
531     {
532         PersistenceManager pm = getPersistenceManager();
533 
534         Transaction tx = pm.currentTransaction();
535 
536         try
537         {
538             tx.begin();
539 
540             Extent extent = pm.getExtent( BuildResult.class, true );
541 
542             Query query = pm.newQuery( extent );
543 
544             query.declareParameters( "int projectId" );
545 
546             query.setFilter( "this.project.id == projectId" );
547 
548             query.setOrdering( "this.startTime descending" );
549 
550             if ( startIndex >= 0 )
551             {
552                 query.setRange( startIndex, endIndex );
553             }
554 
555             List<BuildResult> result = (List<BuildResult>) query.execute( projectId );
556 
557             result = (List<BuildResult>) pm.detachCopyAll( result );
558 
559             tx.commit();
560 
561             return result;
562         }
563         finally
564         {
565             rollback( tx );
566         }
567     }
568 
569     public List<BuildResult> getBuildResultsForProjectFromId( int projectId, long startId )
570         throws ContinuumStoreException
571     {
572         PersistenceManager pm = getPersistenceManager();
573 
574         Transaction tx = pm.currentTransaction();
575 
576         pm.getFetchPlan().addGroup( BUILD_RESULT_WITH_DETAILS_FETCH_GROUP );
577 
578         try
579         {
580             tx.begin();
581 
582             Extent extent = pm.getExtent( BuildResult.class, true );
583 
584             Query query = pm.newQuery( extent );
585 
586             query.declareParameters( "int projectId, int buildNumber" );
587 
588             query.setFilter( "this.project.id == projectId && this.buildNumber >= buildNumber" );
589 
590             query.setOrdering( "this.startTime descending" );
591 
592             List<BuildResult> result = (List<BuildResult>) query.execute( projectId, startId );
593 
594             result = (List<BuildResult>) pm.detachCopyAll( result );
595 
596             tx.commit();
597 
598             return result;
599         }
600         catch ( Exception e )
601         {
602             throw new ContinuumStoreException( e.getMessage(), e );
603         }
604         finally
605         {
606             rollback( tx );
607         }
608     }
609 
610     public BuildResult getLatestBuildResultInSuccess( int projectId )
611     {
612         PersistenceManager pm = getPersistenceManager();
613 
614         Transaction tx = pm.currentTransaction();
615 
616         try
617         {
618             tx.begin();
619 
620             Extent extent = pm.getExtent( BuildResult.class, true );
621 
622             Query query = pm.newQuery( extent );
623 
624             query.declareParameters( "int projectId" );
625 
626             String filter = "this.project.buildNumber == this.buildNumber && this.project.id == projectId";
627 
628             query.setFilter( filter );
629 
630             query.setUnique( true );
631 
632             BuildResult result = (BuildResult) query.execute( projectId );
633 
634             result = (BuildResult) pm.detachCopy( result );
635 
636             tx.commit();
637 
638             return result;
639         }
640         finally
641         {
642             rollback( tx );
643         }
644     }
645 
646     private int getPreviousBuildResultIdInSuccess( int projectId, int buildResultId )
647     {
648         PersistenceManager pm = getPersistenceManager();
649 
650         Transaction tx = pm.currentTransaction();
651 
652         try
653         {
654             tx.begin();
655 
656             Extent extent = pm.getExtent( BuildResult.class, true );
657 
658             Query query = pm.newQuery( extent );
659 
660             query.declareParameters( "int projectId, int buildResultId" );
661 
662             String filter = "this.id < buildResultId && this.state == " + ContinuumProjectState.OK +
663                 "  && this.project.id == projectId";
664 
665             query.setFilter( filter );
666 
667             query.setResult( "max(this.id)" );
668 
669             int result = (Integer) query.execute( projectId, buildResultId );
670 
671             tx.commit();
672 
673             return result;
674         }
675         finally
676         {
677             rollback( tx );
678         }
679     }
680 
681     public BuildResult getPreviousBuildResultInSuccess( int projectId, int buildResultId )
682         throws ContinuumStoreException
683     {
684         try
685         {
686             return getBuildResult( getPreviousBuildResultIdInSuccess( projectId, buildResultId ) );
687         }
688         catch ( NullPointerException e )
689         {
690             return null;
691         }
692     }
693 
694     public Map<Integer, BuildResult> getBuildResultsInSuccessByProjectGroupId( int projectGroupId )
695     {
696         PersistenceManager pm = getPersistenceManager();
697 
698         Transaction tx = pm.currentTransaction();
699 
700         try
701         {
702             tx.begin();
703 
704             Extent extent = pm.getExtent( BuildResult.class, true );
705 
706             Query query = pm.newQuery( extent );
707 
708             String filter = "this.project.buildNumber == this.buildNumber";
709 
710             if ( projectGroupId > 0 )
711             {
712                 query.declareParameters( "int projectGroupId" );
713                 filter += " && this.project.projectGroup.id == projectGroupId";
714             }
715 
716             query.setFilter( filter );
717 
718             List<BuildResult> result;
719 
720             if ( projectGroupId > 0 )
721             {
722                 result = (List<BuildResult>) query.execute( projectGroupId );
723             }
724             else
725             {
726                 result = (List<BuildResult>) query.execute();
727             }
728 
729             result = (List<BuildResult>) pm.detachCopyAll( result );
730 
731             tx.commit();
732 
733             if ( result != null && !result.isEmpty() )
734             {
735                 Map<Integer, BuildResult> builds = new HashMap<Integer, BuildResult>();
736 
737                 for ( BuildResult br : result )
738                 {
739                     builds.put( br.getProject().getId(), br );
740                 }
741 
742                 return builds;
743             }
744         }
745         finally
746         {
747             rollback( tx );
748         }
749 
750         return null;
751     }
752 
753     @SuppressWarnings( "unchecked" )
754     public List<BuildResult> getBuildResultsInRange( Date fromDate, Date toDate, int state, String triggeredBy,
755                                                      int projectGroupId )
756     {
757         PersistenceManager pm = getPersistenceManager();
758 
759         Transaction tx = pm.currentTransaction();
760 
761         try
762         {
763             tx.begin();
764 
765             pm.getFetchPlan().addGroup( BUILD_RESULT_WITH_DETAILS_FETCH_GROUP );
766 
767             Extent extent = pm.getExtent( BuildResult.class, true );
768 
769             Query query = pm.newQuery( extent );
770 
771             String parameters = "";
772             String filter = "";
773 
774             Map params = new HashMap();
775 
776             int ctr = 0;
777 
778             if ( state > 0 )
779             {
780                 params.put( "state", state );
781                 ctr++;
782                 parameters += "int state, ";
783                 filter += "this.state == state && ";
784             }
785 
786             if ( projectGroupId > 0 )
787             {
788                 params.put( "projectGroupId", projectGroupId );
789                 ctr++;
790                 parameters += "int projectGroupId, ";
791                 filter += "this.project.projectGroup.id == projectGroupId && ";
792             }
793 
794             if ( triggeredBy != null && !triggeredBy.equals( "" ) )
795             {
796                 params.put( "triggeredBy", triggeredBy );
797                 ctr++;
798                 query.declareImports( "import java.lang.String" );
799                 parameters += "String triggeredBy, ";
800                 filter += "this.username == triggeredBy && ";
801             }
802 
803             if ( fromDate != null )
804             {
805                 params.put( "fromDate", fromDate.getTime() );
806                 ctr++;
807                 parameters += "long fromDate, ";
808                 filter += "this.startTime >= fromDate && ";
809             }
810 
811             if ( toDate != null )
812             {
813                 Calendar cal = Calendar.getInstance();
814                 cal.setTime( toDate );
815                 cal.add( Calendar.DAY_OF_MONTH, 1 );
816 
817                 params.put( "toDate", cal.getTimeInMillis() );
818                 ctr++;
819                 parameters += "long toDate";
820                 filter += "this.startTime < toDate";
821             }
822 
823             if ( filter.endsWith( "&& " ) )
824             {
825                 filter = filter.substring( 0, filter.length() - 3 );
826                 parameters = parameters.substring( 0, parameters.length() - 2 );
827             }
828 
829             query.declareParameters( parameters );
830             query.setFilter( filter );
831 
832             List<BuildResult> result = (List<BuildResult>) query.executeWithMap( params );
833 
834             result = (List<BuildResult>) pm.detachCopyAll( result );
835 
836             tx.commit();
837 
838             return result;
839         }
840         finally
841         {
842             rollback( tx );
843         }
844     }
845 }