blob: 468b26ea5ce05a22f5e507e766181350fdc44d9a [file] [log] [blame]
Shawn Pearce45e83752015-02-20 17:59:05 -08001// Copyright 2015 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.gitiles;
Dave Borowitz40255d52016-08-19 16:16:22 -040016
Shawn Pearce45e83752015-02-20 17:59:05 -080017import com.google.gitiles.doc.GitilesMarkdown;
Shawn Pearce47fd6562016-05-28 14:15:15 -070018import com.google.gitiles.doc.MarkdownConfig;
Shawn Pearce45e83752015-02-20 17:59:05 -080019import com.google.gitiles.doc.MarkdownToHtml;
20import com.google.template.soy.data.SanitizedContent;
Dave Borowitz3b744b12016-08-19 16:11:10 -040021import java.io.IOException;
Shawn Pearce45e83752015-02-20 17:59:05 -080022import org.eclipse.jgit.errors.CorruptObjectException;
23import org.eclipse.jgit.errors.IncorrectObjectTypeException;
Shawn Pearce45e83752015-02-20 17:59:05 -080024import org.eclipse.jgit.errors.MissingObjectException;
Shawn Pearce45e83752015-02-20 17:59:05 -080025import org.eclipse.jgit.lib.Constants;
26import org.eclipse.jgit.lib.FileMode;
27import org.eclipse.jgit.lib.ObjectId;
28import org.eclipse.jgit.lib.ObjectReader;
29import org.eclipse.jgit.revwalk.RevTree;
30import org.eclipse.jgit.treewalk.TreeWalk;
Shawn Pearce45e83752015-02-20 17:59:05 -080031import org.slf4j.Logger;
32import org.slf4j.LoggerFactory;
33
Shawn Pearce45e83752015-02-20 17:59:05 -080034class ReadmeHelper {
35 private static final Logger log = LoggerFactory.getLogger(ReadmeHelper.class);
36
37 private final ObjectReader reader;
38 private final GitilesView view;
Shawn Pearce47fd6562016-05-28 14:15:15 -070039 private final MarkdownConfig config;
Shawn Pearce45e83752015-02-20 17:59:05 -080040 private final RevTree rootTree;
Shawn Pearcec68ad0b2016-05-28 16:52:47 -070041 private final String requestUri;
Shawn Pearce45e83752015-02-20 17:59:05 -080042
43 private String readmePath;
44 private ObjectId readmeId;
45
Shawn Pearcec68ad0b2016-05-28 16:52:47 -070046 ReadmeHelper(
47 ObjectReader reader,
48 GitilesView view,
49 MarkdownConfig config,
50 RevTree rootTree,
51 String requestUri) {
Shawn Pearce45e83752015-02-20 17:59:05 -080052 this.reader = reader;
53 this.view = view;
Shawn Pearce47fd6562016-05-28 14:15:15 -070054 this.config = config;
Shawn Pearce45e83752015-02-20 17:59:05 -080055 this.rootTree = rootTree;
Shawn Pearcec68ad0b2016-05-28 16:52:47 -070056 this.requestUri = requestUri;
Shawn Pearce45e83752015-02-20 17:59:05 -080057 }
58
Han-Wen Nienhuysc0200f62016-05-02 17:34:51 +020059 void scanTree(RevTree tree)
60 throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException,
61 IOException {
Shawn Pearce47fd6562016-05-28 14:15:15 -070062 if (config.render) {
David Ostrovsky5685e572016-12-18 15:31:39 +010063 try (TreeWalk tw = new TreeWalk(reader)) {
64 tw.setRecursive(false);
65 tw.addTree(tree);
66 while (tw.next() && !isPresent()) {
67 considerEntry(tw);
68 }
Shawn Pearce45e83752015-02-20 17:59:05 -080069 }
70 }
71 }
72
73 void considerEntry(TreeWalk tw) {
Shawn Pearce47fd6562016-05-28 14:15:15 -070074 if (config.render
Shawn Pearce45e83752015-02-20 17:59:05 -080075 && FileMode.REGULAR_FILE.equals(tw.getRawMode(0))
76 && isReadmeFile(tw.getNameString())) {
77 readmePath = tw.getPathString();
78 readmeId = tw.getObjectId(0);
79 }
80 }
81
82 boolean isPresent() {
83 return readmeId != null;
84 }
85
86 String getPath() {
87 return readmePath;
88 }
89
90 SanitizedContent render() {
91 try {
Shawn Pearce47fd6562016-05-28 14:15:15 -070092 byte[] raw = reader.open(readmeId, Constants.OBJ_BLOB).getCachedBytes(config.inputLimit);
93 return MarkdownToHtml.builder()
94 .setConfig(config)
95 .setGitilesView(view)
Shawn Pearcec68ad0b2016-05-28 16:52:47 -070096 .setRequestUri(requestUri)
Shawn Pearce47fd6562016-05-28 14:15:15 -070097 .setFilePath(readmePath)
98 .setReader(reader)
99 .setRootTree(rootTree)
100 .build()
101 .toSoyHtml(GitilesMarkdown.parse(raw));
Shawn Pearce08e38f22016-05-24 16:40:18 -0700102 } catch (RuntimeException | IOException err) {
103 log.error(
104 String.format(
105 "error rendering %s/%s %s:%s",
Dave Borowitz40255d52016-08-19 16:16:22 -0400106 view.getHostName(), view.getRepositoryName(), view.getRevision(), readmePath),
Shawn Pearce08e38f22016-05-24 16:40:18 -0700107 err);
Shawn Pearce45e83752015-02-20 17:59:05 -0800108 return null;
109 }
110 }
111
112 /** True if the file is the default markdown file to render in tree view. */
113 private static boolean isReadmeFile(String name) {
114 return name.equalsIgnoreCase("README.md");
115 }
116}