ICU-7273 add loading of custom data, with caching and test code (test data was included in the latest testdata.jar update)

X-SVN-Rev: 27594
This commit is contained in:
Markus Scherer 2010-02-18 18:50:23 +00:00
parent 049b68b40b
commit 72c8f9620c
2 changed files with 126 additions and 24 deletions

View file

@ -8,6 +8,10 @@ package com.ibm.icu.impl;
import java.io.InputStream;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.MissingResourceException;
import com.ibm.icu.text.Normalizer;
import com.ibm.icu.text.Normalizer2;
@ -304,17 +308,49 @@ public final class Norm2AllModes {
} else if(name.equals("nfkc_cf")) {
singleton=NFKC_CFSingleton.INSTANCE;
} else {
throw new UnsupportedOperationException(); // TODO
singleton=null;
}
if(singleton.ioException!=null) {
throw singleton.ioException;
} else if(singleton.runtimeException!=null) {
throw singleton.runtimeException;
if(singleton!=null) {
if(singleton.ioException!=null) {
throw singleton.ioException;
} else if(singleton.runtimeException!=null) {
throw singleton.runtimeException;
}
return singleton.allModes;
}
return singleton.allModes;
}
throw new UnsupportedOperationException(); // TODO
Norm2AllModes allModes=null;
synchronized(Norm2AllModes.class) {
if(cache!=null) {
allModes=cache.get(name).get();
}
}
if(allModes==null) {
if(data==null) {
throw new MissingResourceException(
"No Normalizer2 data name \""+name+"\" cached, and InputStream is null",
"Normalizer2",
name);
}
Normalizer2Impl impl=new Normalizer2Impl().load(data);
allModes=new Norm2AllModes(impl);
synchronized(Norm2AllModes.class) {
if(cache==null) {
cache=new HashMap<String, SoftReference<Norm2AllModes>>();
}
Reference<Norm2AllModes> ref=cache.get(name);
Norm2AllModes temp;
if(ref==null || (temp=ref.get())==null) {
cache.put(name, new SoftReference<Norm2AllModes>(allModes));
} else {
// race condition
allModes=temp;
}
}
}
return allModes;
}
private static HashMap<String, SoftReference<Norm2AllModes>> cache;
public static final NoopNormalizer2 NOOP_NORMALIZER2=new NoopNormalizer2();
/**
@ -328,20 +364,16 @@ public final class Norm2AllModes {
}
private static final class Norm2AllModesSingleton {
private Norm2AllModesSingleton(InputStream data, String name) {
Normalizer2Impl impl;
if(data==null) {
try {
impl=new Normalizer2Impl().load(ICUResourceBundle.ICU_BUNDLE+"/"+name+".nrm");
allModes=new Norm2AllModes(impl);
} catch(IOException e) {
ioException=e;
runtimeException=new RuntimeException(e);
} catch(RuntimeException e) {
runtimeException=e;
}
} else {
throw new UnsupportedOperationException(); // TODO
private Norm2AllModesSingleton(String name) {
try {
Normalizer2Impl impl=new Normalizer2Impl().load(
ICUResourceBundle.ICU_BUNDLE+"/"+name+".nrm");
allModes=new Norm2AllModes(impl);
} catch(IOException e) {
ioException=e;
runtimeException=new RuntimeException(e);
} catch(RuntimeException e) {
runtimeException=e;
}
}
@ -350,12 +382,12 @@ public final class Norm2AllModes {
private RuntimeException runtimeException;
}
private static final class NFCSingleton {
private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton(null, "nfc");
private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton("nfc");
}
private static final class NFKCSingleton {
private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton(null, "nfkc");
private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton("nfkc");
}
private static final class NFKC_CFSingleton {
private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton(null, "nfkc_cf");
private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton("nfkc_cf");
}
}

View file

@ -7,6 +7,7 @@
package com.ibm.icu.dev.test.normalizer;
import java.io.IOException;
import java.text.StringCharacterIterator;
import java.util.Random;
@ -17,6 +18,7 @@ import com.ibm.icu.impl.USerializedSet;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.lang.*;
import com.ibm.icu.text.Normalizer;
import com.ibm.icu.text.Normalizer2;
import com.ibm.icu.text.UCharacterIterator;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.text.UnicodeSet;
@ -2845,4 +2847,72 @@ public class BasicTest extends TestFmwk {
}
}
}
public void TestCustomComp() {
String [][] pairs={
{ "\\uD801\\uE000\\uDFFE", "" },
{ "\\uD800\\uD801\\uE000\\uDFFE\\uDFFF", "\\uD7FF\\uFFFF" },
{ "\\uD800\\uD801\\uDFFE\\uDFFF", "\\uD7FF\\U000107FE\\uFFFF" },
{ "\\uE001\\U000110B9\\u0345\\u0308\\u0327", "\\uE002\\U000110B9\\u0327\\u0345" },
{ "\\uE010\\U000F0011\\uE012", "\\uE011\\uE012" },
{ "\\uE010\\U000F0011\\U000F0011\\uE012", "\\uE011\\U000F0010" },
{ "\\uE111\\u1161\\uE112\\u1162", "\\uAE4C\\u1102\\u0062\\u1162" },
{ "\\uFFF3\\uFFF7\\U00010036\\U00010077", "\\U00010037\\U00010037\\uFFF6\\U00010037" }
};
Normalizer2 customNorm2;
try {
customNorm2=
Normalizer2.getInstance(
BasicTest.class.getResourceAsStream("/com/ibm/icu/dev/data/testdata/testnorm.nrm"),
"testnorm",
Normalizer2.Mode.COMPOSE);
} catch(IOException e) {
errln("testdata/testnorm.nrm is not available: "+e.getMessage());
return;
}
for(int i=0; i<pairs.length; ++i) {
String[] pair=pairs[i];
String input=Utility.unescape(pair[0]);
String expected=Utility.unescape(pair[1]);
String result=customNorm2.normalize(input);
if(!result.equals(expected)) {
errln("custom compose Normalizer2 did not normalize input "+i+" as expected");
}
}
}
public void TestCustomFCC() {
String[][] pairs={
{ "\\uD801\\uE000\\uDFFE", "" },
{ "\\uD800\\uD801\\uE000\\uDFFE\\uDFFF", "\\uD7FF\\uFFFF" },
{ "\\uD800\\uD801\\uDFFE\\uDFFF", "\\uD7FF\\U000107FE\\uFFFF" },
// The following expected result is different from CustomComp
// because of only-contiguous composition.
{ "\\uE001\\U000110B9\\u0345\\u0308\\u0327", "\\uE001\\U000110B9\\u0327\\u0308\\u0345" },
{ "\\uE010\\U000F0011\\uE012", "\\uE011\\uE012" },
{ "\\uE010\\U000F0011\\U000F0011\\uE012", "\\uE011\\U000F0010" },
{ "\\uE111\\u1161\\uE112\\u1162", "\\uAE4C\\u1102\\u0062\\u1162" },
{ "\\uFFF3\\uFFF7\\U00010036\\U00010077", "\\U00010037\\U00010037\\uFFF6\\U00010037" }
};
Normalizer2 customNorm2;
try {
customNorm2=
Normalizer2.getInstance(
BasicTest.class.getResourceAsStream("/com/ibm/icu/dev/data/testdata/testnorm.nrm"),
"testnorm",
Normalizer2.Mode.COMPOSE_CONTIGUOUS);
} catch(IOException e) {
errln("testdata/testnorm.nrm is not available: "+e.getMessage());
return;
}
for(int i=0; i<pairs.length; ++i) {
String[] pair=pairs[i];
String input=Utility.unescape(pair[0]);
String expected=Utility.unescape(pair[1]);
String result=customNorm2.normalize(input);
if(!result.equals(expected)) {
errln("custom FCC Normalizer2 did not normalize input "+i+" as expected");
}
}
}
}