| /* GENERATED SOURCE. DO NOT MODIFY. */ |
| /* |
| ******************************************************************************* |
| * Copyright (C) 1996-2015, International Business Machines Corporation and |
| * others. All Rights Reserved. |
| ******************************************************************************* |
| * |
| */ |
| |
| package android.icu.dev.test.serializable; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.ObjectInputStream; |
| import java.net.JarURLConnection; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.Enumeration; |
| import java.util.MissingResourceException; |
| import java.util.jar.JarEntry; |
| import java.util.jar.JarFile; |
| |
| import android.icu.dev.test.TestFmwk; |
| import org.junit.runner.RunWith; |
| import android.icu.junit.IcuTestFmwkRunner; |
| |
| /** |
| * @author emader |
| */ |
| @RunWith(IcuTestFmwkRunner.class) |
| public class CompatibilityTest extends TestFmwk |
| { |
| public class FolderTarget extends Target |
| { |
| private Target head = new Target(null); |
| private Target tail = head; |
| |
| public FolderTarget(String name) |
| { |
| super(name); |
| } |
| |
| public void add(String className, InputStream is) |
| { |
| HandlerTarget newTarget = new HandlerTarget(className, is); |
| |
| tail.setNext(newTarget); |
| tail = newTarget; |
| } |
| |
| protected boolean validate() |
| { |
| return true; |
| } |
| |
| protected void execute() throws Exception |
| { |
| params.indentLevel += 1; |
| |
| for (Target target = head.getNext(); target != null; target = target.getNext()) |
| { |
| target.run(); |
| } |
| |
| params.indentLevel -= 1; |
| } |
| } |
| |
| public class HandlerTarget extends Target |
| { |
| protected SerializableTest.Handler handler = null; |
| protected InputStream inputStream = null; |
| |
| public HandlerTarget(String name, InputStream is) |
| { |
| super(name); |
| inputStream = is; |
| } |
| |
| protected boolean validate() |
| { |
| handler = SerializableTest.getHandler(name); |
| |
| return handler != null; |
| } |
| |
| protected void execute() throws Exception |
| { |
| try { |
| if (params.inDocMode()) { |
| // nothing to execute |
| } else if (!params.stack.included) { |
| ++params.invalidCount; |
| } else { |
| params.testCount += 1; |
| |
| try { |
| ObjectInputStream in = new ObjectInputStream(inputStream); |
| Object inputObjects[] = (Object[]) in.readObject(); |
| Object testObjects[] = handler.getTestObjects(); |
| |
| in.close(); |
| inputStream.close(); |
| |
| // TODO: add equality test... |
| // The commented out code below does that, |
| // but some test objects don't define an equals() method, |
| // and the default method is the same as the "==" operator... |
| for (int i = 0; i < testObjects.length; i += 1) { |
| // if (! inputObjects[i].equals(testObjects[i])) { |
| // errln("Input object " + i + " failed equality test."); |
| // } |
| |
| if (!handler.hasSameBehavior(inputObjects[i], testObjects[i])) { |
| warnln("Input object " + i + " failed behavior test."); |
| } |
| } |
| } catch (MissingResourceException e) { |
| warnln("Could not load the data. " + e.getMessage()); |
| // Android patch: Work-around for ClassNotFoundException. |
| } catch (ClassNotFoundException e) { |
| warnln("Could not load the data. " + e.getMessage()); |
| // Android patch end. |
| } catch (Exception e) { |
| e.printStackTrace(); |
| errln("Exception: " + e.toString()); |
| } |
| } |
| } finally { |
| inputStream.close(); |
| inputStream = null; |
| } |
| } |
| } |
| |
| private static final String[][] SKIP_CASES = { |
| // ICU 52+ PluralRules/PluralFormat/CurrencyPluralInfo are not |
| // serialization-compatible with previous versions. |
| {"ICU_50.1", "android.icu.text.CurrencyPluralInfo.dat"}, |
| {"ICU_51.1", "android.icu.text.CurrencyPluralInfo.dat"}, |
| |
| {"ICU_50.1", "android.icu.text.PluralFormat.dat"}, |
| {"ICU_51.1", "android.icu.text.PluralFormat.dat"}, |
| |
| {"ICU_50.1", "android.icu.text.PluralRules.dat"}, |
| {"ICU_51.1", "android.icu.text.PluralRules.dat"}, |
| |
| // GeneralMeasureFormat was in technical preview, but is going away after ICU 52.1. |
| {"ICU_52.1", "android.icu.text.GeneralMeasureFormat.dat"}, |
| |
| // RuleBasedNumberFormat |
| {"ICU_3.6", "android.icu.text.RuleBasedNumberFormat.dat"}, |
| |
| // ICU 4.8+ MessageFormat is not serialization-compatible with previous versions. |
| {"ICU_3.6", "android.icu.text.MessageFormat.dat"}, |
| }; |
| |
| private Target getFileTargets(URL fileURL) |
| { |
| File topDir = new File(fileURL.getPath()); |
| File dataDirs[] = topDir.listFiles(); |
| FolderTarget target = null; |
| |
| for (int d = 0; d < dataDirs.length; d += 1) { |
| File dataDir = dataDirs[d]; |
| |
| if (dataDir.isDirectory()) { |
| FolderTarget newTarget = new FolderTarget(dataDir.getName()); |
| File files[] = dataDir.listFiles(); |
| |
| newTarget.setNext(target); |
| target = newTarget; |
| |
| String dataDirName = dataDir.getName(); |
| |
| element_loop: |
| for (int i = 0; i < files.length; i += 1) { |
| File file = files[i]; |
| String filename = file.getName(); |
| int ix = filename.indexOf(".dat"); |
| |
| if (ix > 0) { |
| String className = filename.substring(0, ix); |
| |
| // Skip some cases which do not work well |
| for (int j = 0; j < SKIP_CASES.length; j++) { |
| if (dataDirName.equals(SKIP_CASES[j][0]) && filename.equals(SKIP_CASES[j][1])) { |
| logln("Skipping test case - " + dataDirName + "/" + className); |
| continue element_loop; |
| } |
| } |
| |
| try { |
| @SuppressWarnings("resource") // Closed by HandlerTarget.execute(). |
| InputStream is = new FileInputStream(file); |
| target.add(className, is); |
| } catch (FileNotFoundException e) { |
| errln("Exception: " + e.toString()); |
| } |
| |
| } |
| } |
| } |
| } |
| |
| return target; |
| } |
| |
| private static InputStream copyInputStream(InputStream in) throws IOException { |
| try { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| byte[] buf = new byte[1024]; |
| while (true) { |
| int r = in.read(buf); |
| if (r == -1) { |
| break; |
| } |
| out.write(buf, 0, r); |
| } |
| return new ByteArrayInputStream(out.toByteArray()); |
| } finally { |
| in.close(); |
| } |
| } |
| |
| private Target getJarTargets(URL jarURL) |
| { |
| String prefix = jarURL.getPath(); |
| String currentDir = null; |
| int ix = prefix.indexOf("!/"); |
| FolderTarget target = null; |
| |
| if (ix >= 0) { |
| prefix = prefix.substring(ix + 2); |
| } |
| |
| try { |
| // android-changed - need to trim the directory off the JAR entry before opening the |
| // connection otherwise it could fail as it will try and find the entry within the JAR |
| // which may not exist. |
| String urlAsString = jarURL.toExternalForm(); |
| ix = urlAsString.indexOf("!/"); |
| jarURL = new URL(urlAsString.substring(0, ix + 2)); |
| // end android-changed |
| |
| JarURLConnection conn = (JarURLConnection) jarURL.openConnection(); |
| JarFile jarFile = conn.getJarFile(); |
| try { |
| Enumeration entries = jarFile.entries(); |
| element_loop: |
| while (entries.hasMoreElements()) { |
| JarEntry entry = (JarEntry) entries.nextElement(); |
| String name = entry.getName(); |
| |
| if (name.startsWith(prefix)) { |
| name = name.substring(prefix.length()); |
| |
| if (!entry.isDirectory()) { |
| int dx = name.lastIndexOf("/"); |
| String dirName = name.substring(1, dx); |
| String filename = name.substring(dx + 1); |
| |
| if (!dirName.equals(currentDir)) { |
| currentDir = dirName; |
| |
| FolderTarget newTarget = new FolderTarget(currentDir); |
| |
| newTarget.setNext(target); |
| target = newTarget; |
| } |
| |
| int xx = filename.indexOf(".dat"); |
| |
| if (xx > 0) { |
| String className = filename.substring(0, xx); |
| |
| // Skip some cases which do not work well |
| for (int i = 0; i < SKIP_CASES.length; i++) { |
| if (dirName.equals(SKIP_CASES[i][0]) && filename.equals(SKIP_CASES[i][1])) { |
| logln("Skipping test case - " + dirName + "/" + className); |
| continue element_loop; |
| } |
| } |
| |
| // The InputStream object returned by JarFile.getInputStream() will |
| // no longer be useable after JarFile.close() has been called. It's |
| // therefore necessary to make a copy of it here. |
| target.add(className, copyInputStream(jarFile.getInputStream(entry))); |
| } |
| } |
| } |
| } |
| } finally { |
| jarFile.close(); |
| } |
| } catch (Exception e) { |
| errln("jar error: " + e.getMessage()); |
| } |
| |
| return target; |
| } |
| |
| // android-changed - need to access an actual resource file |
| /** |
| * The path to an actual data resource file in the JAR. This is needed because when the |
| * code is packaged for Android the resulting archive does not have entries for directories |
| * and so only actual resources can be found. |
| */ |
| private static final String ACTUAL_RESOURCE = "/ICU_3.6/android.icu.impl.OlsonTimeZone.dat"; |
| // end android-changed |
| |
| protected Target getTargets(String targetName) |
| { |
| // android-changed - locate an actual resource and find the containing JAR file/directory |
| // Get the URL to an actual resource and then compute the URL to the directory just in |
| // case the resources are in a JAR file that doesn't have entries for directories. |
| URL dataURL = getClass().getResource("data" + ACTUAL_RESOURCE); |
| try { |
| dataURL = new URL(dataURL.toExternalForm().replace(ACTUAL_RESOURCE, "")); |
| } catch (MalformedURLException e) { |
| throw new RuntimeException(e); |
| } |
| // end android-changed |
| String protocol = dataURL.getProtocol(); |
| |
| if (protocol.equals("jar")) { |
| return getJarTargets(dataURL); |
| } else if (protocol.equals("file")) { |
| return getFileTargets(dataURL); |
| } else { |
| errln("Don't know how to test " + dataURL); |
| return null; |
| } |
| } |
| |
| public static void main(String[] args) |
| { |
| CompatibilityTest test = new CompatibilityTest(); |
| |
| test.run(args); |
| } |
| } |