1 /* 2 * Copyright (C) 2020 The Libphonenumber Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.phonenumbers.migrator; 17 18 import com.google.common.collect.ImmutableMap; 19 import com.google.i18n.phonenumbers.metadata.DigitSequence; 20 import com.google.i18n.phonenumbers.metadata.RangeTree; 21 import com.google.i18n.phonenumbers.metadata.table.Column; 22 import com.google.i18n.phonenumbers.metadata.table.CsvTable; 23 import com.google.i18n.phonenumbers.metadata.table.RangeKey; 24 import com.google.i18n.phonenumbers.metadata.table.RangeTable; 25 import java.util.Optional; 26 import java.util.stream.Stream; 27 28 /** Utilities for migration tool. */ 29 public final class MigrationUtils { 30 31 /** 32 * Returns the entries within migrationEntries that can be migrated using the given recipe. This 33 * method will not perform migrations and as a result, the validity of migrations using the given 34 * recipe cannot be verified. 35 * 36 * @param recipeKey: the key of the recipe that is being checked 37 * @throws IllegalArgumentException if there is no row in the recipesTable with the given 38 * recipeKey 39 */ getMigratableRangeByRecipe(CsvTable<RangeKey> recipesTable, RangeKey recipeKey, Stream<MigrationEntry> migrationEntries)40 public static Stream<MigrationEntry> getMigratableRangeByRecipe(CsvTable<RangeKey> recipesTable, 41 RangeKey recipeKey, 42 Stream<MigrationEntry> migrationEntries) { 43 if (!recipesTable.containsRow(recipeKey)) { 44 throw new IllegalArgumentException( 45 recipeKey + " does not match any recipe row in the given recipes table"); 46 } 47 48 return migrationEntries 49 .filter(entry -> recipeKey.asRangeTree().contains(entry.getSanitizedNumber())); 50 } 51 52 /** 53 * Returns the sub range of entries within migrationEntries that can be migrated using any recipe 54 * from the {@link CsvTable} recipesTable that matches the specified BCP-47 country code. This 55 * method will not perform migrations and as a result, the validity of migrations using the given 56 * recipesTable cannot be verified. 57 */ getMigratableRangeByCountry(RangeTable recipesTable, DigitSequence countryCode, Stream<MigrationEntry> migrationEntries)58 public static Stream<MigrationEntry> getMigratableRangeByCountry(RangeTable recipesTable, 59 DigitSequence countryCode, 60 Stream<MigrationEntry> migrationEntries) { 61 62 RangeTree countryRecipes = recipesTable 63 .getRanges(RecipesTableSchema.COUNTRY_CODE, countryCode); 64 65 return migrationEntries 66 .filter(entry -> countryRecipes.contains(entry.getSanitizedNumber())); 67 } 68 69 /** 70 * Returns the {@link CsvTable} row for the given recipe in a recipes table that can be used to 71 * migrate the given {@link DigitSequence}. The found recipe must also be linked to the given 72 * country code to ensure that recipes from incorrect countries are not used to migrated a given 73 * number. 74 */ findMatchingRecipe( CsvTable<RangeKey> recipesTable, DigitSequence countryCode, DigitSequence number)75 public static Optional<ImmutableMap<Column<?>, Object>> findMatchingRecipe( 76 CsvTable<RangeKey> recipesTable, 77 DigitSequence countryCode, 78 DigitSequence number) { 79 80 for (RangeKey recipeKey : recipesTable.getKeys()) { 81 if (recipeKey.contains(number, number.length()) && recipesTable.getRow(recipeKey) 82 .get(RecipesTableSchema.COUNTRY_CODE).equals(countryCode)) { 83 return Optional.of(recipesTable.getRow(recipeKey)); 84 } 85 } 86 return Optional.empty(); 87 } 88 } 89