// Copyright (C) 2012 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.google.gerrit.httpd.plugins;

import static com.google.gerrit.common.FileUtil.lastModified;
import static com.google.gerrit.server.plugins.PluginEntry.ATTR_CHARACTER_ENCODING;
import static com.google.gerrit.server.plugins.PluginEntry.ATTR_CONTENT_TYPE;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.CharMatcher;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.cache.Cache;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.ByteStreams;
import com.google.common.net.HttpHeaders;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.httpd.resources.Resource;
import com.google.gerrit.httpd.resources.ResourceKey;
import com.google.gerrit.httpd.resources.SmallResource;
import com.google.gerrit.httpd.restapi.RestApiServlet;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.documentation.MarkdownFormatter;
import com.google.gerrit.server.mime.MimeUtilFileTypeRegistry;
import com.google.gerrit.server.plugins.Plugin;
import com.google.gerrit.server.plugins.Plugin.ApiType;
import com.google.gerrit.server.plugins.PluginContentScanner;
import com.google.gerrit.server.plugins.PluginEntry;
import com.google.gerrit.server.plugins.PluginsCollection;
import com.google.gerrit.server.plugins.ReloadPluginListener;
import com.google.gerrit.server.plugins.StartPluginListener;
import com.google.gerrit.server.ssh.SshInfo;
import com.google.gerrit.util.http.RequestUtil;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.servlet.GuiceFilter;

