LCOV - code coverage report
Current view: top level - server/config - PreferencesParserUtil.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 84 94 89.4 %
Date: 2022-11-19 15:00:39 Functions: 15 15 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2020 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.config;
      16             : 
      17             : import static com.google.gerrit.server.config.ConfigUtil.loadSection;
      18             : import static com.google.gerrit.server.config.ConfigUtil.skipField;
      19             : import static com.google.gerrit.server.git.UserConfigSections.CHANGE_TABLE;
      20             : import static com.google.gerrit.server.git.UserConfigSections.CHANGE_TABLE_COLUMN;
      21             : import static com.google.gerrit.server.git.UserConfigSections.KEY_ID;
      22             : import static com.google.gerrit.server.git.UserConfigSections.KEY_TARGET;
      23             : import static com.google.gerrit.server.git.UserConfigSections.KEY_URL;
      24             : 
      25             : import com.google.common.base.Strings;
      26             : import com.google.common.collect.Lists;
      27             : import com.google.common.flogger.FluentLogger;
      28             : import com.google.gerrit.common.Nullable;
      29             : import com.google.gerrit.extensions.client.DiffPreferencesInfo;
      30             : import com.google.gerrit.extensions.client.EditPreferencesInfo;
      31             : import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
      32             : import com.google.gerrit.extensions.client.MenuItem;
      33             : import com.google.gerrit.server.git.UserConfigSections;
      34             : import java.lang.reflect.Field;
      35             : import java.util.ArrayList;
      36             : import java.util.List;
      37             : import org.eclipse.jgit.errors.ConfigInvalidException;
      38             : import org.eclipse.jgit.lib.Config;
      39             : 
      40             : /** Helper to read default or user preferences from Git-style config files. */
      41             : public class PreferencesParserUtil {
      42         151 :   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
      43             : 
      44             :   private PreferencesParserUtil() {}
      45             : 
      46             :   /**
      47             :    * Returns a {@link GeneralPreferencesInfo} that is the result of parsing {@code defaultCfg} for
      48             :    * the server's default configs and {@code cfg} for the user's config. These configs are then
      49             :    * overlaid to inherit values (default -> user -> input (if provided).
      50             :    */
      51             :   public static GeneralPreferencesInfo parseGeneralPreferences(
      52             :       Config cfg, @Nullable Config defaultCfg, @Nullable GeneralPreferencesInfo input)
      53             :       throws ConfigInvalidException {
      54         151 :     GeneralPreferencesInfo r =
      55         151 :         loadSection(
      56             :             cfg,
      57             :             UserConfigSections.GENERAL,
      58             :             null,
      59             :             new GeneralPreferencesInfo(),
      60         151 :             defaultCfg != null
      61         151 :                 ? parseDefaultGeneralPreferences(defaultCfg, input)
      62         151 :                 : GeneralPreferencesInfo.defaults(),
      63             :             input);
      64         151 :     if (input != null) {
      65           8 :       r.changeTable = input.changeTable;
      66           8 :       r.my = input.my;
      67             :     } else {
      68         151 :       r.changeTable = parseChangeTableColumns(cfg, defaultCfg);
      69         151 :       r.my = parseMyMenus(cfg, defaultCfg);
      70             :     }
      71         151 :     return r;
      72             :   }
      73             : 
      74             :   /**
      75             :    * Returns a {@link GeneralPreferencesInfo} that is the result of parsing {@code defaultCfg} for
      76             :    * the server's default configs. These configs are then overlaid to inherit values (default ->
      77             :    * input (if provided).
      78             :    */
      79             :   public static GeneralPreferencesInfo parseDefaultGeneralPreferences(
      80             :       Config defaultCfg, GeneralPreferencesInfo input) throws ConfigInvalidException {
      81         151 :     GeneralPreferencesInfo allUserPrefs = new GeneralPreferencesInfo();
      82         151 :     loadSection(
      83             :         defaultCfg,
      84             :         UserConfigSections.GENERAL,
      85             :         null,
      86             :         allUserPrefs,
      87         151 :         GeneralPreferencesInfo.defaults(),
      88             :         input);
      89         151 :     return updateGeneralPreferencesDefaults(allUserPrefs);
      90             :   }
      91             : 
      92             :   /**
      93             :    * Returns a {@link DiffPreferencesInfo} that is the result of parsing {@code defaultCfg} for the
      94             :    * server's default configs and {@code cfg} for the user's config. These configs are then overlaid
      95             :    * to inherit values (default -> user -> input (if provided).
      96             :    */
      97             :   public static DiffPreferencesInfo parseDiffPreferences(
      98             :       Config cfg, @Nullable Config defaultCfg, @Nullable DiffPreferencesInfo input)
      99             :       throws ConfigInvalidException {
     100         151 :     return loadSection(
     101             :         cfg,
     102             :         UserConfigSections.DIFF,
     103             :         null,
     104             :         new DiffPreferencesInfo(),
     105         151 :         defaultCfg != null
     106         151 :             ? parseDefaultDiffPreferences(defaultCfg, input)
     107         151 :             : DiffPreferencesInfo.defaults(),
     108             :         input);
     109             :   }
     110             : 
     111             :   /**
     112             :    * Returns a {@link DiffPreferencesInfo} that is the result of parsing {@code defaultCfg} for the
     113             :    * server's default configs. These configs are then overlaid to inherit values (default -> input
     114             :    * (if provided).
     115             :    */
     116             :   public static DiffPreferencesInfo parseDefaultDiffPreferences(
     117             :       Config defaultCfg, DiffPreferencesInfo input) throws ConfigInvalidException {
     118         151 :     DiffPreferencesInfo allUserPrefs = new DiffPreferencesInfo();
     119         151 :     loadSection(
     120             :         defaultCfg,
     121             :         UserConfigSections.DIFF,
     122             :         null,
     123             :         allUserPrefs,
     124         151 :         DiffPreferencesInfo.defaults(),
     125             :         input);
     126         151 :     return updateDiffPreferencesDefaults(allUserPrefs);
     127             :   }
     128             : 
     129             :   /**
     130             :    * Returns a {@link EditPreferencesInfo} that is the result of parsing {@code defaultCfg} for the
     131             :    * server's default configs and {@code cfg} for the user's config. These configs are then overlaid
     132             :    * to inherit values (default -> user -> input (if provided).
     133             :    */
     134             :   public static EditPreferencesInfo parseEditPreferences(
     135             :       Config cfg, @Nullable Config defaultCfg, @Nullable EditPreferencesInfo input)
     136             :       throws ConfigInvalidException {
     137         151 :     return loadSection(
     138             :         cfg,
     139             :         UserConfigSections.EDIT,
     140             :         null,
     141             :         new EditPreferencesInfo(),
     142         151 :         defaultCfg != null
     143         151 :             ? parseDefaultEditPreferences(defaultCfg, input)
     144         151 :             : EditPreferencesInfo.defaults(),
     145             :         input);
     146             :   }
     147             : 
     148             :   /**
     149             :    * Returns a {@link EditPreferencesInfo} that is the result of parsing {@code defaultCfg} for the
     150             :    * server's default configs. These configs are then overlaid to inherit values (default -> input
     151             :    * (if provided).
     152             :    */
     153             :   public static EditPreferencesInfo parseDefaultEditPreferences(
     154             :       Config defaultCfg, EditPreferencesInfo input) throws ConfigInvalidException {
     155         151 :     EditPreferencesInfo allUserPrefs = new EditPreferencesInfo();
     156         151 :     loadSection(
     157             :         defaultCfg,
     158             :         UserConfigSections.EDIT,
     159             :         null,
     160             :         allUserPrefs,
     161         151 :         EditPreferencesInfo.defaults(),
     162             :         input);
     163         151 :     return updateEditPreferencesDefaults(allUserPrefs);
     164             :   }
     165             : 
     166             :   private static List<String> parseChangeTableColumns(Config cfg, @Nullable Config defaultCfg) {
     167         151 :     List<String> changeTable = changeTable(cfg);
     168         151 :     if (changeTable == null && defaultCfg != null) {
     169           0 :       changeTable = changeTable(defaultCfg);
     170             :     }
     171         151 :     return changeTable;
     172             :   }
     173             : 
     174             :   private static List<MenuItem> parseMyMenus(Config cfg, @Nullable Config defaultCfg) {
     175         151 :     List<MenuItem> my = my(cfg);
     176         151 :     if (my.isEmpty() && defaultCfg != null) {
     177         151 :       my = my(defaultCfg);
     178             :     }
     179         151 :     if (my.isEmpty()) {
     180         151 :       my.add(new MenuItem("Dashboard", "#/dashboard/self", null));
     181         151 :       my.add(new MenuItem("Draft Comments", "#/q/has:draft", null));
     182         151 :       my.add(new MenuItem("Edits", "#/q/has:edit", null));
     183         151 :       my.add(new MenuItem("Watched Changes", "#/q/is:watched+is:open", null));
     184         151 :       my.add(new MenuItem("Starred Changes", "#/q/is:starred", null));
     185         151 :       my.add(new MenuItem("All Visible Changes", "#/q/is:visible", null));
     186         151 :       my.add(new MenuItem("Groups", "#/settings/#Groups", null));
     187             :     }
     188         151 :     return my;
     189             :   }
     190             : 
     191             :   private static GeneralPreferencesInfo updateGeneralPreferencesDefaults(
     192             :       GeneralPreferencesInfo input) {
     193         151 :     GeneralPreferencesInfo result = GeneralPreferencesInfo.defaults();
     194             :     try {
     195         151 :       for (Field field : input.getClass().getDeclaredFields()) {
     196         151 :         if (skipField(field)) {
     197         151 :           continue;
     198             :         }
     199         151 :         Object newVal = field.get(input);
     200         151 :         if (newVal != null) {
     201         151 :           field.set(result, newVal);
     202             :         }
     203             :       }
     204           0 :     } catch (IllegalAccessException e) {
     205           0 :       logger.atSevere().withCause(e).log("Failed to apply default general preferences");
     206           0 :       return GeneralPreferencesInfo.defaults();
     207         151 :     }
     208         151 :     return result;
     209             :   }
     210             : 
     211             :   private static DiffPreferencesInfo updateDiffPreferencesDefaults(DiffPreferencesInfo input) {
     212         151 :     DiffPreferencesInfo result = DiffPreferencesInfo.defaults();
     213             :     try {
     214         151 :       for (Field field : input.getClass().getDeclaredFields()) {
     215         151 :         if (skipField(field)) {
     216         151 :           continue;
     217             :         }
     218         151 :         Object newVal = field.get(input);
     219         151 :         if (newVal != null) {
     220         151 :           field.set(result, newVal);
     221             :         }
     222             :       }
     223           0 :     } catch (IllegalAccessException e) {
     224           0 :       logger.atSevere().withCause(e).log("Failed to apply default diff preferences");
     225           0 :       return DiffPreferencesInfo.defaults();
     226         151 :     }
     227         151 :     return result;
     228             :   }
     229             : 
     230             :   private static EditPreferencesInfo updateEditPreferencesDefaults(EditPreferencesInfo input) {
     231         151 :     EditPreferencesInfo result = EditPreferencesInfo.defaults();
     232             :     try {
     233         151 :       for (Field field : input.getClass().getDeclaredFields()) {
     234         151 :         if (skipField(field)) {
     235         151 :           continue;
     236             :         }
     237         151 :         Object newVal = field.get(input);
     238         151 :         if (newVal != null) {
     239         151 :           field.set(result, newVal);
     240             :         }
     241             :       }
     242           0 :     } catch (IllegalAccessException e) {
     243           0 :       logger.atSevere().withCause(e).log("Failed to apply default edit preferences");
     244           0 :       return EditPreferencesInfo.defaults();
     245         151 :     }
     246         151 :     return result;
     247             :   }
     248             : 
     249             :   private static List<String> changeTable(Config cfg) {
     250         151 :     return Lists.newArrayList(cfg.getStringList(CHANGE_TABLE, null, CHANGE_TABLE_COLUMN));
     251             :   }
     252             : 
     253             :   private static List<MenuItem> my(Config cfg) {
     254         151 :     List<MenuItem> my = new ArrayList<>();
     255         151 :     for (String subsection : cfg.getSubsections(UserConfigSections.MY)) {
     256           6 :       String url = my(cfg, subsection, KEY_URL, "#/");
     257           6 :       String target = my(cfg, subsection, KEY_TARGET, url.startsWith("#") ? null : "_blank");
     258           6 :       my.add(new MenuItem(subsection, url, target, my(cfg, subsection, KEY_ID, null)));
     259           6 :     }
     260         151 :     return my;
     261             :   }
     262             : 
     263             :   private static String my(Config cfg, String subsection, String key, String defaultValue) {
     264           6 :     String val = cfg.getString(UserConfigSections.MY, subsection, key);
     265           6 :     return !Strings.isNullOrEmpty(val) ? val : defaultValue;
     266             :   }
     267             : }

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