3939import org .slf4j .LoggerFactory ;
4040
4141import org .springframework .boot .web .client .RestTemplateBuilder ;
42- import org .springframework .cache .annotation .Cacheable ;
4342import org .springframework .core .ParameterizedTypeReference ;
4443import org .springframework .http .HttpStatusCode ;
4544import org .springframework .http .MediaType ;
@@ -59,9 +58,6 @@ public class GithubOperations {
5958 private static final TypeReference <@ NotNull List <ProjectDocumentation >> DOCUMENTATION_LIST = new TypeReference <>() {
6059 };
6160
62- private static final TypeReference <List <ProjectSupport >> SUPPORT_LIST = new TypeReference <>() {
63- };
64-
6561 private static final String GITHUB_URI = "https://api.github.com/repos/spring-io/spring-website-content/contents" ;
6662
6763 private static final Comparator <ProjectDocumentation > VERSION_COMPARATOR = GithubOperations ::compare ;
@@ -78,8 +74,6 @@ public class GithubOperations {
7874
7975 private static final String CONFIG_COMMIT_MESSAGE = "Update Spring Boot Config" ;
8076
81- private static final String DEFAULT_SUPPORT_POLICY = "UPSTREAM" ;
82-
8377 private static final ParameterizedTypeReference <Map <String , Object >> STRING_OBJECT_MAP = new ParameterizedTypeReference <>() {
8478 };
8579
@@ -121,11 +115,19 @@ public void addProjectDocumentation(String projectSlug, ProjectDocumentation doc
121115 updateProjectDocumentation (projectSlug , updatedDocumentation , sha );
122116 }
123117
124- @ NotNull
125118 private List <ProjectDocumentation > convertToProjectDocumentation (String content ) {
126119 return readValue (content , DOCUMENTATION_LIST );
127120 }
128121
122+ private <T > T readValue (String contents , TypeReference <T > type ) {
123+ try {
124+ return this .objectMapper .readValue (contents , type );
125+ }
126+ catch (JsonProcessingException ex ) {
127+ throw new RuntimeException (ex );
128+ }
129+ }
130+
129131 private void updateProjectDocumentation (String projectSlug , List <ProjectDocumentation > documentations , String sha ) {
130132 try {
131133 byte [] content = this .objectMapper .writer (this .prettyPrinter ).writeValueAsBytes (documentations );
@@ -140,14 +142,14 @@ public void patchProjectDetails(String projectSlug, ProjectDetails projectDetail
140142 throwIfProjectDoesNotExist (projectSlug );
141143 if (projectDetails .getSpringBootConfig () != null ) {
142144 ResponseEntity <Map <String , Object >> response = getFile (projectSlug , "springBootConfig.md" );
143- NoSuchGithubFileFoundException .throwWhenFileNotFound (response , projectSlug , "documentation.json " );
145+ NoSuchGithubFileFoundException .throwWhenFileNotFound (response , projectSlug , "springBootConfig.md " );
144146 String sha = getFileSha (response );
145147 updateContents (projectDetails .getSpringBootConfig ().getBytes (), sha , projectSlug , "springBootConfig.md" ,
146148 CONFIG_COMMIT_MESSAGE );
147149 }
148150 if (projectDetails .getBody () != null ) {
149151 ResponseEntity <Map <String , Object >> response = getFile (projectSlug , "index.md" );
150- NoSuchGithubFileFoundException .throwWhenFileNotFound (response , projectSlug , "documentation.json " );
152+ NoSuchGithubFileFoundException .throwWhenFileNotFound (response , projectSlug , "index.md " );
151153 String contents = getFileContents (response );
152154 String sha = getFileSha (response );
153155 String updatedContent = MarkdownUtils .getUpdatedContent (contents , projectDetails .getBody ());
@@ -218,9 +220,9 @@ private ResponseEntity<Map<String, Object>> getFile(String projectSlug, String f
218220 return this .restTemplate .exchange (request , STRING_OBJECT_MAP );
219221 }
220222 catch (HttpClientErrorException ex ) {
221- logger .info ("*** Exception thrown for " + projectSlug + " and file " + fileName + " due to "
222- + ex .getMessage () + " with status " + ex .getStatusCode ());
223223 HttpStatusCode statusCode = ex .getStatusCode ();
224+ logger .debug ("Failed to get file " + fileName + " for project " + projectSlug + " due to " + ex .getMessage ()
225+ + " with status " + statusCode );
224226 if (statusCode .value () == 404 ) {
225227 throwIfProjectDoesNotExist (projectSlug );
226228 return null ;
@@ -253,83 +255,4 @@ private String getFileSha(ResponseEntity<Map<String, Object>> exchange) {
253255 return (String ) exchange .getBody ().get ("sha" );
254256 }
255257
256- @ Cacheable ("projects" )
257- public List <Project > getProjects () {
258- List <Project > projects = new ArrayList <>();
259- try {
260- RequestEntity <Void > request = RequestEntity .get ("/project?ref=" + this .branch ).build ();
261- ResponseEntity <List <Map <String , Object >>> exchange = this .restTemplate .exchange (request ,
262- STRING_OBJECT_MAP_LIST );
263- InvalidGithubResponseException .throwIfInvalid (exchange );
264- List <Map <String , Object >> body = exchange .getBody ();
265- body .forEach ((project ) -> {
266- String projectSlug = (String ) project .get ("name" );
267- try {
268- Project fetchedProject = getProject (projectSlug );
269- if (fetchedProject != null ) {
270- projects .add (fetchedProject );
271- }
272- }
273- catch (Exception ex ) {
274- // Ignore project without an index file
275- }
276- });
277- }
278- catch (HttpClientErrorException ex ) {
279- // Return empty list
280- }
281- return List .copyOf (projects );
282- }
283-
284- public Project getProject (String projectSlug ) {
285- ResponseEntity <Map <String , Object >> response = getFile (projectSlug , "index.md" );
286- if (response == null ) {
287- return null ;
288- }
289- String contents = getFileContents (response );
290- Map <String , String > frontMatter = MarkdownUtils .getFrontMatter (contents );
291- InvalidGithubProjectIndexException .throwIfInvalid (Objects ::nonNull , frontMatter , projectSlug );
292- frontMatter .put ("slug" , projectSlug );
293- return this .objectMapper .convertValue (frontMatter , Project .class );
294- }
295-
296- public List <ProjectDocumentation > getProjectDocumentations (String projectSlug ) {
297- ResponseEntity <Map <String , Object >> response = getFile (projectSlug , "documentation.json" );
298- if (response == null ) {
299- return Collections .emptyList ();
300- }
301- String content = getFileContents (response );
302- return List .copyOf (convertToProjectDocumentation (content ));
303- }
304-
305- public List <ProjectSupport > getProjectSupports (String projectSlug ) {
306- ResponseEntity <Map <String , Object >> response = getFile (projectSlug , "support.json" );
307- if (response == null ) {
308- return Collections .emptyList ();
309- }
310- String contents = getFileContents (response );
311- return List .copyOf (readValue (contents , SUPPORT_LIST ));
312- }
313-
314- private <T > T readValue (String contents , TypeReference <T > type ) {
315- try {
316- return this .objectMapper .readValue (contents , type );
317- }
318- catch (JsonProcessingException ex ) {
319- throw new RuntimeException (ex );
320- }
321- }
322-
323- public String getProjectSupportPolicy (String projectSlug ) {
324- ResponseEntity <Map <String , Object >> indexResponse = getFile (projectSlug , "index.md" );
325- if (indexResponse == null ) {
326- return DEFAULT_SUPPORT_POLICY ;
327- }
328- String indexContents = getFileContents (indexResponse );
329- Map <String , String > frontMatter = MarkdownUtils .getFrontMatter (indexContents );
330- InvalidGithubProjectIndexException .throwIfInvalid (Objects ::nonNull , frontMatter , projectSlug );
331- String supportPolicy = frontMatter .get ("supportPolicy" );
332- return (supportPolicy != null ) ? supportPolicy : DEFAULT_SUPPORT_POLICY ;
333- }
334-
335258}
0 commit comments