LCOV - code coverage report
Current view: top level - server/git/meta - TabFile.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 62 63 98.4 %
Date: 2022-11-19 15:00:39 Functions: 9 9 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2015 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.git.meta;
      16             : 
      17             : import static com.google.common.collect.ImmutableList.toImmutableList;
      18             : 
      19             : import com.google.common.collect.ImmutableList;
      20             : import com.google.gerrit.common.Nullable;
      21             : import com.google.gerrit.server.git.ValidationError;
      22             : import java.io.BufferedReader;
      23             : import java.io.IOException;
      24             : import java.io.StringReader;
      25             : import java.util.ArrayList;
      26             : import java.util.Collection;
      27             : import java.util.HashMap;
      28             : import java.util.List;
      29             : import java.util.Map;
      30             : 
      31             : /** (De)serializer for tab-delimited text files. */
      32         152 : public class TabFile {
      33             :   @FunctionalInterface
      34             :   public interface Parser {
      35             :     String parse(String str);
      36             :   }
      37             : 
      38         152 :   public static final Parser TRIM = String::trim;
      39             : 
      40             :   protected static class Row {
      41             :     public String left;
      42             :     public String right;
      43             : 
      44         151 :     public Row(String left, String right) {
      45         151 :       this.left = left;
      46         151 :       this.right = right;
      47         151 :     }
      48             :   }
      49             : 
      50             :   protected static List<Row> parse(
      51             :       String text, String filename, Parser left, Parser right, ValidationError.Sink errors)
      52             :       throws IOException {
      53         152 :     List<Row> rows = new ArrayList<>();
      54         152 :     BufferedReader br = new BufferedReader(new StringReader(text));
      55             :     String s;
      56         152 :     for (int lineNumber = 1; (s = br.readLine()) != null; lineNumber++) {
      57         151 :       if (s.isEmpty() || s.startsWith("#")) {
      58         151 :         continue;
      59             :       }
      60             : 
      61         151 :       int tab = s.indexOf('\t');
      62         151 :       if (tab < 0) {
      63           1 :         errors.error(ValidationError.create(filename, lineNumber, "missing tab delimiter"));
      64           1 :         continue;
      65             :       }
      66             : 
      67         151 :       Row row = new Row(s.substring(0, tab), s.substring(tab + 1));
      68         151 :       rows.add(row);
      69             : 
      70         151 :       if (left != null) {
      71         151 :         row.left = left.parse(row.left);
      72             :       }
      73         151 :       if (right != null) {
      74         151 :         row.right = right.parse(row.right);
      75             :       }
      76             :     }
      77         152 :     return rows;
      78             :   }
      79             : 
      80             :   protected static Map<String, String> toMap(List<Row> rows) {
      81           5 :     Map<String, String> map = new HashMap<>(rows.size());
      82           5 :     for (Row row : rows) {
      83           5 :       map.put(row.left, row.right);
      84           5 :     }
      85           5 :     return map;
      86             :   }
      87             : 
      88             :   @Nullable
      89             :   protected static String asText(String left, String right, Map<String, String> entries) {
      90           5 :     if (entries.isEmpty()) {
      91           1 :       return null;
      92             :     }
      93             : 
      94           5 :     List<Row> rows = new ArrayList<>(entries.size());
      95           5 :     for (String key : sort(entries.keySet())) {
      96           5 :       rows.add(new Row(key, entries.get(key)));
      97           5 :     }
      98           5 :     return asText(left, right, rows);
      99             :   }
     100             : 
     101             :   @Nullable
     102             :   protected static String asText(String left, String right, List<Row> rows) {
     103         151 :     if (rows.isEmpty()) {
     104           0 :       return null;
     105             :     }
     106             : 
     107         151 :     left = "# " + left;
     108         151 :     int leftLen = left.length();
     109         151 :     for (Row row : rows) {
     110         151 :       leftLen = Math.max(leftLen, row.left.length());
     111         151 :     }
     112             : 
     113         151 :     StringBuilder buf = new StringBuilder();
     114         151 :     buf.append(pad(leftLen, left));
     115         151 :     buf.append('\t');
     116         151 :     buf.append(right);
     117         151 :     buf.append('\n');
     118             : 
     119         151 :     buf.append('#');
     120         151 :     buf.append('\n');
     121             : 
     122         151 :     for (Row row : rows) {
     123         151 :       buf.append(pad(leftLen, row.left));
     124         151 :       buf.append('\t');
     125         151 :       buf.append(row.right);
     126         151 :       buf.append('\n');
     127         151 :     }
     128         151 :     return buf.toString();
     129             :   }
     130             : 
     131             :   protected static <T extends Comparable<? super T>> ImmutableList<T> sort(Collection<T> m) {
     132         151 :     return m.stream().sorted().collect(toImmutableList());
     133             :   }
     134             : 
     135             :   protected static String pad(int len, String src) {
     136         151 :     if (len <= src.length()) {
     137         151 :       return src;
     138             :     }
     139             : 
     140         151 :     StringBuilder r = new StringBuilder(len);
     141         151 :     r.append(src);
     142         151 :     while (r.length() < len) {
     143         151 :       r.append(' ');
     144             :     }
     145         151 :     return r.toString();
     146             :   }
     147             : }

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