1 /* 2 * Copyright (c) 2007, 2012, 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 24 import java.io.*; 25 import java.text.*; 26 import java.util.*; 27 import java.util.regex.*; 28 29 public class PropertiesTest { 30 public static void main(String[] s) throws Exception { 31 for (int i = 0; i < s.length; i ++) { 32 if ("-d".equals(s[i])) { 33 i++; 34 if (i == s.length) { 35 throw new RuntimeException("-d needs output file name"); 36 } else { 37 dump(s[i]); 38 } 39 } else if ("-c".equals(s[i])) { 40 if (i+2 == s.length) { 41 throw new RuntimeException("-d needs two file name arguments, before and after respectively"); 42 } else { 43 compare(s[++i], s[++i]); 44 } 45 } 46 } 47 } 48 49 private static void dump(String outfile) { 50 File f = new File(outfile); 51 PrintWriter pw; 52 try { 53 f.createNewFile(); 54 pw = new PrintWriter(f); 55 } catch (Exception fnfe) { 56 throw new RuntimeException(fnfe); 57 } 58 for (char c1 = 'A'; c1 <= 'Z'; c1++) { 59 for (char c2 = 'A'; c2 <= 'Z'; c2++) { 60 String ctry = new StringBuilder().append(c1).append(c2).toString(); 61 try { 62 Currency c = Currency.getInstance(new Locale("", ctry)); 63 if (c != null) { 64 pw.printf(Locale.ROOT, "%s=%s,%03d,%1d\n", 65 ctry, 66 c.getCurrencyCode(), 67 c.getNumericCode(), 68 c.getDefaultFractionDigits()); 69 } 70 } catch (IllegalArgumentException iae) { 71 // invalid country code 72 continue; 73 } 74 } 75 } 76 pw.flush(); 77 pw.close(); 78 } 79 80 private static void compare(String beforeFile, String afterFile) throws Exception { 81 // load file contents 82 Properties before = new Properties(); 83 Properties after = new Properties(); 84 try { 85 before.load(new FileReader(beforeFile)); 86 after.load(new FileReader(afterFile)); 87 } catch (IOException ioe) { 88 throw new RuntimeException(ioe); 89 } 90 91 // remove the same contents from the 'after' properties 92 Set<String> keys = before.stringPropertyNames(); 93 for (String key: keys) { 94 String beforeVal = before.getProperty(key); 95 String afterVal = after.getProperty(key); 96 System.out.printf("Removing country: %s. before: %s, after: %s", key, beforeVal, afterVal); 97 if (beforeVal.equals(afterVal)) { 98 after.remove(key); 99 System.out.printf(" --- removed\n"); 100 } else { 101 System.out.printf(" --- NOT removed\n"); 102 } 103 } 104 105 // now look at the currency.properties 106 String propFileName = System.getProperty("java.home") + File.separator + 107 "lib" + File.separator + "currency.properties"; 108 Properties p = new Properties(); 109 try { 110 p.load(new FileReader(propFileName)); 111 } catch (IOException ioe) { 112 throw new RuntimeException(ioe); 113 } 114 115 // test each replacements 116 keys = p.stringPropertyNames(); 117 Pattern propertiesPattern = 118 Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" + 119 "([0-3])\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" + 120 "\\d{2}:\\d{2})?"); 121 for (String key: keys) { 122 String val = p.getProperty(key); 123 try { 124 if (countOccurrences(val, ',') == 3 && !isPastCutoverDate(val)) { 125 System.out.println("Skipping since date is in future"); 126 continue; // skip since date in future (no effect) 127 } 128 } catch (ParseException pe) { 129 // swallow - currency class should not honour this value 130 continue; 131 } 132 String afterVal = after.getProperty(key); 133 System.out.printf("Testing key: %s, val: %s... ", key, val); 134 System.out.println("AfterVal is : " + afterVal); 135 136 Matcher m = propertiesPattern.matcher(val.toUpperCase(Locale.ROOT)); 137 if (!m.find()) { 138 // format is not recognized. 139 System.out.printf("Format is not recognized.\n"); 140 if (afterVal != null) { 141 throw new RuntimeException("Currency data replacement for "+key+" failed: It was incorrectly altered to "+afterVal); 142 } 143 144 // ignore this 145 continue; 146 } 147 Matcher mAfter = propertiesPattern.matcher(afterVal); 148 mAfter.find(); 149 150 String code = m.group(1); 151 String codeAfter = mAfter.group(1); 152 int numeric = Integer.parseInt(m.group(2)); 153 int numericAfter = Integer.parseInt(mAfter.group(2)); 154 int fraction = Integer.parseInt(m.group(3)); 155 int fractionAfter = Integer.parseInt(mAfter.group(3)); 156 if (code.equals(codeAfter) && 157 (numeric == numericAfter)&& 158 (fraction == fractionAfter)) { 159 after.remove(key); 160 } else { 161 throw new RuntimeException("Currency data replacement for "+key+" failed: actual: (alphacode: "+codeAfter+", numcode: "+numericAfter+", fraction: "+fractionAfter+"), expected: (alphacode: "+code+", numcode: "+numeric+", fraction: "+fraction+")"); 162 } 163 System.out.printf("Success!\n"); 164 } 165 if (!after.isEmpty()) { 166 StringBuilder sb = new StringBuilder() 167 .append("Currency data replacement failed. Unnecessary modification was(were) made for the following currencies:\n"); 168 keys = after.stringPropertyNames(); 169 for (String key : keys) { 170 sb.append(" country: ") 171 .append(key) 172 .append(" currency: ") 173 .append(after.getProperty(key)) 174 .append("\n"); 175 } 176 throw new RuntimeException(sb.toString()); 177 } 178 } 179 180 private static boolean isPastCutoverDate(String s) 181 throws IndexOutOfBoundsException, NullPointerException, ParseException { 182 String dateString = s.substring(s.lastIndexOf(',')+1, s.length()).trim(); 183 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT); 184 format.setTimeZone(TimeZone.getTimeZone("GMT")); 185 format.setLenient(false); 186 187 long time = format.parse(dateString).getTime(); 188 if (System.currentTimeMillis() - time >= 0L) { 189 return true; 190 } else { 191 return false; 192 } 193 } 194 195 private static int countOccurrences(String value, char match) { 196 int count = 0; 197 for (char c : value.toCharArray()) { 198 if (c == match) { 199 ++count; 200 } 201 } 202 return count; 203 } 204 }