View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.releaser.service;
35  
36  import java.io.FileInputStream;
37  import java.io.FileNotFoundException;
38  import java.io.IOException;
39  import java.io.InputStream;
40  import java.util.ArrayList;
41  import java.util.HashMap;
42  import java.util.List;
43  import java.util.Locale;
44  import java.util.Map;
45  import java.util.concurrent.ExecutionException;
46  import java.util.concurrent.ExecutorService;
47  import java.util.concurrent.Executors;
48  import java.util.concurrent.Future;
49  
50  import javax.servlet.http.HttpServletRequest;
51  import javax.xml.bind.JAXBException;
52  
53  import fr.paris.lutece.plugins.releaser.business.Component;
54  import fr.paris.lutece.plugins.releaser.business.Dependency;
55  import fr.paris.lutece.plugins.releaser.business.ReleaserUser;
56  import fr.paris.lutece.plugins.releaser.business.ReleaserUser.Credential;
57  import fr.paris.lutece.plugins.releaser.business.jaxb.maven.Model;
58  import fr.paris.lutece.plugins.releaser.business.Site;
59  import fr.paris.lutece.plugins.releaser.business.SiteHome;
60  import fr.paris.lutece.plugins.releaser.business.WorkflowReleaseContext;
61  import fr.paris.lutece.plugins.releaser.util.CVSFactoryService;
62  import fr.paris.lutece.plugins.releaser.util.ConstanteUtils;
63  import fr.paris.lutece.plugins.releaser.util.ReleaserUtils;
64  import fr.paris.lutece.plugins.releaser.util.github.GitUtils;
65  import fr.paris.lutece.plugins.releaser.util.pom.PomParser;
66  import fr.paris.lutece.plugins.releaser.util.pom.PomUpdater;
67  import fr.paris.lutece.plugins.releaser.util.version.Version;
68  import fr.paris.lutece.plugins.releaser.util.version.VersionParsingException;
69  import fr.paris.lutece.portal.business.user.AdminUser;
70  import fr.paris.lutece.portal.service.datastore.DatastoreService;
71  import fr.paris.lutece.portal.service.i18n.I18nService;
72  import fr.paris.lutece.portal.service.plugin.Plugin;
73  import fr.paris.lutece.portal.service.rbac.RBACService;
74  import fr.paris.lutece.portal.service.util.AppException;
75  import fr.paris.lutece.portal.service.util.AppLogService;
76  import fr.paris.lutece.portal.service.util.AppPropertiesService;
77  import fr.paris.lutece.util.httpaccess.HttpAccessException;
78  
79  // TODO: Auto-generated Javadoc
80  /**
81   * SiteService.
82   */
83  public class SiteService
84  {
85  
86      /** The Constant NB_POOL_REMOTE_INFORMATION. */
87      private static final int NB_POOL_REMOTE_INFORMATION = 60;
88     
89      /** The Constant MESSAGE_AVOID_SNAPSHOT. */
90      private static final String MESSAGE_AVOID_SNAPSHOT = "releaser.message.avoidSnapshot";
91  
92      /** The Constant MESSAGE_UPGRADE_SELECTED. */
93      private static final String MESSAGE_UPGRADE_SELECTED = "releaser.message.upgradeSelected";
94  
95      /** The Constant MESSAGE_TO_BE_RELEASED. */
96      private static final String MESSAGE_TO_BE_RELEASED = "releaser.message.toBeReleased";
97  
98      /** The Constant MESSAGE_MORE_RECENT_VERSION_AVAILABLE. */
99      private static final String MESSAGE_MORE_RECENT_VERSION_AVAILABLE = "releaser.message.moreRecentVersionAvailable";
100 
101     /** The Constant MESSAGE_AN_RELEASE_VERSION_ALREADY_EXIST. */
102     private static final String MESSAGE_AN_RELEASE_VERSION_ALREADY_EXIST = "releaser.message.releleaseVersionAlreadyExist";
103 
104     /** The Constant MESSAGE_WRONG_POM_PARENT_SITE_VERSION. */
105     private static final String MESSAGE_WRONG_POM_PARENT_SITE_VERSION = "releaser.message.wrongPomParentSiteVersion";
106 
107     /** The Constant MESSAGE_NOT_DEFAULT_RELEASE_BRANCH. */
108     private static final String MESSAGE_NOT_DEFAULT_RELEASE_BRANCH_FROM = "releaser.message.notDefaultReleaseBranchFrom";
109     
110     /** Minimum pom parent version to create docker image. */
111     public static String POM_PARENT_MIN_VERSION_TO_CREATE_DOCKET_IMAGE = AppPropertiesService.getProperty( ConstanteUtils.PROPERTY_POM_PARENT_MIN_VERSION_TO_CREATE_DOCKET_IMAGE );
112 
113 
114     /**
115      * Load a site from its id.
116      *
117      * @param nSiteId
118      *            The site id
119      * @param request
120      *            the request
121      * @param locale
122      *            the locale
123      * @return A site object
124      */
125     public static Site getSite( int nSiteId, HttpServletRequest request, Locale locale )
126     {
127         Site site = SiteHome.findByPrimaryKey( nSiteId );
128         String strPom = null;
129         ReleaserUser user = ReleaserUtils.getReleaserUser( request, locale );
130 
131         if ( user != null )
132         {
133             Credential credential = user.getCredential( site.getRepoType( ) );
134 
135             strPom = CVSFactoryService.getService( site.getRepoType( ) ).fetchPom( site, credential.getLogin( ), credential.getPassword( ) );
136 
137             if ( strPom != null )
138             {
139                 PomParsereleaser/util/pom/PomParser.html#PomParser">PomParser parser = new PomParser( );
140                 parser.parse( site, strPom );
141                 initSite( site, request, locale );                
142             }
143         }
144         else
145         {
146             throw new AppException( ConstanteUtils.ERROR_TYPE_AUTHENTICATION_ERROR );
147         }
148 
149         return site;
150     }
151 
152     /**
153      * Inits the site.
154      *
155      * @param site
156      *            the site
157      * @param request
158      *            the request
159      * @param locale
160      *            the locale
161      */
162     private static void initSite( Site site, HttpServletRequest request, Locale locale )
163     {
164 
165         ReleaserUser user = ReleaserUtils.getReleaserUser( request, locale );
166         Credential credential = user.getCredential( site.getRepoType( ) );
167 
168         // Find last release in the repository
169         String strLastReleaseVersion = CVSFactoryService.getService( site.getRepoType( ) ).getLastRelease( site, credential.getLogin( ),
170                 credential.getPassword( ) );
171         site.setLastReleaseVersion( strLastReleaseVersion );
172 
173         // To find next releases
174 
175         String strOriginVersion = getOriginVersion( strLastReleaseVersion, site.getVersion( ) );
176 
177         site.setNextReleaseVersion( Version.getReleaseVersion( strOriginVersion ) );
178         site.setNextSnapshotVersion( Version.getNextSnapshotVersion( strOriginVersion ) );
179         site.setTargetVersions( Version.getNextReleaseVersions( strOriginVersion, strLastReleaseVersion ) );
180 
181         site.setBranchReleaseFrom( GitUtils.DEFAULT_RELEASE_BRANCH );    
182 		site.setCreateDckerImage(isSiteCreateDockerImage( site ) );        
183         
184         initComponents( site );
185     }
186     
187     public static boolean isSiteCreateDockerImage( Site site )
188     {
189     	try 
190         {
191         	String strPomParentVersion = site.getParentVersion();
192         	
193             if ( strPomParentVersion != null)
194             {
195             	strPomParentVersion.replace("[", "").replace("]", "");
196             	Version vPomParentVersion = Version.parse( strPomParentVersion );
197     			
198     			if (vPomParentVersion.getMajor() >= Integer.valueOf( POM_PARENT_MIN_VERSION_TO_CREATE_DOCKET_IMAGE ) )
199     			{
200     				return true;
201     			}
202             }
203 			
204 		} catch (VersionParsingException e) {
205 			AppLogService.error( e );
206 		}
207     	
208     	return false;
209     }
210         
211     /**
212      * Define which version between last released or current snapshot should be the origin for next release versions. Ex of cases :<br>
213      * last release : 3.2.1 current : 4.0.0-SNAPSHOT -- current <br>
214      * last release : 3.2.1 current : 3.2.2-SNAPSHOT -- last or current <br>
215      * last release : missing current : 1.0.0-SNAPSHOT -- current <br>
216      * last release : 3.2.1-RC-02 current : 3.2.1-SNAPSHOT -- last <br>
217      * 
218      * @param strLastRelease
219      *            The last release
220      * @param strCurrentVersion
221      *            The current release
222      * @return The origin version
223      */
224     public static String getOriginVersion( String strLastRelease, String strCurrentVersion )
225     {
226         String strOriginVersion = strCurrentVersion;
227         if ( ( strLastRelease != null ) && Version.isCandidate( strLastRelease ) )
228         {
229             strOriginVersion = strLastRelease;
230         }
231         return strOriginVersion;
232     }
233 
234     /**
235      * Initialize the component list for a given site.
236      *
237      * @param site
238      *            The site
239      */
240     private static void initComponents( Site site )
241     {
242         for ( Dependency dependency : site.getCurrentDependencies( ) )
243         {        	
244             Componentaser/business/Component.html#Component">Component component = new Component( );
245 
246             component.setIsProject( isProjectComponent( site, dependency.getArtifactId( ) ) );
247             component.setArtifactId( dependency.getArtifactId( ) );
248             component.setGroupId( dependency.getGroupId( ) );
249             component.setType( dependency.getType( ) );
250             if ( dependency.getVersion() == null )
251             {
252             	dependency.setVersion( ConstanteUtils.NO_VERSION_DEFINED_IN_POM );
253             }
254             String currentVersion = dependency.getVersion( ).replace( "[", "" ).replace( "]", "" );
255             component.setCurrentVersion( currentVersion );
256             site.addComponent( component );
257             
258             
259             
260         }
261 
262         ExecutorService executor = Executors.newFixedThreadPool( NB_POOL_REMOTE_INFORMATION );
263 
264         List<Future> futures = new ArrayList<Future>( site.getCurrentDependencies( ).size( ) );
265 
266         for ( Component component : site.getComponents( ) )
267         {
268             futures.add( executor.submit( new GetRemoteInformationsTask( component ) ) );
269         }
270 
271         // wait all futures stop before continue
272         for ( Future future : futures )
273         {
274 
275             try
276             {
277                 future.get( );
278             }
279             catch( InterruptedException e )
280             {
281                 AppLogService.error( e );
282             }
283             catch( ExecutionException e )
284             {
285                 // TODO Auto-generated catch block
286                 AppLogService.error( e );
287             }
288 
289         }
290 
291         executor.shutdown( );
292 
293         for ( Component component : site.getComponents( ) )
294         {
295             ComponentService.getService( ).updateRemoteInformations( component );
296             defineTargetVersion( component );
297             defineNextSnapshotVersion( component );
298             component.setName( ReleaserUtils.getComponentName( component.getScmDeveloperConnection( ), component.getArtifactId( ) ) );
299             component.setBranchReleaseFrom( GitUtils.DEFAULT_RELEASE_BRANCH );
300         }
301 
302     }
303 
304     /**
305      * Define the target version for a given component : <br>
306      * - current version for non project component <br>
307      * - nex release for project component.
308      *
309      * @param component
310      *            The component
311      */
312     private static void defineTargetVersion( Component component )
313     {
314         if ( component.isProject( ) && component.isSnapshotVersion( ) )
315         {
316             if ( component.getLastAvailableVersion( ) != null && !component.getCurrentVersion( ).equals( component.getLastAvailableSnapshotVersion( ) )
317                     || component.isTheme( ) )
318             {
319                 component.setTargetVersion( component.getLastAvailableVersion( ) );
320             }
321             else
322             {
323             	component.setTargetVersions( Version.getNextReleaseVersions( component.getCurrentVersion( ), component.getLastAvailableVersion( ) ) );
324                 String strTargetVersion = Version.getReleaseVersion( component.getCurrentVersion( ) );
325                 component.setTargetVersion( strTargetVersion );
326             }
327         }
328         else
329         {
330             component.setTargetVersion( component.getCurrentVersion( ) );
331         }
332     }
333 
334     /**
335      * Define the next snapshot version for a given component.
336      *
337      * @param component
338      *            The component
339      */
340     private static void defineNextSnapshotVersion( Component component )
341     {
342         String strNextSnapshotVersion = Version.NOT_AVAILABLE;
343         if ( !component.getCurrentVersion( ).equals( component.getLastAvailableSnapshotVersion( ) ) || component.isTheme( ) )
344         {
345             component.setNextSnapshotVersion( component.getLastAvailableSnapshotVersion( ) );
346         }
347         else
348         {
349             try
350             {
351                 Version version = Version.parse( component.getTargetVersion( ) );
352                 boolean bSnapshot = true;
353                 strNextSnapshotVersion = version.nextPatch( bSnapshot ).toString( );
354             }
355             catch( VersionParsingException ex )
356             {
357                 AppLogService.error( "Error parsing version for component " + component.getArtifactId( ) + " : " + ex.getMessage( ), ex );
358 
359             }
360             component.setNextSnapshotVersion( strNextSnapshotVersion );
361         }
362 
363     }
364 
365     /**
366      * Checks if is project component.
367      *
368      * @param site
369      *            the site
370      * @param strArtifactId
371      *            the str artifact id
372      * @return true, if is project component
373      */
374     private static boolean isProjectComponent( Site site, String strArtifactId )
375     {
376         return new Boolean( DatastoreService.getDataValue( getComponetIsProjectDataKey( site, strArtifactId ), Boolean.FALSE.toString( ) ) );
377     }
378 
379     /**
380      * Update component as project status.
381      *
382      * @param site
383      *            the site
384      * @param strArtifactId
385      *            the str artifact id
386      * @param bIsProject
387      *            the b is project
388      */
389     public static void updateComponentAsProjectStatus( Site site, String strArtifactId, Boolean bIsProject )
390     {
391         DatastoreService.setDataValue( getComponetIsProjectDataKey( site, strArtifactId ), bIsProject.toString( ) );
392 
393     }
394 
395     /**
396      * Removes the component as project by site.
397      *
398      * @param nIdSite
399      *            the n id site
400      */
401     public static void removeComponentAsProjectBySite( int nIdSite )
402     {
403         DatastoreService.removeDataByPrefix( getPrefixIsProjectDataKey( nIdSite ) );
404 
405     }
406 
407     /**
408      * Gets the componet is project data key.
409      *
410      * @param site
411      *            the site
412      * @param strArtifactId
413      *            the str artifact id
414      * @return the componet is project data key
415      */
416     private static String getComponetIsProjectDataKey( Site site, String strArtifactId )
417     {
418 
419         return getPrefixIsProjectDataKey( site.getId( ) ) + strArtifactId;
420 
421     }
422 
423     /**
424      * Gets the prefix is project data key.
425      *
426      * @param nIdSite
427      *            the n id site
428      * @return the prefix is project data key
429      */
430     private static String getPrefixIsProjectDataKey( int nIdSite )
431     {
432 
433         return ConstanteUtils.CONSTANTE_COMPONENT_PROJECT_PREFIX + "_" + nIdSite + "_";
434 
435     }
436 
437     /**
438      * Build release comments for a given site.
439      *
440      * @param site
441      *            The site
442      * @param locale
443      *            The locale to use for comments
444      */
445     public static void buildComments( Site site, Locale locale )
446     {
447         site.resetComments( );
448         buildReleaseComments( site, locale );
449 
450         for ( Component component : site.getComponents( ) )
451         {
452             component.resetComments( );
453             buildReleaseComments( component, locale );
454         }
455     }
456 
457     /**
458      * Build release comments for a given component.
459      *
460      * @param component
461      *            The component
462      * @param locale
463      *            The locale to use for comments
464      */
465     private static void buildReleaseComments( Component component, Locale locale )
466     {
467 
468         if ( !component.getBranchReleaseFrom( ).equals( GitUtils.DEFAULT_RELEASE_BRANCH ) )
469         {
470             String strComment = I18nService.getLocalizedString( MESSAGE_NOT_DEFAULT_RELEASE_BRANCH_FROM, locale );
471             component.addReleaseComment( strComment );
472 
473             return;
474         }
475 
476         if ( !component.isProject( ) )
477         {
478             if ( Version.isSnapshot( component.getTargetVersion( ) ) )
479             {
480                 String strComment = I18nService.getLocalizedString( MESSAGE_AVOID_SNAPSHOT, locale );
481                 component.addReleaseComment( strComment );
482             }
483             else
484                 if ( component.getLastAvailableVersion( ) != null && component.getTargetVersion( ) != null && component.getLastAvailableVersion( ) != null
485                         && ReleaserUtils.compareVersion( component.getTargetVersion( ), component.getLastAvailableVersion( ) ) < 0 )
486                 {
487                     String [ ] arguments = {
488                             component.getLastAvailableVersion( )
489                     };
490                     String strComment = I18nService.getLocalizedString( MESSAGE_MORE_RECENT_VERSION_AVAILABLE, arguments, locale );
491 
492                     component.addReleaseComment( strComment );
493                 }
494         }
495         else
496         {
497             if ( component.isSnapshotVersion( ) )
498             {
499                 if ( ReleaserUtils.compareVersion( component.getCurrentVersion( ), component.getLastAvailableSnapshotVersion( ) ) < 0 )
500                 {
501 
502                     String [ ] arguments = {
503                             component.getLastAvailableVersion( )
504                     };
505                     String strComment = I18nService.getLocalizedString( MESSAGE_UPGRADE_SELECTED, arguments, locale );
506                     component.addReleaseComment( strComment );
507                 }
508                 else
509                     if ( !component.shouldBeReleased( ) && !component.isDowngrade( ) )
510                     {
511 
512                         String [ ] arguments = {
513                                 component.getLastAvailableVersion( )
514                         };
515                         String strComment = I18nService.getLocalizedString( MESSAGE_AN_RELEASE_VERSION_ALREADY_EXIST, arguments, locale );
516                         component.addReleaseComment( strComment );
517                     }
518 
519                     else
520                         if ( component.shouldBeReleased( ) )
521                         {
522 
523                             String strComment = I18nService.getLocalizedString( MESSAGE_TO_BE_RELEASED, locale );
524                             component.addReleaseComment( strComment );
525                         }
526             }
527             else
528                 if ( ReleaserUtils.compareVersion( component.getCurrentVersion( ), component.getLastAvailableVersion( ) ) < 0 )
529                 {
530                     String [ ] arguments = {
531                             component.getLastAvailableVersion( )
532                     };
533                     String strComment = I18nService.getLocalizedString( MESSAGE_MORE_RECENT_VERSION_AVAILABLE, arguments, locale );
534 
535                     component.addReleaseComment( strComment );
536                 }
537         }
538     }
539 
540     /**
541      * Upgrade component.
542      *
543      * @param site
544      *            the site
545      * @param strArtifactId
546      *            the str artifact id
547      */
548     public static void upgradeComponent( Site site, String strArtifactId )
549     {
550         for ( Component component : site.getComponents( ) )
551         {
552             if ( component.getArtifactId( ).equals( strArtifactId ) )
553             {
554                 component.setTargetVersion( component.getLastAvailableVersion( ) );
555                 component.setUpgrade( true );
556             }
557         }
558     }
559 
560     /**
561      * Cancel upgrade component.
562      *
563      * @param site
564      *            the site
565      * @param strArtifactId
566      *            the str artifact id
567      */
568     public static void cancelUpgradeComponent( Site site, String strArtifactId )
569     {
570         for ( Component component : site.getComponents( ) )
571         {
572             if ( component.getArtifactId( ).equals( strArtifactId ) )
573             {
574 
575                 component.setTargetVersion( component.getCurrentVersion( ) );
576                 component.setUpgrade( false );
577             }
578         }
579     }
580 
581     /**
582      * Downgrade component.
583      *
584      * @param site
585      *            the site
586      * @param strArtifactId
587      *            the str artifact id
588      */
589     public static void downgradeComponent( Site site, String strArtifactId )
590     {
591         for ( Component component : site.getComponents( ) )
592         {
593             if ( component.getArtifactId( ).equals( strArtifactId ) && component.isSnapshotVersion( ) )
594             {
595                 component.setTargetVersion( component.getLastAvailableVersion( ) );
596                 component.setNextSnapshotVersion( component.getLastAvailableSnapshotVersion( ) );
597                 component.setDowngrade( true );
598             }
599         }
600     }
601 
602     /**
603      * Cancel downgrade component.
604      *
605      * @param site
606      *            the site
607      * @param strArtifactId
608      *            the str artifact id
609      */
610     public static void cancelDowngradeComponent( Site site, String strArtifactId )
611     {
612         for ( Component component : site.getComponents( ) )
613         {
614             if ( component.getArtifactId( ).equals( strArtifactId ) && component.isSnapshotVersion( ) )
615             {
616                 component.setDowngrade( false );
617                 defineTargetVersion( component );
618                 defineNextSnapshotVersion( component );
619             }
620         }
621     }
622 
623     /**
624      * Release component.
625      *
626      * @param site
627      *            the site
628      * @param strArtifactId
629      *            the str artifact id
630      * @param locale
631      *            the locale
632      * @param user
633      *            the user
634      * @param request
635      *            the request
636      * @return the int
637      */
638     public static int releaseComponent( Site site, String strArtifactId, Locale locale, AdminUser user, HttpServletRequest request )
639     {
640         for ( Component component : site.getComponents( ) )
641         {
642             if ( component.getArtifactId( ).equals( strArtifactId ) && component.shouldBeReleased( ) )
643             {
644                 // Release component
645                 return ComponentService.getService( ).release( component, locale, user, request );
646 
647             }
648         }
649         return ConstanteUtils.CONSTANTE_ID_NULL;
650     }
651 
652     /**
653      * Release site.
654      *
655      * @param site
656      *            the site
657      * @param locale
658      *            the locale
659      * @param user
660      *            the user
661      * @param request
662      *            the request
663      * @return the map
664      */
665     public static Map<String, Integer> releaseSite( Site site, Locale locale, AdminUser user, HttpServletRequest request )
666     {
667         Map<String, Integer> mapResultContext = new HashMap<String, Integer>( );
668 
669         Integer nIdWfContext;
670         // Release all snapshot compnent
671         for ( Component component : site.getComponents( ) )
672         {
673             if ( component.isProject( ) && component.shouldBeReleased( ) && !component.isTheme( ) )
674             {
675                 component.setErrorLastRelease( false );
676                 nIdWfContext = ComponentService.getService( ).release( component, locale, user, request );
677                 mapResultContext.put( component.getArtifactId( ), nIdWfContext );
678 
679             }
680         }
681 
682         WorkflowReleaseContext context = new WorkflowReleaseContext( );
683         context.setSite( site );
684         context.setReleaserUser( ReleaserUtils.getReleaserUser( request, locale ) );
685 
686         int nIdWorkflow = WorkflowReleaseContextService.getService( ).getIdWorkflow( context );
687         WorkflowReleaseContextService.getService( ).addWorkflowReleaseContext( context );
688         // start
689         WorkflowReleaseContextService.getService( ).startWorkflowReleaseContext( context, nIdWorkflow, locale, request, user );
690         // Add wf site context
691         mapResultContext.put( site.getArtifactId( ), context.getId( ) );
692 
693         return mapResultContext;
694 
695     }
696 
697     /**
698      * Add or Remove a component from the project's components list.
699      *
700      * @param site
701      *            The site
702      * @param strArtifactId
703      *            The component artifact id
704      */
705     public static void toggleProjectComponent( Site site, String strArtifactId )
706     {
707         for ( Component component : site.getComponents( ) )
708         {
709             if ( component.getArtifactId( ).equals( strArtifactId ) )
710             {
711                 component.setIsProject( !component.isProject( ) );
712                 updateComponentAsProjectStatus( site, strArtifactId, component.isProject( ) );
713 
714                 if ( component.isProject( ) )
715                 {
716                     try
717                     {
718                         ComponentService.getService( ).setRemoteInformations( component, false );
719                     }
720                     catch( HttpAccessException | IOException e )
721                     {
722                         AppLogService.error( e );
723                     }
724                     ComponentService.getService( ).updateRemoteInformations( component );
725                     defineTargetVersion( component );
726                     defineNextSnapshotVersion( component );
727                     component.setName( ReleaserUtils.getComponentName( component.getScmDeveloperConnection( ), component.getArtifactId( ) ) );
728                 }
729 
730             }
731         }
732     }
733 
734     /**
735      * Change the next release version.
736      *
737      * @param site
738      *            The site
739      * @param strArtifactId
740      *            The component artifact id
741      */
742     public static void changeNextReleaseVersion( Site site, String strArtifactId )
743     {
744         for ( Component component : site.getComponents( ) )
745         {
746             if ( component.getArtifactId( ).equals( strArtifactId ) )
747             {
748                 ComponentService.getService( ).changeNextReleaseVersion( component );
749             }
750         }
751     }
752 
753     /**
754      * Change the next release version.
755      *
756      * @param site
757      *            The site
758      */
759     public static void changeNextReleaseVersion( Site site )
760     {
761         List<String> listTargetVersions = site.getTargetVersions( );
762         int nNewIndex = ( site.getTargetVersionIndex( ) + 1 ) % listTargetVersions.size( );
763         String strTargetVersion = listTargetVersions.get( nNewIndex );
764         site.setNextReleaseVersion( strTargetVersion );
765         site.setTargetVersionIndex( nNewIndex );
766         site.setNextSnapshotVersion( Version.getNextSnapshotVersion( strTargetVersion ) );
767     }
768 
769     /**
770      * Generate the pom.xml file for a given site
771      * 
772      * @param site
773      *            The site
774      * @return The pom.xml content
775      */
776     public String generateTargetPOM( Site site )
777     {
778         throw new UnsupportedOperationException( "Not supported yet." ); // To change body of generated methods, choose Tools | Templates.
779     }
780 
781     /**
782      * Builds the release comments.
783      *
784      * @param site
785      *            the site
786      * @param locale
787      *            the locale
788      */
789     private static void buildReleaseComments( Site site, Locale locale )
790     {
791 
792         if ( !site.isTheme( ) )
793         {
794             // Check pom
795             InputStream inputStream = null;
796             String strPomPath = ReleaserUtils.getLocalSitePomPath( site );
797             String strPomParentReferenceVersion = AppPropertiesService.getProperty( ConstanteUtils.PROPERTY_POM_PARENT_SITE_VERSION );
798             try
799             {
800 
801                 inputStream = new FileInputStream( strPomPath );
802                 Model model = PomUpdater.unmarshal( Model.class, inputStream );
803                 String strParentSiteVersion = model.getParent( ).getVersion( );
804                 if ( ReleaserUtils.compareVersion( strParentSiteVersion, strPomParentReferenceVersion ) < 0 )
805                 {
806                     String [ ] arguments = {
807                             strPomParentReferenceVersion
808                     };
809                     String strComment = I18nService.getLocalizedString( MESSAGE_WRONG_POM_PARENT_SITE_VERSION, arguments, locale );
810                     site.addReleaseComment( strComment );
811                 }
812 
813             }
814             catch( FileNotFoundException e )
815             {
816                 AppLogService.error( e );
817             }
818             catch( JAXBException e )
819             {
820                 // TODO Auto-generated catch block
821                 AppLogService.error( e );
822             }
823         }
824 
825     }
826 
827     public static List<Site> getAuthorizedSites( int clusterId, AdminUser adminUser )
828     {
829 
830         List<Site> listAuthorizedSites = new ArrayList<Site>( );
831 
832         List<Site> listSite = SiteHome.findByCluster( clusterId );
833 
834         // Assign site's permissions
835         for ( Site site : listSite )
836         {
837             boolean bAutoriseViewSite = false;
838 
839             HashMap<String, Boolean> sitePermissions = new HashMap<String, Boolean>( );
840 
841             // Release site permission
842             if ( RBACService.isAuthorized( Site.RESOURCE_TYPE, site.getResourceId( ), SiteResourceIdService.PERMISSION_RELEASE, adminUser ) )
843             {
844                 sitePermissions.put( Site.PERMISSION_RELEASE_SITE, true );
845                 bAutoriseViewSite = true;
846             }
847             else
848             {
849                 sitePermissions.put( Site.PERMISSION_RELEASE_SITE, false );
850             }
851 
852             // Modify site permission
853             if ( RBACService.isAuthorized( Site.RESOURCE_TYPE, site.getResourceId( ), SiteResourceIdService.PERMISSION_MODIFY, adminUser ) )
854             {
855                 sitePermissions.put( Site.PERMISSION_MODIFY_SITE, true );
856                 bAutoriseViewSite = true;
857             }
858             else
859             {
860                 sitePermissions.put( Site.PERMISSION_MODIFY_SITE, false );
861             }
862 
863             // Delete site permission
864             if ( RBACService.isAuthorized( Site.RESOURCE_TYPE, site.getResourceId( ), SiteResourceIdService.PERMISSION_DELETE, adminUser ) )
865             {
866                 sitePermissions.put( Site.PERMISSION_DELETE_SITE, true );
867                 bAutoriseViewSite = true;
868             }
869             else
870             {
871                 sitePermissions.put( Site.PERMISSION_DELETE_SITE, false );
872             }
873 
874             // Set permissions
875             if ( bAutoriseViewSite )
876             {
877                 // Add permissions to the site
878                 site.setPermissions( sitePermissions );
879 
880                 // Add the site to list of Authorized sites
881                 listAuthorizedSites.add( site );
882             }
883         }
884 
885         return listAuthorizedSites;
886     }
887 
888     public static boolean IsUserAuthorized( AdminUser adminUser, String siteId, String permission )
889     {
890 
891         boolean bAuthorized = false;
892 
893         if ( RBACService.isAuthorized( Site.RESOURCE_TYPE, siteId, permission, adminUser ) )
894         {
895             bAuthorized = true;
896         }
897 
898         return bAuthorized;
899     }
900 
901     public static boolean IsSiteAlreadyExist( String siteName, String artifactId, String scmUrl )
902     {
903         String clusterName = SiteHome.findDuplicateSite( siteName, artifactId, scmUrl );
904         if ( clusterName != null )
905             return true;
906 
907         return false;
908     }
909 
910 }