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 : }