]> source.dussan.org Git - sonarqube.git/blob
607587950b6c4e9f78fac8350b055d0f2c2011bc
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.scanner.repository.language;
21
22 import com.google.gson.Gson;
23 import java.io.Reader;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.function.Function;
29 import java.util.stream.Collectors;
30 import javax.annotation.CheckForNull;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.sonar.api.Startable;
34 import org.sonar.api.config.Configuration;
35 import org.sonar.api.resources.Languages;
36 import org.sonar.scanner.bootstrap.DefaultScannerWsClient;
37 import org.sonarqube.ws.client.GetRequest;
38
39 /**
40  * Languages repository using {@link Languages}
41  * @since 4.4
42  */
43 public class DefaultLanguagesRepository implements LanguagesRepository, Startable {
44   private static final Logger LOG = LoggerFactory.getLogger(DefaultLanguagesRepository.class);
45   private static final String LANGUAGES_WS_URL = "/api/languages/list";
46   private static final Map<String, String> PROPERTY_FRAGMENT_MAP = Map.of(
47     "js", "javascript",
48     "ts", "typescript",
49     "py", "python",
50     "web", "html"
51   );
52
53   private final Map<String, Language> languages = new HashMap<>();
54   private final DefaultScannerWsClient wsClient;
55   private final Configuration properties;
56
57   public DefaultLanguagesRepository(DefaultScannerWsClient wsClient, Configuration properties) {
58     this.wsClient = wsClient;
59     this.properties = properties;
60   }
61
62   @Override
63   public void start() {
64     GetRequest getRequest = new GetRequest(LANGUAGES_WS_URL);
65     LanguagesWSResponse response;
66     try (Reader reader = wsClient.call(getRequest).contentReader()) {
67       response = new Gson().fromJson(reader, LanguagesWSResponse.class);
68     } catch (Exception e) {
69       throw new IllegalStateException("Fail to parse response of " + LANGUAGES_WS_URL, e);
70     }
71
72     languages.putAll(response.languages.stream()
73       .map(this::populateFileSuffixesAndPatterns)
74       .collect(Collectors.toMap(Language::key, Function.identity())));
75   }
76
77   private Language populateFileSuffixesAndPatterns(SupportedLanguageDto lang) {
78     String propertyFragment = PROPERTY_FRAGMENT_MAP.getOrDefault(lang.getKey(), lang.getKey());
79     lang.setFileSuffixes(properties.getStringArray(String.format("sonar.%s.file.suffixes", propertyFragment)));
80     lang.setFilenamePatterns(properties.getStringArray(String.format("sonar.%s.file.patterns", propertyFragment)));
81     if (lang.filenamePatterns() == null && lang.getFileSuffixes() == null) {
82       LOG.debug("Language '{}' cannot be detected as it has neither suffixes nor patterns.", lang.getName());
83     }
84     return new Language(lang);
85   }
86
87   private String[] getFileSuffixes(String languageKey) {
88     String propName = String.format("sonar.%s.file.suffixes", PROPERTY_FRAGMENT_MAP.getOrDefault(languageKey, languageKey));
89     return properties.getStringArray(propName);
90   }
91
92   /**
93    * Get language.
94    */
95   @Override
96   @CheckForNull
97   public Language get(String languageKey) {
98     return languages.get(languageKey);
99   }
100
101   /**
102    * Get list of all supported languages.
103    */
104   @Override
105   public Collection<Language> all() {
106     return languages.values();
107   }
108
109   @Override
110   public void stop() {
111     // nothing to do
112   }
113
114   private static class LanguagesWSResponse {
115     List<SupportedLanguageDto> languages;
116   }
117
118 }