View Javadoc
1   /*
2    * Copyright (c) 2002-2020, 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.lutecetools.service;
35  
36  import fr.paris.lutece.plugins.lutecetools.business.Component;
37  import fr.paris.lutece.portal.service.util.AppLogService;
38  import fr.paris.lutece.portal.service.util.AppPropertiesService;
39  import java.io.IOException;
40  import java.util.HashMap;
41  import java.util.List;
42  import java.util.Map;
43  import org.gitlab.api.GitlabAPI;
44  import org.gitlab.api.models.GitlabProject;
45  
46  /**
47   * GitlabService
48   */
49  public class GitLabService extends AbstractGitPlatformService
50  {
51  
52      private static final String SERVICE_NAME = "Gitlab Info filler service";
53      private static final String PROPERTY_GITLAB_URL = "lutecetools.gitlab.url";
54      private static final String PROPERTY_GITLAB_ACCOUNT_TOKEN = "lutecetools.gitlab.account.token";
55  
56      private static final String SITE_INDEX_PATH_PART1 = "/raw/develop/src/site/";
57      private static final String SITE_INDEX_PATH_PART2 = "xdoc/index.xml";
58  
59      private static Map<String, GitlabProject> _mapRepositories;
60  
61      /**
62       * {@inheritDoc }
63       */
64      @Override
65      public String getName( )
66      {
67          return SERVICE_NAME;
68      }
69  
70      /**
71       * {@inheritDoc }
72       */
73      @Override
74      public void fill( Component component, StringBuilder sbLogs )
75      {
76          String strRepository = getGitLabRepository( component );
77          if ( strRepository != null )
78          {
79              GitlabProject project = _mapRepositories.get( strRepository );
80              component.set( Component.IS_GIT_REPO, true );
81              component.set( GIT_PLATFORM, getGitPlatform( ) );
82              component.set( GIT_GROUP, getGroup( project ) );
83  
84              component.set( GIT_REPO_STATUS, 4 ); // FIXME 4 = OK
85              component.set( GIT_REPO_ERRORS, "" );
86              component.set( HAS_README, false );
87  
88              incrementItemCount( );
89              incrementItemOk( );
90  
91              fillSiteInfos( component, sbLogs );
92          }
93  
94      }
95  
96      private static String getGitLabRepository( Component component )
97      {
98          try
99          {
100             if ( _mapRepositories == null )
101             {
102                 _mapRepositories = getRepositories( );
103             }
104             for ( String strRepository : _mapRepositories.keySet( ) )
105             {
106                 if ( strRepository.endsWith( component.getArtifactId( ) ) )
107                 {
108                     return strRepository;
109                 }
110             }
111 
112         }
113         catch ( IOException ex )
114         {
115             AppLogService.error( "GitlabService - Error getting repositories : " + ex.getMessage( ), ex );
116         }
117         return null;
118 
119     }
120 
121     /**
122      * Fetch all repositories hosted by the platform
123      * 
124      * @return The repositories map
125      * @throws IOException if an error occurs
126      */
127     public static Map<String, GitlabProject> getRepositories( ) throws IOException
128     {
129         String strUrl = AppPropertiesService.getProperty( PROPERTY_GITLAB_URL );
130         String strToken = AppPropertiesService.getProperty( PROPERTY_GITLAB_ACCOUNT_TOKEN );
131         GitlabAPI gitLabApi = GitlabAPI.connect( strUrl, strToken );
132         List<GitlabProject> listProjects = gitLabApi.getProjects( );
133         AppLogService.debug( "GitlabService - fetching Gitlab repositories " + listProjects.size( ) );
134         Map<String, GitlabProject> mapRepositories = new HashMap<>( );
135         for ( GitlabProject project : listProjects )
136         {
137             String strGroup = getGroup( project );
138             AppLogService
139                     .debug( "GitlabService - fetching repository : " + project.getName( ) + " group : " + strGroup );
140             mapRepositories.put( project.getName( ), project );
141         }
142         return mapRepositories;
143     }
144 
145     /**
146      * Gets the group from a given GitLab project
147      * 
148      * @param project The project
149      * @return The group
150      */
151     static String getGroup( GitlabProject project )
152     {
153         String strNameWithNamespace = project.getNameWithNamespace( );
154 
155         int nPos = strNameWithNamespace.indexOf( '/' );
156         if ( nPos > 0 )
157         {
158             return strNameWithNamespace.substring( 0, nPos );
159         }
160         AppLogService.error( "Error no group found for repository : " + strNameWithNamespace );
161 
162         return "";
163     }
164 
165     /**
166      * fill site infos from xdox site index
167      *
168      * @param component The component
169      */
170     private void fillSiteInfos( Component component, StringBuilder sbLogs )
171     {
172         String strScmUrl = component.get( Component.SCM_URL );
173         if ( strScmUrl != null )
174         {
175             if ( strScmUrl.endsWith( ".git" ) )
176             {
177                 strScmUrl = strScmUrl.substring( 0, strScmUrl.length( ) - 4 );
178             }
179 
180             String strXdocSiteIndexUrl = strScmUrl + SITE_INDEX_PATH_PART1 + SITE_INDEX_PATH_PART2;
181             SiteInfoService.instance( ).getSiteInfos( component, strXdocSiteIndexUrl, "en", sbLogs );
182 
183             strXdocSiteIndexUrl = strScmUrl + SITE_INDEX_PATH_PART1 + "fr/" + SITE_INDEX_PATH_PART2;
184             SiteInfoService.instance( ).getSiteInfos( component, strXdocSiteIndexUrl, "fr", sbLogs );
185         }
186     }
187 }