LCOV - code coverage report
Current view: top level - server/plugins - ListPlugins.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 51 53 96.2 %
Date: 2022-11-19 15:00:39 Functions: 14 14 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2012 The Android Open Source Project
       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             : 
      15             : package com.google.gerrit.server.plugins;
      16             : 
      17             : import static java.util.Comparator.comparing;
      18             : import static java.util.stream.Collectors.toMap;
      19             : 
      20             : import com.google.common.collect.Streams;
      21             : import com.google.gerrit.common.data.GlobalCapability;
      22             : import com.google.gerrit.extensions.annotations.RequiresCapability;
      23             : import com.google.gerrit.extensions.api.plugins.Plugins;
      24             : import com.google.gerrit.extensions.common.PluginInfo;
      25             : import com.google.gerrit.extensions.restapi.BadRequestException;
      26             : import com.google.gerrit.extensions.restapi.Response;
      27             : import com.google.gerrit.extensions.restapi.RestReadView;
      28             : import com.google.gerrit.extensions.restapi.TopLevelResource;
      29             : import com.google.gerrit.extensions.restapi.Url;
      30             : import com.google.inject.Inject;
      31             : import java.util.Locale;
      32             : import java.util.SortedMap;
      33             : import java.util.TreeMap;
      34             : import java.util.regex.Pattern;
      35             : import java.util.stream.Stream;
      36             : import org.kohsuke.args4j.Option;
      37             : 
      38             : /** List the installed plugins. */
      39             : @RequiresCapability(GlobalCapability.VIEW_PLUGINS)
      40             : public class ListPlugins implements RestReadView<TopLevelResource> {
      41             :   private final PluginLoader pluginLoader;
      42             : 
      43             :   private boolean all;
      44             :   private int limit;
      45             :   private int start;
      46             :   private String matchPrefix;
      47             :   private String matchSubstring;
      48             :   private String matchRegex;
      49             : 
      50             :   @Option(
      51             :       name = "--all",
      52             :       aliases = {"-a"},
      53             :       usage = "List all plugins, including disabled plugins")
      54             :   public void setAll(boolean all) {
      55           1 :     this.all = all;
      56           1 :   }
      57             : 
      58             :   @Option(
      59             :       name = "--limit",
      60             :       aliases = {"-n"},
      61             :       metaVar = "CNT",
      62             :       usage = "maximum number of plugins to list")
      63             :   public void setLimit(int limit) {
      64           1 :     this.limit = limit;
      65           1 :   }
      66             : 
      67             :   @Option(
      68             :       name = "--start",
      69             :       aliases = {"-S"},
      70             :       metaVar = "CNT",
      71             :       usage = "number of plugins to skip")
      72             :   public void setStart(int start) {
      73           1 :     this.start = start;
      74           1 :   }
      75             : 
      76             :   @Option(
      77             :       name = "--prefix",
      78             :       aliases = {"-p"},
      79             :       metaVar = "PREFIX",
      80             :       usage = "match plugin prefix")
      81             :   public void setMatchPrefix(String matchPrefix) {
      82           1 :     this.matchPrefix = matchPrefix;
      83           1 :   }
      84             : 
      85             :   @Option(
      86             :       name = "--match",
      87             :       aliases = {"-m"},
      88             :       metaVar = "MATCH",
      89             :       usage = "match plugin substring")
      90             :   public void setMatchSubstring(String matchSubstring) {
      91           1 :     this.matchSubstring = matchSubstring;
      92           1 :   }
      93             : 
      94             :   @Option(name = "-r", metaVar = "REGEX", usage = "match plugin regex")
      95             :   public void setMatchRegex(String matchRegex) {
      96           1 :     this.matchRegex = matchRegex;
      97           1 :   }
      98             : 
      99             :   @Inject
     100           3 :   protected ListPlugins(PluginLoader pluginLoader) {
     101           3 :     this.pluginLoader = pluginLoader;
     102           3 :   }
     103             : 
     104             :   public ListPlugins request(Plugins.ListRequest request) {
     105           1 :     this.setAll(request.getAll());
     106           1 :     this.setStart(request.getStart());
     107           1 :     this.setLimit(request.getLimit());
     108           1 :     this.setMatchPrefix(request.getPrefix());
     109           1 :     this.setMatchSubstring(request.getSubstring());
     110           1 :     this.setMatchRegex(request.getRegex());
     111           1 :     return this;
     112             :   }
     113             : 
     114             :   @Override
     115             :   public Response<SortedMap<String, PluginInfo>> apply(TopLevelResource resource)
     116             :       throws BadRequestException {
     117           2 :     Stream<Plugin> s = Streams.stream(pluginLoader.getPlugins(all));
     118           2 :     if (matchPrefix != null) {
     119           1 :       checkMatchOptions(matchSubstring == null && matchRegex == null);
     120           1 :       s = s.filter(p -> p.getName().startsWith(matchPrefix));
     121           2 :     } else if (matchSubstring != null) {
     122           1 :       checkMatchOptions(matchPrefix == null && matchRegex == null);
     123           1 :       String substring = matchSubstring.toLowerCase(Locale.US);
     124           1 :       s = s.filter(p -> p.getName().toLowerCase(Locale.US).contains(substring));
     125           2 :     } else if (matchRegex != null) {
     126           1 :       checkMatchOptions(matchPrefix == null && matchSubstring == null);
     127           1 :       Pattern pattern = Pattern.compile(matchRegex);
     128           1 :       s = s.filter(p -> pattern.matcher(p.getName()).matches());
     129             :     }
     130           2 :     s = s.sorted(comparing(Plugin::getName));
     131           2 :     if (start > 0) {
     132           1 :       s = s.skip(start);
     133             :     }
     134           2 :     if (limit > 0) {
     135           1 :       s = s.limit(limit);
     136             :     }
     137           2 :     return Response.ok(new TreeMap<>(s.collect(toMap(Plugin::getName, ListPlugins::toPluginInfo))));
     138             :   }
     139             : 
     140             :   private void checkMatchOptions(boolean cond) throws BadRequestException {
     141           1 :     if (!cond) {
     142           1 :       throw new BadRequestException("specify exactly one of p/m/r");
     143             :     }
     144           1 :   }
     145             : 
     146             :   public static PluginInfo toPluginInfo(Plugin p) {
     147             :     String id;
     148             :     String version;
     149             :     String apiVersion;
     150             :     String indexUrl;
     151             :     String filename;
     152             :     Boolean disabled;
     153             : 
     154           3 :     id = Url.encode(p.getName());
     155           3 :     version = p.getVersion();
     156           3 :     apiVersion = p.getApiVersion();
     157           3 :     disabled = p.isDisabled() ? true : null;
     158           3 :     if (p.getSrcFile() != null) {
     159           3 :       indexUrl = String.format("plugins/%s/", p.getName());
     160           3 :       filename = p.getSrcFile().getFileName().toString();
     161             :     } else {
     162           0 :       indexUrl = null;
     163           0 :       filename = null;
     164             :     }
     165             : 
     166           3 :     return new PluginInfo(id, version, apiVersion, indexUrl, filename, disabled);
     167             :   }
     168             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750