1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.openjdk.skara.bots.hgbridge; 24 25 import org.openjdk.skara.forge.HostedRepository; 26 import org.openjdk.skara.json.*; 27 import org.openjdk.skara.vcs.*; 28 import org.openjdk.skara.vcs.openjdk.convert.*; 29 30 import java.io.IOException; 31 import java.net.URI; 32 import java.nio.charset.StandardCharsets; 33 import java.nio.file.*; 34 import java.util.*; 35 import java.util.stream.Collectors; 36 37 class ExporterConfig { 38 private List<HostedRepository> destinations; 39 private URI source; 40 private HostedRepository configurationRepo; 41 private String configurationRef; 42 private HostedRepository marksRepo; 43 private String marksRef; 44 private String marksAuthorName; 45 private String marksAuthorEmail; 46 private List<String> replacementsFile; 47 private List<String> correctionsFile; 48 private List<String> lowercaseFile; 49 private List<String> punctuatedFile; 50 private List<String> authorsFile; 51 private List<String> contributorsFile; 52 private List<String> sponsorsFile; 53 54 void destinations(List<HostedRepository> destinations) { 55 this.destinations = destinations; 56 } 57 58 List<HostedRepository> destinations() { 59 return new ArrayList<>(destinations); 60 } 61 62 void source(URI source) { 63 this.source = source; 64 } 65 66 URI source() { 67 return source; 68 } 69 70 void configurationRepo(HostedRepository configurationRepo) { 71 this.configurationRepo = configurationRepo; 72 } 73 74 void configurationRef(String configurationRef) { 75 this.configurationRef = configurationRef; 76 } 77 78 void marksRepo(HostedRepository marksRepo) { 79 this.marksRepo = marksRepo; 80 } 81 82 HostedRepository marksRepo() { 83 return marksRepo; 84 } 85 86 void marksRef(String marksRef) { 87 this.marksRef = marksRef; 88 } 89 90 String marksRef() { 91 return marksRef; 92 } 93 94 void marksAuthorName(String marksAuthorName) { 95 this.marksAuthorName = marksAuthorName; 96 } 97 98 String marksAuthorName() { 99 return marksAuthorName; 100 } 101 102 void marksAuthorEmail(String marksAuthorEmail) { 103 this.marksAuthorEmail = marksAuthorEmail; 104 } 105 106 String marksAuthorEmail() { 107 return marksAuthorEmail; 108 } 109 110 void replacements(List<String> replacements) { 111 replacementsFile = replacements; 112 } 113 114 void corrections(List<String> corrections) { 115 correctionsFile = corrections; 116 } 117 118 void lowercase(List<String> lowercase) { 119 lowercaseFile = lowercase; 120 } 121 122 void punctuated(List<String> punctuated) { 123 punctuatedFile = punctuated; 124 } 125 126 void authors(List<String> authors) { 127 authorsFile = authors; 128 } 129 130 void contributors(List<String> contributors) { 131 contributorsFile = contributors; 132 } 133 134 void sponsors(List<String> sponsors) { 135 sponsorsFile = sponsors; 136 } 137 138 private interface FieldParser<T> { 139 T parse(JSONObject.Field value); 140 } 141 142 private <K, V> Map<K, V> parseMap(Path base, List<String> files, FieldParser<K> keyParser, FieldParser<V> valueParser) throws IOException { 143 var ret = new HashMap<K, V>(); 144 for (var file : files) { 145 var jsonData = Files.readString(base.resolve(file), StandardCharsets.UTF_8); 146 var json = JSON.parse(jsonData); 147 for (var field : json.fields()) { 148 ret.put(keyParser.parse(field), valueParser.parse(field)); 149 } 150 } 151 return ret; 152 } 153 154 private interface ValueParser<T> { 155 T parse(JSONValue value); 156 } 157 158 private <E> Set<E> parseCommits(Path base, List<String> files, ValueParser<E> valueParser) throws IOException { 159 var ret = new HashSet<E>(); 160 for (var file : files) { 161 var jsonData = Files.readString(base.resolve(file), StandardCharsets.UTF_8); 162 var json = JSON.parse(jsonData); 163 for (var value : json.get("commits").asArray()) { 164 ret.add(valueParser.parse(value)); 165 } 166 } 167 return ret; 168 } 169 170 public Converter resolve(Path scratchPath) throws IOException { 171 var localRepo = Repository.materialize(scratchPath, configurationRepo.url(), 172 configurationRef + ":hgbridge_config_" + configurationRepo.name()); 173 174 var replacements = parseMap(localRepo.root(), replacementsFile, 175 field -> new Hash(field.name()), 176 field -> field.value().stream() 177 .map(JSONValue::asString).collect(Collectors.toList())); 178 var corrections = parseMap(localRepo.root(), correctionsFile, 179 field -> new Hash(field.name()), 180 field -> field.value().fields().stream() 181 .collect(Collectors.toMap(JSONObject.Field::name, sub -> sub.value().asString()))); 182 var lowercase = parseCommits(localRepo.root(), lowercaseFile, value -> new Hash(value.asString())); 183 var punctuated = parseCommits(localRepo.root(), punctuatedFile, value -> new Hash(value.asString())); 184 var authors = parseMap(localRepo.root(), authorsFile, JSONObject.Field::name, field -> field.value().asString()); 185 var contributors = parseMap(localRepo.root(), contributorsFile, JSONObject.Field::name, field -> field.value().asString()); 186 var sponsors = parseMap(localRepo.root(), sponsorsFile, 187 JSONObject.Field::name, 188 field -> field.value().stream() 189 .map(JSONValue::asString) 190 .collect(Collectors.toList())); 191 192 return new HgToGitConverter(replacements, corrections, lowercase, punctuated, authors, contributors, sponsors); 193 } 194 }