1 /* 2 * Copyright (C) 2015 The Android Open Source Project 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.android.timezone.distro.tools; 17 18 import com.android.i18n.timezone.TzDataSetVersion; 19 20 import com.android.timezone.distro.DistroVersion; 21 import com.android.timezone.distro.TimeZoneDistro; 22 import com.android.timezone.distro.builder.TimeZoneDistroBuilder; 23 24 import java.io.File; 25 import java.io.FileInputStream; 26 import java.io.FileOutputStream; 27 import java.io.IOException; 28 import java.io.InputStreamReader; 29 import java.io.OutputStream; 30 import java.io.Reader; 31 import java.util.Properties; 32 33 /** 34 * A command-line tool for creating a time zone update distro and associated 35 * files. 36 * 37 * <p>Args: 38 * <dl> 39 * <dt>input properties file</dt> 40 * <dd>the file describing the distro and output dirs</dd> 41 * </dl> 42 * 43 * <p>The input properties file must have the entries: 44 * <dl> 45 * <dt>rules.version</dt> 46 * <dd>The IANA rules version.</dd> 47 * <dt>revision</dt> 48 * <dd>The distro revision (typically 1).</dd> 49 * <dt>tzdata.file</dt> 50 * <dd>The location of the tzdata file.</dd> 51 * <dt>icu.file</dt> 52 * <dd>The location of the ICU overlay .dat file.</dd> 53 * <dt>tzlookup.file</dt> 54 * <dd>The location of the tzlookup.xml file.</dd> 55 * <dt>telephonylookup.file</dt> 56 * <dd>The location of the telephonylookup.xml file.</dd> 57 * <dt>output.distro.dir</dt> 58 * <dd>The directory to write the distro.zip file to.</dd> 59 * <dt>output.version.file</dt> 60 * <dd>The location to write the version file to.</dd> 61 * </dl> 62 * 63 * <p>The output consists of: 64 * <ul> 65 * <li>A distro .zip containing the input files. See 66 * {@link com.android.timezone.distro.TimeZoneDistro}</li> 67 * <li>A version file (same as contained in the distro .zip).</li> 68 * </ul> 69 */ 70 public class CreateTimeZoneDistro { 71 CreateTimeZoneDistro()72 private CreateTimeZoneDistro() {} 73 main(String[] args)74 public static void main(String[] args) throws Exception { 75 if (args.length != 1) { 76 printUsage(); 77 System.exit(1); 78 } 79 File f = new File(args[0]); 80 if (!f.exists()) { 81 System.err.println("Properties file " + f + " not found"); 82 printUsage(); 83 System.exit(2); 84 } 85 Properties properties = loadProperties(f); 86 String ianaRulesVersion = getMandatoryProperty(properties, "rules.version"); 87 int revision = Integer.parseInt(getMandatoryProperty(properties, "revision")); 88 89 // Create an object to hold version metadata for the tz data. 90 TzDataSetVersion tzDataSetVersion = new TzDataSetVersion( 91 TzDataSetVersion.currentFormatMajorVersion(), 92 TzDataSetVersion.currentFormatMinorVersion(), 93 ianaRulesVersion, 94 revision); 95 byte[] tzDataSetVersionBytes = tzDataSetVersion.toBytes(); 96 97 // Create a DistroVersion from the TzDataSetVersion. 98 DistroVersion distroVersion = new DistroVersion( 99 tzDataSetVersion.getFormatMajorVersion(), 100 tzDataSetVersion.getFormatMinorVersion(), 101 tzDataSetVersion.getRulesVersion(), 102 tzDataSetVersion.getRevision()); 103 TimeZoneDistroBuilder builder = new TimeZoneDistroBuilder() 104 .setDistroVersion(distroVersion) 105 .setTzDataFile(getMandatoryPropertyFile(properties, "tzdata.file")) 106 .setIcuDataFile(getMandatoryPropertyFile(properties, "icu.file")) 107 .setTzLookupFile(getMandatoryPropertyFile(properties, "tzlookup.file")) 108 .setTelephonyLookupFile( 109 getMandatoryPropertyFile(properties, "telephonylookup.file")); 110 byte[] distroBytes = builder.buildBytes(); 111 112 File outputDistroDir = getMandatoryPropertyFile(properties, "output.distro.dir"); 113 File outputVersionFile = new File(getMandatoryProperty(properties, "output.version.file")); 114 115 // Write the tz data set version file. 116 try (OutputStream os = new FileOutputStream(outputVersionFile)) { 117 os.write(tzDataSetVersionBytes); 118 } 119 System.out.println("Wrote " + outputVersionFile); 120 121 // Write the distro file. 122 File outputDistroFile = new File(outputDistroDir, TimeZoneDistro.FILE_NAME); 123 try (OutputStream os = new FileOutputStream(outputDistroFile)) { 124 os.write(distroBytes); 125 } 126 System.out.println("Wrote " + outputDistroFile); 127 } 128 getMandatoryPropertyFile(Properties p, String propertyName)129 private static File getMandatoryPropertyFile(Properties p, String propertyName) { 130 String fileName = getMandatoryProperty(p, propertyName); 131 File file = new File(fileName); 132 if (!file.exists()) { 133 System.out.println( 134 "Missing file: " + file + " for property " + propertyName + " does not exist."); 135 printUsage(); 136 System.exit(4); 137 } 138 return file; 139 } 140 getMandatoryProperty(Properties p, String propertyName)141 private static String getMandatoryProperty(Properties p, String propertyName) { 142 String value = p.getProperty(propertyName); 143 if (value == null) { 144 System.out.println("Missing property: " + propertyName); 145 printUsage(); 146 System.exit(3); 147 } 148 return value; 149 } 150 loadProperties(File f)151 private static Properties loadProperties(File f) throws IOException { 152 Properties p = new Properties(); 153 try (Reader reader = new InputStreamReader(new FileInputStream(f))) { 154 p.load(reader); 155 } 156 return p; 157 } 158 printUsage()159 private static void printUsage() { 160 System.out.println("Usage:"); 161 System.out.println("\t" + CreateTimeZoneDistro.class.getName() + 162 " <tzupdate.properties file>"); 163 } 164 } 165