import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.jar.Attributes;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.FilterChain;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Singleton
class HttpPluginServlet extends HttpServlet
    implements StartPluginListener, ReloadPluginListener {
  private static final int SMALL_RESOURCE = 128 * 1024;
  private static final long serialVersionUID = 1L;
  private static final Logger log
      = LoggerFactory.getLogger(HttpPluginServlet.class);

  private final MimeUtilFileTypeRegistry mimeUtil;
  private final Provider<String> webUrl;
  private final Cache<ResourceKey, Resource> resourceCache;
  private final String sshHost;
  private final int sshPort;
  private final RestApiServlet managerApi;

  private List<Plugin> pending = new ArrayList<>();
  private ContextMapper wrapper;
  private final ConcurrentMap<String, PluginHolder> plugins
      = Maps.newConcurrentMap();

  @Inject
  HttpPluginServlet(
      MimeUtilFileTypeRegistry mimeUtil,
      @CanonicalWebUrl Provider<String> webUrl,
      @Named(HttpPluginModule.PLUGIN_RESOURCES) Cache<ResourceKey, Resource> cache,
      SshInfo sshInfo,
      RestApiServlet.Globals globals,
      PluginsCollection plugins) {
    this.mimeUtil = mimeUtil;
    this.webUrl = webUrl;
    this.resourceCache = cache;
    this.managerApi = new RestApiServlet(globals, plugins);

    String sshHost = "review.example.com";
    int sshPort = 29418;
    if (!sshInfo.getHostKeys().isEmpty()) {
      String host = sshInfo.getHostKeys().get(0).getHost();
      int c = host.lastIndexOf(':');
      if (0 <= c) {
        sshHost = host.substring(0, c);
        sshPort = Integer.parseInt(host.substring(c + 1));
      } else {
        sshHost = host;
        sshPort = 22;
      }
    }
    this.sshHost = sshHost;
    this.sshPort = sshPort;
  }

  @Override
  public synchronized void init(ServletConfig config) throws ServletException {
    super.init(config);

    wrapper = new ContextMapper(config.getServletContext().getContextPath());
    for (Plugin plugin : pending) {
      install(plugin);
    }
    pending = null;
  }

  @Override
  public synchronized void onStartPlugin(Plugin plugin) {
    if (pending != null) {
      pending.add(plugin);
    } else {
      install(plugin);
    }
  }

  @Override
  public void onReloadPlugin(Plugin oldPlugin, Plugin newPlugin) {
    install(newPlugin);
  }

  private void install(Plugin plugin) {
    GuiceFilter filter = load(plugin);
    final String name = plugin.getName();
    final PluginHolder holder = new PluginHolder(plugin, filter);
    plugin.add(new RegistrationHandle() {
      @Override
      public void remove() {
        plugins.remove(name, holder);
      }
    });
    plugins.put(name, holder);
  }

  private GuiceFilter load(Plugin plugin) {
    if (plugin.getHttpInjector() != null) {
      final String name = plugin.getName();
      final GuiceFilter filter;
      try {
        filter = plugin.getHttpInjector().getInstance(GuiceFilter.class);
      } catch (RuntimeException e) {
        log.warn(String.format("Plugin %s cannot load GuiceFilter", name), e);
        return null;
      }

      try {
        ServletContext ctx =
            PluginServletContext.create(plugin, wrapper.getFullPath(name));
        filter.init(new WrappedFilterConfig(ctx));
      } catch (ServletException e) {
        log.warn(String.format("Plugin %s failed to initialize HTTP", name), e);
        return null;
      }

      plugin.add(new RegistrationHandle() {
        @Override
        public void remove() {
          filter.destroy();
        }
      });
      return filter;
    }
    return null;
  }

  @Override
  public void service(HttpServletRequest req, HttpServletResponse res)
      throws IOException, ServletException {
    List<String> parts = Lists.newArrayList(
      Splitter.on('/').limit(3).omitEmptyStrings()
        .split(Strings.nullToEmpty(RequestUtil.getEncodedPathInfo(req))));

    if (isApiCall(req, parts)) {
      managerApi.service(req, res);
      return;
    }

    String name = parts.get(0);
    final PluginHolder holder = plugins.get(name);
    if (holder == null) {
      CacheHeaders.setNotCacheable(res);
      res.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    HttpServletRequest wr = wrapper.create(req, name);
    FilterChain chain = new FilterChain() {
      @Override
      public void doFilter(ServletRequest req, ServletResponse res)
          throws IOException {
        onDefault(holder, (HttpServletRequest) req, (HttpServletResponse) res);
      }
    };
    if (holder.filter != null) {
      holder.filter.doFilter(wr, res, chain);
    } else {
      chain.doFilter(wr, res);
    }
  }

  private static boolean isApiCall(HttpServletRequest req, List<String> parts) {
    String method = req.getMethod();
    int cnt = parts.size();
    return cnt == 0
        || (cnt == 1 && ("PUT".equals(method) || "DELETE".equals(method)))
        || (cnt == 2 && parts.get(1).startsWith("gerrit~"));
  }

  private void onDefault(PluginHolder holder,
      HttpServletRequest req,
      HttpServletResponse res) throws IOException {
    if (!"GET".equals(req.getMethod()) && !"HEAD".equals(req.getMethod())) {
      CacheHeaders.setNotCacheable(res);
      res.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
      return;
    }

    String pathInfo = RequestUtil.getEncodedPathInfo(req);
    if (pathInfo.length() < 1) {
      Resource.NOT_FOUND.send(req, res);
      return;
    }

    String file = pathInfo.substring(1);
    PluginResourceKey key = PluginResourceKey.create(holder.plugin, file);
    Resource rsc = resourceCache.getIfPresent(key);
    if (rsc != null && req.getHeader(HttpHeaders.IF_MODIFIED_SINCE) == null) {
      rsc.send(req, res);
      return;
    }

    String uri = req.getRequestURI();
    if ("".equals(file)) {
      res.sendRedirect(uri + holder.docPrefix + "index.html");
      return;
    }

    if (file.startsWith(holder.staticPrefix)) {
      if (holder.plugin.getApiType() == ApiType.JS) {
        sendJsPlugin(holder.plugin, key, req, res);
      } else {
        PluginContentScanner scanner = holder.plugin.getContentScanner();
        Optional<PluginEntry> entry = scanner.getEntry(file);
        if (entry.isPresent()) {
          if (hasUpToDateCachedResource(rsc, entry.get().getTime())) {
            rsc.send(req, res);
          } else {
            sendResource(scanner, entry.get(), key, res);
          }
        } else {
          resourceCache.put(key, Resource.NOT_FOUND);
          Resource.NOT_FOUND.send(req, res);
        }
      }
    } else if (file.equals(
        holder.docPrefix.substring(0, holder.docPrefix.length() - 1))) {
      res.sendRedirect(uri + "/index.html");
    } else if (file.startsWith(holder.docPrefix) && file.endsWith("/")) {
      res.sendRedirect(uri + "index.html");
    } else if (file.startsWith(holder.docPrefix)) {
      PluginContentScanner scanner = holder.plugin.getContentScanner();
      Optional<PluginEntry> entry = scanner.getEntry(file);
      if (!entry.isPresent()) {
        entry = findSource(scanner, file);
      }
      if (!entry.isPresent() && file.endsWith("/index.html")) {
        String pfx = file.substring(0, file.length() - "index.html".length());
        long pluginLastModified = lastModified(holder.plugin.getSrcFile());
        if (hasUpToDateCachedResource(rsc, pluginLastModified)) {
          rsc.send(req, res);
        } else {
          sendAutoIndex(scanner, pfx, holder.plugin.getName(), key, res,
              pluginLastModified);
        }
      } else if (entry.isPresent() && entry.get().getName().endsWith(".md")) {
        if (hasUpToDateCachedResource(rsc, entry.get().getTime())) {
          rsc.send(req, res);
        } else {
          sendMarkdownAsHtml(scanner, entry.get(), holder.plugin.getName(),
              key, res);
        }
      } else if (entry.isPresent()) {
        if (hasUpToDateCachedResource(rsc, entry.get().getTime())) {
          rsc.send(req, res);
        } else {
          sendResource(scanner, entry.get(), key, res);
        }
      } else {
        resourceCache.put(key, Resource.NOT_FOUND);
        Resource.NOT_FOUND.send(req, res);
      }
    } else {
      resourceCache.put(key, Resource.NOT_FOUND);
      Resource.NOT_FOUND.send(req, res);
    }
  }

  private boolean hasUpToDateCachedResource(Resource cachedResource, long lastUpdateTime) {
    return cachedResource != null
        && cachedResource.isUnchanged(lastUpdateTime);
  }

  private void appendEntriesSection(PluginContentScanner scanner, List<PluginEntry> entries,
      String sectionTitle, StringBuilder md, String prefix,
      int nameOffset) throws IOException {
    if (!entries.isEmpty()) {
      md.append("## ").append(sectionTitle).append(" ##\n");
      for (PluginEntry entry : entries) {
        String rsrc = entry.getName().substring(prefix.length());
        String entryTitle;
        if (rsrc.endsWith(".html")) {
          entryTitle = rsrc.substring(nameOffset, rsrc.length() - 5).replace('-', ' ');
        } else if (rsrc.endsWith(".md")) {
          entryTitle = extractTitleFromMarkdown(scanner, entry);
          if (Strings.isNullOrEmpty(entryTitle)) {
            entryTitle = rsrc.substring(nameOffset, rsrc.length() - 3).replace('-', ' ');
          }
          rsrc = rsrc.substring(0, rsrc.length() - 3) + ".html";
        } else {
          entryTitle = rsrc.substring(nameOffset).replace('-', ' ');
        }
        md.append(String.format("* [%s](%s)\n", entryTitle, rsrc));
      }
      md.append("\n");
    }
  }

  private void sendAutoIndex(PluginContentScanner scanner,
      final String prefix, final String pluginName,
      PluginResourceKey cacheKey, HttpServletResponse res,long lastModifiedTime)
      throws IOException {
    List<PluginEntry> cmds = new ArrayList<>();
    List<PluginEntry> servlets = new ArrayList<>();
    List<PluginEntry> restApis = new ArrayList<>();
    List<PluginEntry> docs = new ArrayList<>();
    PluginEntry about = null;

    Predicate<PluginEntry> filter = new Predicate<PluginEntry>() {
      @Override
      public boolean apply(PluginEntry entry) {
        String name = entry.getName();
        Optional<Long> size = entry.getSize();
        if (name.startsWith(prefix)
            && (name.endsWith(".md") || name.endsWith(".html"))
            && size.isPresent()) {
          if (size.get() <= 0 || size.get() > SMALL_RESOURCE) {
            log.warn(String.format(
                "Plugin %s: %s omitted from document index. "
                  + "Size %d out of range (0,%d).",
                pluginName,
                name.substring(prefix.length()),
                size.get(),
                SMALL_RESOURCE));
            return false;
          }
          return true;
        }
        return false;
      }
    };

    List<PluginEntry> entries = FluentIterable
        .from(Collections.list(scanner.entries()))
        .filter(filter)
        .toList();
    for (PluginEntry entry: entries) {
      String name = entry.getName().substring(prefix.length());
      if (name.startsWith("cmd-")) {
        cmds.add(entry);
      } else if (name.startsWith("servlet-")) {
        servlets.add(entry);
      } else if (name.startsWith("rest-api-")) {
        restApis.add(entry);
      } else if (name.startsWith("about.")) {
        if (about == null) {
          about = entry;
        } else {
          log.warn(String.format(
              "Plugin %s: Multiple 'about' documents found; using %s",
              pluginName,
              about.getName().substring(prefix.length())));
        }
      } else {
        docs.add(entry);
      }
    }

    Collections.sort(cmds, PluginEntry.COMPARATOR_BY_NAME);
    Collections.sort(docs, PluginEntry.COMPARATOR_BY_NAME);

    StringBuilder md = new StringBuilder();
    md.append(String.format("# Plugin %s #\n", pluginName));
    md.append("\n");
    appendPluginInfoTable(md, scanner.getManifest().getMainAttributes());

    if (about != null) {
      InputStreamReader isr = new InputStreamReader(scanner.getInputStream(about));
      StringBuilder aboutContent = new StringBuilder();
      try (BufferedReader reader = new BufferedReader(isr)) {
        String line;
        while ((line = reader.readLine()) != null) {
          line = line.trim();
          if (line.isEmpty()) {
            aboutContent.append("\n");
          } else {
            aboutContent.append(line).append("\n");
          }
        }
      }

      // Only append the About section if there was anything in it
      if (aboutContent.toString().trim().length() > 0) {
        md.append("## About ##\n");
        md.append("\n").append(aboutContent);
      }
    }

    appendEntriesSection(scanner, docs, "Documentation", md, prefix, 0);
    appendEntriesSection(scanner, servlets, "Servlets", md, prefix, "servlet-".length());
    appendEntriesSection(scanner, restApis, "REST APIs", md, prefix, "rest-api-".length());
    appendEntriesSection(scanner, cmds, "Commands", md, prefix, "cmd-".length());

    sendMarkdownAsHtml(md.toString(), pluginName, cacheKey, res, lastModifiedTime);
  }

  private void sendMarkdownAsHtml(String md, String pluginName,
      PluginResourceKey cacheKey, HttpServletResponse res, long lastModifiedTime)
      throws UnsupportedEncodingException, IOException {
    Map<String, String> macros = new HashMap<>();
    macros.put("PLUGIN", pluginName);
    macros.put("SSH_HOST", sshHost);
    macros.put("SSH_PORT", "" + sshPort);
    String url = webUrl.get();
    if (Strings.isNullOrEmpty(url)) {
      url = "http://review.example.com/";
    }
    macros.put("URL", url);

    Matcher m = Pattern.compile("(\\\\)?@([A-Z_]+)@").matcher(md);
    StringBuffer sb = new StringBuffer();
    while (m.find()) {
      String key = m.group(2);
      String val = macros.get(key);
      if (m.group(1) != null) {
        m.appendReplacement(sb, "@" + key + "@");
      } else if (val != null) {
        m.appendReplacement(sb, val);
      } else {
        m.appendReplacement(sb, "@" + key + "@");
      }
    }
    m.appendTail(sb);

    byte[] html = new MarkdownFormatter()
      .markdownToDocHtml(sb.toString(), UTF_8.name());
    resourceCache.put(cacheKey, new SmallResource(html)
        .setContentType("text/html")
        .setCharacterEncoding(UTF_8.name())
        .setLastModified(lastModifiedTime));
    res.setContentType("text/html");
    res.setCharacterEncoding(UTF_8.name());
    res.setContentLength(html.length);
    res.setDateHeader("Last-Modified", lastModifiedTime);
    res.getOutputStream().write(html);
  }

  private static void appendPluginInfoTable(StringBuilder html, Attributes main) {
    if (main != null) {
      String t = main.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
      String n = main.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
      String v = main.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
      String a = main.getValue("Gerrit-ApiVersion");

      html.append("<table class=\"plugin_info\">");
      if (!Strings.isNullOrEmpty(t)) {
        html.append("<tr><th>Name</th><td>")
            .append(t)
            .append("</td></tr>\n");
      }
      if (!Strings.isNullOrEmpty(n)) {
        html.append("<tr><th>Vendor</th><td>")
            .append(n)
            .append("</td></tr>\n");
      }
      if (!Strings.isNullOrEmpty(v)) {
        html.append("<tr><th>Version</th><td>")
            .append(v)
            .append("</td></tr>\n");
      }
      if (!Strings.isNullOrEmpty(a)) {
        html.append("<tr><th>API Version</th><td>")
            .append(a)
            .append("</td></tr>\n");
      }
      html.append("</table>\n");
    }
  }

  private static String extractTitleFromMarkdown(PluginContentScanner scanner, PluginEntry entry)
        throws IOException {
    String charEnc = null;
    Map<Object, String> atts = entry.getAttrs();
    if (atts != null) {
      charEnc = Strings.emptyToNull(atts.get(ATTR_CHARACTER_ENCODING));
    }
    if (charEnc == null) {
      charEnc = UTF_8.name();
    }
    return new MarkdownFormatter().extractTitleFromMarkdown(
          readWholeEntry(scanner, entry),
          charEnc);
  }

  private static Optional<PluginEntry> findSource(
      PluginContentScanner scanner, String file) throws IOException {
    if (file.endsWith(".html")) {
      int d = file.lastIndexOf('.');
      return scanner.getEntry(file.substring(0, d) + ".md");
    }
    return Optional.absent();
  }

  private void sendMarkdownAsHtml(PluginContentScanner scanner, PluginEntry entry,
      String pluginName, PluginResourceKey key, HttpServletResponse res)
      throws IOException {
    byte[] rawmd = readWholeEntry(scanner, entry);
    String encoding = null;
    Map<Object, String> atts = entry.getAttrs();
    if (atts != null) {
      encoding = Strings.emptyToNull(atts.get(ATTR_CHARACTER_ENCODING));
    }

    String txtmd = RawParseUtils.decode(
        Charset.forName(encoding != null ? encoding : UTF_8.name()),
        rawmd);
    long time = entry.getTime();
    if (0 < time) {
      res.setDateHeader("Last-Modified", time);
    }
    sendMarkdownAsHtml(txtmd, pluginName, key, res, time);
  }

  private void sendResource(PluginContentScanner scanner, PluginEntry entry,
      PluginResourceKey key, HttpServletResponse res)
      throws IOException {
    byte[] data = null;
    Optional<Long> size = entry.getSize();
    if (size.isPresent() && size.get() <= SMALL_RESOURCE) {
      data = readWholeEntry(scanner, entry);
    }

    String contentType = null;
    String charEnc = null;
    Map<Object, String> atts = entry.getAttrs();
    if (atts != null) {
      contentType = Strings.emptyToNull(atts.get(ATTR_CONTENT_TYPE));
      charEnc = Strings.emptyToNull(atts.get(ATTR_CHARACTER_ENCODING));
    }
    if (contentType == null) {
      contentType = mimeUtil.getMimeType(entry.getName(), data).toString();
      if ("application/octet-stream".equals(contentType)
          && entry.getName().endsWith(".js")) {
        contentType = "application/javascript";
      } else if ("application/x-pointplus".equals(contentType)
          && entry.getName().endsWith(".css")) {
        contentType = "text/css";
      }
    }

    long time = entry.getTime();
    if (0 < time) {
      res.setDateHeader("Last-Modified", time);
    }
    if (size.isPresent()) {
      res.setHeader("Content-Length", size.get().toString());
    }
    res.setContentType(contentType);
    if (charEnc != null) {
      res.setCharacterEncoding(charEnc);
    }
    if (data != null) {
      resourceCache.put(key, new SmallResource(data)
          .setContentType(contentType)
          .setCharacterEncoding(charEnc)
          .setLastModified(time));
      res.getOutputStream().write(data);
    } else {
      writeToResponse(res, scanner.getInputStream(entry));
    }
  }

  private void sendJsPlugin(Plugin plugin, PluginResourceKey key,
      HttpServletRequest req, HttpServletResponse res) throws IOException {
    Path path = plugin.getSrcFile();
    if (req.getRequestURI().endsWith(getJsPluginPath(plugin))
        && Files.exists(path)) {
      res.setHeader("Content-Length", Long.toString(Files.size(path)));
      res.setContentType("application/javascript");
      writeToResponse(res, Files.newInputStream(path));
    } else {
      resourceCache.put(key, Resource.NOT_FOUND);
      Resource.NOT_FOUND.send(req, res);
    }
  }

  private static String getJsPluginPath(Plugin plugin) {
    return String.format("/plugins/%s/static/%s", plugin.getName(),
        plugin.getSrcFile().getFileName());
  }

  private void writeToResponse(HttpServletResponse res, InputStream inputStream)
      throws IOException {
    try (OutputStream out = res.getOutputStream();
        InputStream in = inputStream) {
      ByteStreams.copy(in, out);
    }
  }

  private static byte[] readWholeEntry(PluginContentScanner scanner, PluginEntry entry)
      throws IOException {
    try (InputStream in = scanner.getInputStream(entry)) {
      return IO.readWholeStream(in, entry.getSize().get().intValue()).array();
    }
  }

  private static class PluginHolder {
    final Plugin plugin;
    final GuiceFilter filter;
    final String staticPrefix;
    final String docPrefix;

    PluginHolder(Plugin plugin, GuiceFilter filter) {
      this.plugin = plugin;
      this.filter = filter;
      this.staticPrefix =
        getPrefix(plugin, "Gerrit-HttpStaticPrefix", "static/");
      this.docPrefix =
        getPrefix(plugin, "Gerrit-HttpDocumentationPrefix", "Documentation/");
    }

    private static String getPrefix(Plugin plugin, String attr, String def) {
      Path path = plugin.getSrcFile();
      PluginContentScanner scanner = plugin.getContentScanner();
      if (path == null || scanner == PluginContentScanner.EMPTY) {
        return def;
      }
      try {
        String prefix =
            scanner.getManifest().getMainAttributes().getValue(attr);
        if (prefix != null) {
          return CharMatcher.is('/').trimFrom(prefix) + "/";
        }
        return def;
      } catch (IOException e) {
        log.warn(String.format("Error getting %s for plugin %s, using default",
            attr, plugin.getName()), e);
        return null;
      }
    }
  }
}
