| // 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.formatter; |
| |
| import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_ENABLED; |
| import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_EXT; |
| import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_FORMATTER; |
| import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_MIME_TYPE; |
| import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_PREFIX; |
| import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_PRIO; |
| import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.SECTION_FORMATTER; |
| |
| import com.google.gerrit.common.data.PatchScript.FileMode; |
| import com.google.gerrit.extensions.annotations.PluginName; |
| import com.google.gerrit.extensions.registration.DynamicMap; |
| import com.google.gerrit.reviewdb.client.Project; |
| import com.google.gerrit.server.mime.FileTypeRegistry; |
| import com.google.gerrit.server.change.FileContentUtil; |
| import com.google.gerrit.server.config.PluginConfigFactory; |
| import com.google.gerrit.server.project.ProjectCache; |
| import com.google.gerrit.server.project.ProjectState; |
| import com.google.inject.Inject; |
| import com.google.inject.Provider; |
| import com.google.inject.Singleton; |
| |
| import com.googlesource.gerrit.plugins.xdocs.ConfigSection; |
| import com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig; |
| |
| import eu.medsea.mimeutil.MimeType; |
| |
| import org.apache.commons.io.FilenameUtils; |
| import org.eclipse.jgit.lib.Config; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.Map.Entry; |
| |
| @Singleton |
| public class Formatters { |
| private static final Logger log = LoggerFactory.getLogger(Formatters.class); |
| |
| public static final String RAW_FORMATTER = "RAW"; |
| |
| private final String pluginName; |
| private final PluginConfigFactory pluginCfgFactory; |
| private final FileTypeRegistry fileTypeRegistry; |
| private final DynamicMap<Formatter> formatters; |
| private final ProjectCache projectCache; |
| |
| @Inject |
| Formatters( |
| @PluginName String pluginName, |
| PluginConfigFactory pluginCfgFactory, |
| FileTypeRegistry fileTypeRegistry, |
| DynamicMap<Formatter> formatters, |
| ProjectCache projectCache) { |
| this.pluginName = pluginName; |
| this.pluginCfgFactory = pluginCfgFactory; |
| this.fileTypeRegistry = fileTypeRegistry; |
| this.formatters = formatters; |
| this.projectCache = projectCache; |
| } |
| |
| public FormatterProvider get(String projectName, String fileName) { |
| ProjectState project = projectCache.get(new Project.NameKey(projectName)); |
| if (project == null) { |
| return null; |
| } |
| return get(project, fileName); |
| } |
| |
| public FormatterProvider get(ProjectState project, String fileName) { |
| XDocGlobalConfig globalCfg = new XDocGlobalConfig( |
| pluginCfgFactory.getGlobalPluginConfig(pluginName)); |
| MimeType mimeType = fileTypeRegistry.getMimeType(fileName, null); |
| mimeType = new MimeType(FileContentUtil.resolveContentType( |
| project, fileName, FileMode.FILE, mimeType.toString())); |
| String extension = FilenameUtils.getExtension(fileName); |
| FormatterProvider formatter = null; |
| int formatterPrio = 0; |
| for (String pluginName : formatters.plugins()) { |
| for (Entry<String, Provider<Formatter>> e : |
| formatters.byPlugin(pluginName).entrySet()) { |
| if (!globalCfg.getFormatterConfig(e.getKey()) |
| .getBoolean(KEY_ENABLED, true)) { |
| continue; |
| } |
| ConfigSection formatterCfg = getFormatterConfig(e.getKey(), project); |
| String[] prefixes = formatterCfg.getStringList(KEY_PREFIX); |
| if (prefixes.length > 0) { |
| boolean match = false; |
| for (String prefix : prefixes) { |
| if (fileName.startsWith(prefix)) { |
| match = true; |
| break; |
| } |
| } |
| if (!match) { |
| continue; |
| } |
| } |
| for (String mt : formatterCfg.getStringList(KEY_MIME_TYPE)) { |
| MimeType configuredMimeType = new MimeType(mt); |
| if (mimeType.equals(configuredMimeType) |
| || ("*".equals(configuredMimeType.getSubType()) |
| && mimeType.getMediaType().equals(configuredMimeType.getMediaType()))) { |
| int prio = formatterCfg.getInt(KEY_PRIO, 0); |
| if (formatter == null || prio > formatterPrio) { |
| formatter = new FormatterProvider(e.getKey(), e.getValue()); |
| formatterPrio = prio; |
| } |
| } |
| } |
| for (String ext : |
| formatterCfg.getStringList(KEY_EXT)) { |
| if (extension.equals(ext) || "*".equals(ext)) { |
| int prio = formatterCfg.getInt(KEY_PRIO, 0); |
| if (formatter == null || prio > formatterPrio) { |
| formatter = new FormatterProvider(e.getKey(), e.getValue()); |
| formatterPrio = prio; |
| } |
| } |
| } |
| } |
| } |
| return formatter; |
| } |
| |
| public ConfigSection getFormatterConfig(String formatterName, |
| String projectName) { |
| ProjectState project = projectCache.get(new Project.NameKey(projectName)); |
| if (project == null) { |
| return null; |
| } |
| return getFormatterConfig(formatterName, project); |
| } |
| |
| public ConfigSection getFormatterConfig(String formatterName, |
| ProjectState project) { |
| for (ProjectState p : project.tree()) { |
| Config cfg = pluginCfgFactory.getProjectPluginConfig(p, pluginName); |
| if (cfg.getSubsections(SECTION_FORMATTER).contains(formatterName)) { |
| return new XDocGlobalConfig(cfg).getFormatterConfig(formatterName); |
| } |
| } |
| |
| return new XDocGlobalConfig( |
| pluginCfgFactory.getGlobalPluginConfig(pluginName)) |
| .getFormatterConfig(formatterName); |
| } |
| |
| public FormatterProvider getByName(String formatterName) { |
| if (formatterName.equals(RAW_FORMATTER)) { |
| return resolveRawFormatter(); |
| } |
| |
| for (String pluginName : formatters.plugins()) { |
| for (Entry<String, Provider<Formatter>> e : |
| formatters.byPlugin(pluginName).entrySet()) { |
| if (formatterName.equals(e.getKey())) { |
| return new FormatterProvider(formatterName, e.getValue()); |
| } |
| } |
| } |
| return null; |
| } |
| |
| public FormatterProvider getRawFormatter() { |
| return getByName(RAW_FORMATTER); |
| } |
| |
| private FormatterProvider resolveRawFormatter() { |
| XDocGlobalConfig globalCfg = |
| new XDocGlobalConfig(pluginCfgFactory.getGlobalPluginConfig(pluginName)); |
| String formatterName = |
| globalCfg.getFormatterConfig(RAW_FORMATTER) |
| .getString(KEY_FORMATTER, PlainTextFormatter.NAME); |
| if (formatterName.equals(RAW_FORMATTER)) { |
| log.warn(String.format( |
| "%s plugin: Invalid '%s' formatter configuration, '%s' formatter cannot be set to '%s', using '%s' formatter", |
| pluginName, RAW_FORMATTER, RAW_FORMATTER, formatterName, PlainTextFormatter.NAME)); |
| formatterName = PlainTextFormatter.NAME; |
| } |
| FormatterProvider formatter = getByName(formatterName); |
| if (formatter == null) { |
| log.warn(String.format( |
| "%s plugin: Invalid '%s' formatter configuration, formatter '%s' not found, using '%s' formatter", |
| pluginName, RAW_FORMATTER, formatterName, PlainTextFormatter.NAME)); |
| formatter = getByName(PlainTextFormatter.NAME); |
| } |
| return new FormatterProvider(RAW_FORMATTER, formatter.formatter); |
| } |
| |
| public static class FormatterProvider { |
| private final String name; |
| private final Provider<? extends Formatter> formatter; |
| |
| FormatterProvider(String name, Provider<? extends Formatter> formatter) { |
| this.name = name; |
| this.formatter = formatter; |
| } |
| |
| public Formatter get() { |
| return formatter.get(); |
| } |
| |
| public String getName() { |
| return name; |
| } |
| } |
| } |