Refactor XDocLoader to make the code better readable and extensible
Change-Id: I8ca57922ea6512d2420bc75143801f7e2ff31e86
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocLoader.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocLoader.java
index 502c1a6..7971096 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocLoader.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocLoader.java
@@ -22,6 +22,8 @@
import com.google.common.cache.Weigher;
import com.google.common.collect.Maps;
import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.httpd.resources.Resource;
import com.google.gerrit.httpd.resources.SmallResource;
import com.google.gerrit.reviewdb.client.Project;
@@ -88,72 +90,118 @@
@Override
public Resource load(String strKey) throws Exception {
XDocResourceKey key = XDocResourceKey.fromString(strKey);
- XDocGlobalConfig cfg =
- new XDocGlobalConfig(cfgFactory.getGlobalPluginConfig(pluginName));
- FormatterProvider formatter = formatters.getByName(key.getFormatter());
- if (formatter == null) {
- return Resource.NOT_FOUND;
- }
- ConfigSection formatterCfg = cfg.getFormatterConfig(formatter.getName());
- Repository repo = repoManager.openRepository(key.getProject());
try {
- RevWalk rw = new RevWalk(repo);
+ FormatterProvider formatter = getFormatter(key.getFormatter());
+ Repository repo = repoManager.openRepository(key.getProject());
try {
- ObjectId revId = key.getRevId();
- if (revId == null) {
- return Resource.NOT_FOUND;
- }
- RevCommit commit = rw.parseCommit(revId);
- RevTree tree = commit.getTree();
- TreeWalk tw = new TreeWalk(repo);
+ RevWalk rw = new RevWalk(repo);
try {
- tw.addTree(tree);
- tw.setRecursive(true);
- tw.setFilter(PathFilter.create(key.getResource()));
- if (!tw.next()) {
- return Resource.NOT_FOUND;
- }
- ObjectId objectId = tw.getObjectId(0);
- ObjectLoader loader = repo.open(objectId);
- ObjectReader reader = repo.newObjectReader();
- String abbrRevId = reader.abbreviate(revId).name();
+ ObjectId revId = checkRevId(key.getRevId());
+ RevCommit commit = rw.parseCommit(revId);
+ RevTree tree = commit.getTree();
+ TreeWalk tw = new TreeWalk(repo);
try {
- String html;
- Formatter f = formatter.get();
- if (f instanceof StringFormatter) {
- byte[] bytes = loader.getBytes(Integer.MAX_VALUE);
- boolean isBinary = RawText.isBinary(bytes);
- if (formatter.getName().equals(Formatters.RAW_FORMATTER) && isBinary) {
- return Resources.METHOD_NOT_ALLOWED;
- }
- String raw = new String(bytes, UTF_8);
- if (!isBinary) {
- raw = replaceMacros(repo, key.getProject(), revId, abbrRevId, raw);
- }
- html = ((StringFormatter) f).format(key.getProject().get(),
- abbrRevId, formatterCfg, raw);
- } else if (f instanceof StreamFormatter) {
- try (InputStream raw = loader.openStream()) {
- html = ((StreamFormatter) f).format(key.getProject().get(),
- abbrRevId, formatterCfg, raw);
- }
- } else {
- log.error(String.format("Unsupported formatter: %s", formatter.getName()));
- return Resource.NOT_FOUND;
+ tw.addTree(tree);
+ tw.setRecursive(true);
+ tw.setFilter(PathFilter.create(key.getResource()));
+ if (!tw.next()) {
+ throw new ResourceNotFoundException();
}
-
+ ObjectId objectId = tw.getObjectId(0);
+ ObjectLoader loader = repo.open(objectId);
+ String html =
+ getHtml(formatter, repo, loader, key.getProject(), revId);
return getAsHtmlResource(html, commit.getCommitTime());
} finally {
- reader.release();
+ tw.release();
}
} finally {
- tw.release();
+ rw.release();
}
} finally {
- rw.release();
+ repo.close();
}
+ } catch (ResourceNotFoundException e) {
+ return Resource.NOT_FOUND;
+ } catch (MethodNotAllowedException e) {
+ return Resources.METHOD_NOT_ALLOWED;
+ }
+ }
+
+ private FormatterProvider getFormatter(String formatterName)
+ throws ResourceNotFoundException {
+ FormatterProvider formatter = formatters.getByName(formatterName);
+ if (formatter == null) {
+ throw new ResourceNotFoundException();
+ }
+ return formatter;
+ }
+
+ private static ObjectId checkRevId(ObjectId revId)
+ throws ResourceNotFoundException {
+ if (revId == null) {
+ throw new ResourceNotFoundException();
+ }
+ return revId;
+ }
+
+ private String getHtml(FormatterProvider formatter, Repository repo,
+ ObjectLoader loader, Project.NameKey project, ObjectId revId)
+ throws MethodNotAllowedException, IOException, GitAPIException,
+ ResourceNotFoundException {
+ Formatter f = formatter.get();
+ if (f instanceof StringFormatter) {
+ return getHtml(formatter.getName(), (StringFormatter) f, repo, loader,
+ project, revId);
+ } else if (f instanceof StreamFormatter) {
+ return getHtml(formatter.getName(), (StreamFormatter) f, repo, loader,
+ project, revId);
+ } else {
+ log.error(String.format("Unsupported formatter: %s", formatter.getName()));
+ throw new ResourceNotFoundException();
+ }
+ }
+
+ private String getHtml(String formatterName, StringFormatter f,
+ Repository repo, ObjectLoader loader, Project.NameKey project,
+ ObjectId revId) throws MethodNotAllowedException, IOException,
+ GitAPIException {
+ byte[] bytes = loader.getBytes(Integer.MAX_VALUE);
+ boolean isBinary = RawText.isBinary(bytes);
+ if (formatterName.equals(Formatters.RAW_FORMATTER) && isBinary) {
+ throw new MethodNotAllowedException();
+ }
+ String raw = new String(bytes, UTF_8);
+ String abbrRevId = getAbbrRevId(repo, revId);
+ if (!isBinary) {
+ raw = replaceMacros(repo, project, revId, abbrRevId, raw);
+ }
+ return f.format(project.get(), abbrRevId,
+ getFormatterConfig(formatterName), raw);
+ }
+
+ private String getHtml(String formatterName, StreamFormatter f,
+ Repository repo, ObjectLoader loader, Project.NameKey project,
+ ObjectId revId) throws IOException {
+ try (InputStream raw = loader.openStream()) {
+ return ((StreamFormatter) f).format(project.get(),
+ getAbbrRevId(repo, revId), getFormatterConfig(formatterName), raw);
+ }
+ }
+
+ private ConfigSection getFormatterConfig(String formatterName) {
+ XDocGlobalConfig cfg =
+ new XDocGlobalConfig(cfgFactory.getGlobalPluginConfig(pluginName));
+ return cfg.getFormatterConfig(formatterName);
+ }
+
+ private static String getAbbrRevId(Repository repo, ObjectId revId)
+ throws IOException {
+ ObjectReader reader = repo.newObjectReader();
+ try {
+ return reader.abbreviate(revId).name();
} finally {
- repo.close();
+ reader.release();
}
}