Make it configurable which mime types should be handled as project doc
At the moment it is hard-coded that "*.md" files are handled as
Markdown project documentation. Instead one can now define in the
global plugin configuration which mime types should be handled by the
Markdown formatter:
[formatter "MARKDOWN"]
mimeType = text/x-markdown
A mapping from file extensions to mime types already exists and
doesn't need to be reimplemented, instead just rely on the mime type.
Multiple mime types may be specified for a formatter. A formatter for
which no mime type is specified is disabled.
An init step creates the basic plugin configuration so that the
default mime type for a formatter is automatically set.
At the moment there is only a single formatter, the formatter for
Markdown, but follow-up changes will add formatters for other
syntaxes, such as Asciidoc.
Change-Id: I0f89463f89baaac962876a166e72ff8e26865280
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/BUCK b/BUCK
index 7a43f6f..339a27c 100644
--- a/BUCK
+++ b/BUCK
@@ -10,6 +10,7 @@
'Gerrit-ApiVersion: 2.11-SNAPSHOT',
'Gerrit-HttpModule: com.googlesource.gerrit.plugins.xdocs.HttpModule',
'Gerrit-Module: com.googlesource.gerrit.plugins.xdocs.Module',
+ 'Gerrit-InitStep: com.googlesource.gerrit.plugins.xdocs.XDocInit',
],
)
diff --git a/pom.xml b/pom.xml
index 9d7d24c..6776eb4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,6 +41,7 @@
<Gerrit-PluginName>xdocs</Gerrit-PluginName>
<Gerrit-HttpModule>com.googlesource.gerrit.plugins.xdocs.HttpModule</Gerrit-HttpModule>
<Gerrit-Module>com.googlesource.gerrit.plugins.xdocs.Module</Gerrit-Module>
+ <Gerrit-InitStep>com.googlesource.gerrit.plugins.xdocs.XDocInit</Gerrit-InitStep>
<Implementation-Vendor>Gerrit Code Review</Implementation-Vendor>
<Implementation-URL>http://code.google.com/p/gerrit/</Implementation-URL>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocFileWebLink.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocFileWebLink.java
index 32fb4e0..cd5d676 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocFileWebLink.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocFileWebLink.java
@@ -18,6 +18,8 @@
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.webui.FileWebLink;
import com.google.gerrit.httpd.resources.Resource;
+import com.google.gerrit.server.FileTypeRegistry;
+import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectCache;
import com.google.inject.Inject;
@@ -31,8 +33,11 @@
GitRepositoryManager repoManager,
@Named(XDocLoader.Module.X_DOC_RESOURCES) LoadingCache<String, Resource> cache,
XDocProjectConfig.Factory cfgFactory,
- ProjectCache projectCache) {
- super(pluginName, repoManager, cache, cfgFactory, projectCache);
+ ProjectCache projectCache,
+ FileTypeRegistry fileTypeRegistry,
+ PluginConfigFactory pluginCfgFactory) {
+ super(pluginName, repoManager, cache, cfgFactory, projectCache,
+ fileTypeRegistry, pluginCfgFactory);
}
@Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocGlobalConfig.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocGlobalConfig.java
index df6ff5a..062a683 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocGlobalConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocGlobalConfig.java
@@ -14,11 +14,17 @@
package com.googlesource.gerrit.plugins.xdocs;
+import eu.medsea.mimeutil.MimeType;
+
import org.eclipse.jgit.lib.Config;
+import java.util.HashMap;
+import java.util.Map;
+
public class XDocGlobalConfig {
private static final String SECTION_FORMATTER = "formatter";
private static final String KEY_ALLOW_HTML = "allowHtml";
+ private static final String KEY_MIME_TYPE = "mimeType";
enum Formatter {
MARKDOWN;
@@ -34,4 +40,20 @@
return cfg.getBoolean(SECTION_FORMATTER, formatter.name(),
KEY_ALLOW_HTML, false);
}
+
+ Map<MimeType, Formatter> getMimeTypes() {
+ Map<MimeType, Formatter> mimeTypes = new HashMap<>();
+ for (Formatter f : Formatter.values()) {
+ for (String mimeType :
+ cfg.getStringList(SECTION_FORMATTER, f.name(), KEY_MIME_TYPE)) {
+ mimeTypes.put(new MimeType(mimeType), f);
+ }
+ }
+ return mimeTypes;
+ }
+
+ static void initialize(Config cfg) {
+ cfg.setString(SECTION_FORMATTER, Formatter.MARKDOWN.name(), KEY_MIME_TYPE,
+ "text/x-markdown");
+ }
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocInit.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocInit.java
new file mode 100644
index 0000000..25cd2a2
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocInit.java
@@ -0,0 +1,62 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.xdocs;
+
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.pgm.init.api.ConsoleUI;
+import com.google.gerrit.pgm.init.api.InitStep;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
+
+import java.io.File;
+
+@Singleton
+public class XDocInit implements InitStep {
+ private final String pluginName;
+ private final SitePaths sitePaths;
+ private final ConsoleUI ui;
+
+ @Inject
+ XDocInit(@PluginName String pluginName, SitePaths sitePaths,
+ ConsoleUI ui) {
+ this.pluginName = pluginName;
+ this.sitePaths = sitePaths;
+ this.ui = ui;
+ }
+
+ @Override
+ public void run() throws Exception {
+ File pluginConfig = new File(sitePaths.etc_dir, pluginName + ".config");
+ if (!pluginConfig.exists()) {
+ ui.message("\n");
+ ui.header("%s plugin", pluginName);
+
+ FileBasedConfig cfg = new FileBasedConfig(pluginConfig, FS.DETECTED);
+ XDocGlobalConfig.initialize(cfg);
+ cfg.save();
+
+ ui.message("Initialized %s plugin: %s", pluginName,
+ pluginConfig.getAbsolutePath());
+ }
+ }
+
+ @Override
+ public void postRun() throws Exception {
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocServlet.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocServlet.java
index ab56e70..c01cd8b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocServlet.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocServlet.java
@@ -22,6 +22,7 @@
import com.google.common.cache.LoadingCache;
import com.google.common.hash.Hashing;
import com.google.common.net.HttpHeaders;
+import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
@@ -30,6 +31,7 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.FileTypeRegistry;
+import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.GetHead;
import com.google.gerrit.server.project.NoSuchProjectException;
@@ -43,6 +45,8 @@
import com.google.inject.Singleton;
import com.google.inject.name.Named;
+import com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.Formatter;
+
import eu.medsea.mimeutil.MimeType;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
@@ -58,6 +62,7 @@
import org.eclipse.jgit.treewalk.filter.PathFilter;
import java.io.IOException;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServlet;
@@ -78,6 +83,8 @@
private final LoadingCache<String, Resource> docCache;
private final FileTypeRegistry fileTypeRegistry;
private final XDocProjectConfig.Factory cfgFactory;
+ private final String pluginName;
+ private final PluginConfigFactory pluginCfgFactory;
@Inject
XDocServlet(
@@ -88,7 +95,9 @@
GitRepositoryManager repoManager,
@Named(XDocLoader.Module.X_DOC_RESOURCES) LoadingCache<String, Resource> cache,
FileTypeRegistry fileTypeRegistry,
- XDocProjectConfig.Factory cfgFactory) {
+ XDocProjectConfig.Factory cfgFactory,
+ @PluginName String pluginName,
+ PluginConfigFactory pluginCfgFactory) {
this.db = db;
this.projectControlFactory = projectControlFactory;
this.projectCache = projectCache;
@@ -97,6 +106,8 @@
this.docCache = cache;
this.fileTypeRegistry = fileTypeRegistry;
this.cfgFactory = cfgFactory;
+ this.pluginName = pluginName;
+ this.pluginCfgFactory = pluginCfgFactory;
}
@Override
@@ -119,8 +130,11 @@
res.sendRedirect(getRedirectUrl(req, key, cfg));
return;
}
+ XDocGlobalConfig pluginCfg =
+ new XDocGlobalConfig(pluginCfgFactory.getGlobalPluginConfig(pluginName));
MimeType mimeType = fileTypeRegistry.getMimeType(key.file, null);
- if (!key.file.endsWith(".md")
+ Map<MimeType, Formatter> mimeTypes = pluginCfg.getMimeTypes();
+ if (!mimeTypes.keySet().contains(mimeType)
&& !("image".equals(mimeType.getMediaType())
&& fileTypeRegistry.isSafeInline(mimeType))) {
Resource.NOT_FOUND.send(req, res);
@@ -177,7 +191,7 @@
}
Resource rsc;
- if (key.file.endsWith(".md")) {
+ if (mimeTypes.get(mimeType) != null) {
rsc = docCache.getUnchecked(
(new XDocResourceKey(key.project, key.file, revId)).asString());
} else if ("image".equals(mimeType.getMediaType())) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocWebLink.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocWebLink.java
index 1838b0f..e347516 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocWebLink.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocWebLink.java
@@ -21,6 +21,8 @@
import com.google.gerrit.extensions.webui.ProjectWebLink;
import com.google.gerrit.httpd.resources.Resource;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.FileTypeRegistry;
+import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
@@ -28,6 +30,8 @@
import com.google.inject.Singleton;
import com.google.inject.name.Named;
+import eu.medsea.mimeutil.MimeType;
+
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
@@ -46,6 +50,8 @@
private final LoadingCache<String, Resource> docCache;
private final XDocProjectConfig.Factory cfgFactory;
private final ProjectCache projectCache;
+ private final FileTypeRegistry fileTypeRegistry;
+ private final PluginConfigFactory pluginCfgFactory;
@Inject
XDocWebLink(
@@ -53,12 +59,16 @@
GitRepositoryManager repoManager,
@Named(XDocLoader.Module.X_DOC_RESOURCES) LoadingCache<String, Resource> cache,
XDocProjectConfig.Factory cfgFactory,
- ProjectCache projectCache) {
+ ProjectCache projectCache,
+ FileTypeRegistry fileTypeRegistry,
+ PluginConfigFactory pluginCfgFactory) {
this.pluginName = pluginName;
this.repoManager = repoManager;
this.docCache = cache;
this.cfgFactory = cfgFactory;
this.projectCache = projectCache;
+ this.fileTypeRegistry = fileTypeRegistry;
+ this.pluginCfgFactory = pluginCfgFactory;
}
@Override
@@ -84,7 +94,10 @@
public String getPatchUrl(String projectName, String revision,
String fileName) {
- if (!fileName.endsWith(".md")) {
+ XDocGlobalConfig pluginCfg =
+ new XDocGlobalConfig(pluginCfgFactory.getGlobalPluginConfig(pluginName));
+ MimeType mimeType = fileTypeRegistry.getMimeType(fileName, null);
+ if (!pluginCfg.getMimeTypes().keySet().contains(mimeType)) {
return null;
}
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 7b71bf4..3ec161f 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -30,11 +30,20 @@
The global configuration of the @PLUGIN@ plugin is done in the
`$site_path/etc/@PLUGIN@.config` file.
+The plugin contains an init step that creates the initial plugin
+configuration.
+
```
[formatter "MARKDOWN"]
- allowHtml = false
+ mimeType = text/x-markdown
```
+<a id="formatterMimeType">
+formatter.<formatter>.mimeType
+: The mime type of files that you be rendered by this formatter.
+
+ Multiple mime types may be specified for a formatter.
+
<a id="formatterAllowHtml">
formatter.<formatter>.allowHtml
: Whether inline HTML blocks and inline HTML tags are allowed for