ICU-4567 DataDrivenCalendarTest for J

X-SVN-Rev: 22348
This commit is contained in:
Steven R. Loomis 2007-08-10 22:08:56 +00:00
parent 1df115616d
commit 7849815922
8 changed files with 714 additions and 121 deletions

3
.gitattributes vendored
View File

@ -205,6 +205,7 @@ icu4j/src/com/ibm/icu/charset/CharsetUTF7.java -text
icu4j/src/com/ibm/icu/dev/data/rbbi/english.dict -text
icu4j/src/com/ibm/icu/dev/data/testdata.jar -text
icu4j/src/com/ibm/icu/dev/data/thai6.ucs -text
icu4j/src/com/ibm/icu/dev/test/calendar/DataDrivenCalendarTest.java -text
icu4j/src/com/ibm/icu/dev/test/calendar/IndianTest.java -text
icu4j/src/com/ibm/icu/dev/test/duration/DataReadWriteTest.java -text
icu4j/src/com/ibm/icu/dev/test/duration/ICUDurationTest.java -text
@ -293,9 +294,11 @@ icu4j/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.TimeZo
icu4j/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.ULocale.dat -text
icu4j/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.UResourceTypeMismatchException.dat -text
icu4j/src/com/ibm/icu/dev/test/timezone/TimeZoneRuleTest.java -text
icu4j/src/com/ibm/icu/dev/test/util/CalendarFieldsSet.java -text
icu4j/src/com/ibm/icu/dev/test/util/DebugUtilities.java -text
icu4j/src/com/ibm/icu/dev/test/util/DebugUtilitiesData.java -text
icu4j/src/com/ibm/icu/dev/test/util/DebugUtilitiesTest.java -text
icu4j/src/com/ibm/icu/dev/test/util/FieldsSet.java -text
icu4j/src/com/ibm/icu/dev/test/util/PrettyPrinter.java -text
icu4j/src/com/ibm/icu/dev/tool/docs/icu4j28.api.gz -text
icu4j/src/com/ibm/icu/dev/tool/docs/icu4j30.api.gz -text

View File

@ -23,7 +23,7 @@ import com.ibm.icu.dev.test.TestDataModule.TestData;
* Tests can implement this if they make extensive use of information in a
* TestDataModule.
*
* Subclasses can allow for test methods that don't use data from the modeul by
* Subclasses can allow for test methods that don't use data from the module by
* overriding validateMethod to return true for these methods. Tests are also
* free to instantiate their own modules and run from them, though care should
* be taken not to interfere with the methods in this class.

View File

@ -405,7 +405,14 @@ class ResourceModule implements TestDataModule {
}
public String getString(String key) {
return (String)theMap.get(key);
Object o = theMap.get(key);
UResourceBundle rb;
if(o instanceof UResourceBundle) {
// unpack ResourceBundle strings
rb = (UResourceBundle)o;
return rb.getString();
}
return (String)o;
}
public Object getObject(String key) {
return theMap.get(key);

View File

@ -0,0 +1,268 @@
/*
*******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.dev.test.calendar;
import java.util.Date;
import java.util.Iterator;
import com.ibm.icu.dev.test.ModuleTest;
import com.ibm.icu.dev.test.TestDataModule;
import com.ibm.icu.dev.test.TestDataModule.DataMap;
import com.ibm.icu.dev.test.util.CalendarFieldsSet;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;
/**
* @author srl
*
* analog of dadrcal.cpp
*
*/
public class DataDrivenCalendarTest extends ModuleTest {
public DataDrivenCalendarTest() {
super("com/ibm/icu/dev/data/testdata/", "calendar");
}
/* (non-Javadoc)
* @see com.ibm.icu.dev.test.ModuleTest#processModules()
*/
public void processModules() {
//String testName = t.getName().toString();
for (Iterator siter = t.getSettingsIterator(); siter.hasNext();) {
// Iterate through and get each of the test case to process
DataMap settings = (DataMap) siter.next();
String type = settings.getString("Type");
if(type.equals("convert_fwd")) {
testConvert(t, settings, true);
} else if(type.equals("convert_rev")) {
testConvert(t, settings, false);
} else if(type.equals("ops")) {
testOps(t, settings);
} else {
errln("Unknown type: " + type);
}
}
}
void testConvert(String caseString,
CalendarFieldsSet fromSet, Calendar fromCalendar,
CalendarFieldsSet toSet, Calendar toCalendar, boolean forward) {
String thisString = caseString+(forward ? "forward"
: "reverse")+" "+fromCalendar.getType()+"->"+toCalendar.getType()+" ";
fromCalendar.clear();
fromSet.setOnCalendar(fromCalendar);
CalendarFieldsSet diffSet = new CalendarFieldsSet();
diffSet.clear();
// Is the calendar sane at the first?
if (!fromSet.matches(fromCalendar, diffSet)) {
String diffs = diffSet.diffFrom(fromSet);
errln((String)"FAIL: "+thisString
+", SOURCE calendar was not set: Differences: "+ diffs);
} else {
logln("PASS: "+thisString+" SOURCE calendar match.");
}
//logln("Set Source calendar: " + from);
Date fromTime = fromCalendar.getTime();
diffSet.clear();
// Is the calendar sane after being set?
if (!fromSet.matches(fromCalendar, diffSet)) {
String diffs = diffSet.diffFrom(fromSet);
errln((String)"FAIL: "+thisString
+", SET SOURCE calendar was not set: Differences: "+ diffs);
} else {
logln("PASS: "+thisString+" SET SOURCE calendar match.");
}
toCalendar.clear();
toCalendar.setTime(fromTime);
diffSet.clear();
if (!toSet.matches(toCalendar, diffSet)) {
String diffs = diffSet.diffFrom(toSet);
errln((String)"FAIL: "+thisString+", Differences: "+ diffs);
DateFormat fmt = new SimpleDateFormat(new String("EEE MMM dd yyyy G"));
String fromString = fmt.format(fromTime);
logln("Source Time: "+fromString+", Source Calendar: "
+fromCalendar.getType());
} else {
logln("PASS: "+thisString+" match.");
}
}
private void testConvert(TestDataModule.TestData testData, DataMap settings, boolean forward) {
Calendar toCalendar= null;
// build to calendar
String testSetting = settings.getString("ToCalendar");
ULocale loc = new ULocale(testSetting);
toCalendar = Calendar.getInstance(loc);
CalendarFieldsSet fromSet = new CalendarFieldsSet(), toSet = new CalendarFieldsSet();
// DateFormat fmt = new SimpleDateFormat("EEE MMM dd yyyy / YYYY'-W'ww-ee");
// Start the processing
int n = 0;
for (Iterator iter = testData.getDataIterator(); iter.hasNext();) {
++n;
DataMap currentCase = (DataMap) iter.next();
String caseString = "["+testData.getName()+"#"+n+" "+"]";
String locale = testSetting = currentCase.getString("locale");
ULocale fromLoc = new ULocale(testSetting);
Calendar fromCalendar = Calendar.getInstance(fromLoc);
fromSet.clear();
toSet.clear();
String from = currentCase.getString("from");
fromSet.parseFrom(from);
String to = currentCase.getString("to");
toSet.parseFrom(to, fromSet);
// now, do it.
if (forward) {
logln(caseString +" "+locale+"/"+from+" >>> "+loc+"/"
+to);
testConvert(caseString, fromSet, fromCalendar, toSet, toCalendar, forward);
} else {
logln(caseString +" "+locale+"/"+from+" <<< "+loc+"/"
+to);
testConvert(caseString, toSet, toCalendar, fromSet, fromCalendar, forward);
}
}
}
private static final String kADD = "add";
private static final String kROLL = "roll";
private void testOps(TestDataModule.TestData testData, DataMap settings) {
// Get 'from' time
CalendarFieldsSet fromSet = new CalendarFieldsSet(), toSet = new CalendarFieldsSet(), paramsSet = new CalendarFieldsSet(), diffSet = new CalendarFieldsSet();
// DateFormat fmt = new SimpleDateFormat("EEE MMM dd yyyy / YYYY'-W'ww-ee");
// Start the processing
int n = 0;
for (Iterator iter = testData.getDataIterator(); iter.hasNext();) {
++n;
DataMap currentCase = (DataMap) iter.next();
String caseString = "[case "+n+"]";
// build to calendar
// Headers { "locale","from","operation","params","to" }
// #1 locale
String param = "locale";
String locale;
String testSetting = currentCase.getString(param);
locale = testSetting;
ULocale loc = new ULocale(locale);
Calendar fromCalendar = Calendar.getInstance(loc);
fromSet.clear();
// #2 'from' info
param = "from";
String from = testSetting=currentCase.getString(param);
fromSet.parseFrom(testSetting);
// System.err.println("fromset: ["+testSetting+"] >> " + fromSet);
// #4 'operation' info
param = "operation";
String operation = testSetting=currentCase.getString(param);
paramsSet.clear();
// #3 'params' info
param = "params";
String paramsData = testSetting = currentCase.getString(param);
paramsSet.parseFrom(paramsData); // parse with inheritance.
// System.err.println("paramsSet: ["+testSetting+"] >> " + paramsSet);
toSet.clear();
// #4 'to' info
param = "to";
String to = testSetting=currentCase.getString(param);
toSet.parseFrom(testSetting, fromSet); // parse with inheritance.
// System.err.println("toSet: ["+testSetting+"] >> " + toSet);
String caseContentsString = locale+": from "+from+": "
+operation +" [[[ "+paramsSet+" ]]] >>> "+to;
logln(caseString+": "+caseContentsString);
// ------
// now, do it.
/// prepare calendar
fromSet.setOnCalendar(fromCalendar);
// from calendar: 'starting date'
diffSet.clear();
// Is the calendar sane after being set?
if (!fromSet.matches(fromCalendar, diffSet)) {
String diffs = diffSet.diffFrom(fromSet);
errln((String)"FAIL: "+caseString
+", SET SOURCE calendar was not set: Differences: "+ diffs);
} else {
logln(" "+caseString+" SET SOURCE calendar match."); // verifies that the requested fields were set.
}
// to calendar - copy of from calendar
Calendar toCalendar = (Calendar)fromCalendar.clone();
/// perform op on 'to calendar'
for (int q=0; q<paramsSet.fieldCount(); q++) {
if (paramsSet.isSet(q)) {
if (operation.equals(kROLL)) {
toCalendar.roll(q,
paramsSet.get(q));
} else if (operation.equals(kADD)) {
toCalendar.add(q,
paramsSet.get(q));
} else {
errln(caseString+ " FAIL: unknown operation "+ operation);
}
logln(operation + " of "+ paramsSet.get(q));
}
}
// now - what's the result?
diffSet.clear();
// toset contains 'expected'
if (!toSet.matches(toCalendar, diffSet)) {
String diffs = diffSet.diffFrom(toSet);
errln((String)"FAIL: "+caseString+" - , "+caseContentsString
+" Differences: "+ diffs );
} else {
logln("PASS: "+caseString+" matched! ");
}
}
}
/**
* @param args
*/
public static void main(String[] args) throws Exception {
new DataDrivenCalendarTest().run(args);
}
}

View File

@ -29,7 +29,8 @@ public class TestAll extends TestGroup {
"JapaneseTest",
"ChineseTest",
"IndianTest",
"HolidayTest"
"HolidayTest",
"DataDrivenCalendarTest"
},
"Calendars, Holiday, and Astro tests"
);

View File

@ -0,0 +1,58 @@
/*
*******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.dev.test.util;
import com.ibm.icu.util.Calendar;
/**
* @author srl
*
*/
public class CalendarFieldsSet extends FieldsSet {
/**
* @param whichEnum
* @param fieldsCount
*/
public CalendarFieldsSet() {
super(DebugUtilitiesData.UCalendarDateFields,-1);
}
public boolean matches(Calendar cal, CalendarFieldsSet diffSet) {
boolean match = true;
for(int i=0;i<fieldCount();i++) {
if(isSet(i)) {
int calVal = cal.get(i);
if(calVal != get(i)) {
match = false;
diffSet.set(i, calVal);
}
}
}
return match;
}
/**
* set the specified fields on this calendar. Doesn't clear first. Returns any errors the cale
*/
public void setOnCalendar(Calendar cal) {
for(int i=0;i<fieldCount();i++) {
if(isSet(i)) {
cal.set(i, get(i));
}
}
}
protected void handleParseValue(FieldsSet inheritFrom, int field, String substr) {
if(field == Calendar.MONTH) {
parseValueEnum(DebugUtilitiesData.UCalendarMonths, inheritFrom, field, substr);
// will fallback to default.
} else {
parseValueDefault(inheritFrom, field, substr);
}
}
}

View File

@ -1,118 +1,136 @@
/** Copyright (C) 2007, International Business Machines Corporation and Others. All Rights Reserved. **/
/* NOTE: this file is AUTOMATICALLY GENERATED by gentest. */
package com.ibm.icu.dev.test.util;
public class DebugUtilitiesData extends Object {
public static final String ICU4C_VERSION="3.8";
public static final int UDebugEnumType = 0;
public static final int UCalendarDateFields = 1;
public static final int UCalendarMonths = 2;
public static final String [] TYPES = {
"UDebugEnumType", /* 0 */
"UCalendarDateFields", /* 1 */
"UCalendarMonths", /* 2 */
};
public static final String [][] NAMES = {
/* UDebugEnumType, 0 */
{
"UDebugEnumType", /* 0 */
"UCalendarDateFields", /* 1 */
"UCalendarMonths", /* 2 */
},
/* UCalendarDateFields, 1 */
{
"ERA", /* 0 */
"YEAR", /* 1 */
"MONTH", /* 2 */
"WEEK_OF_YEAR", /* 3 */
"WEEK_OF_MONTH", /* 4 */
"DATE", /* 5 */
"DAY_OF_YEAR", /* 6 */
"DAY_OF_WEEK", /* 7 */
"DAY_OF_WEEK_IN_MONTH", /* 8 */
"AM_PM", /* 9 */
"HOUR", /* 10 */
"HOUR_OF_DAY", /* 11 */
"MINUTE", /* 12 */
"SECOND", /* 13 */
"MILLISECOND", /* 14 */
"ZONE_OFFSET", /* 15 */
"DST_OFFSET", /* 16 */
"YEAR_WOY", /* 17 */
"DOW_LOCAL", /* 18 */
"EXTENDED_YEAR", /* 19 */
"JULIAN_DAY", /* 20 */
"MILLISECONDS_IN_DAY", /* 21 */
},
/* UCalendarMonths, 2 */
{
"JANUARY", /* 0 */
"FEBRUARY", /* 1 */
"MARCH", /* 2 */
"APRIL", /* 3 */
"MAY", /* 4 */
"JUNE", /* 5 */
"JULY", /* 6 */
"AUGUST", /* 7 */
"SEPTEMBER", /* 8 */
"OCTOBER", /* 9 */
"NOVEMBER", /* 10 */
"DECEMBER", /* 11 */
"UNDECIMBER", /* 12 */
},
};
public static final int [][] VALUES = {
/* UDebugEnumType, 0 */
{
0, /* UDebugEnumType */
1, /* UCalendarDateFields */
2, /* UCalendarMonths */
},
/* UCalendarDateFields, 1 */
{
com.ibm.icu.util.Calendar.ERA, /* 0 */
com.ibm.icu.util.Calendar.YEAR, /* 1 */
com.ibm.icu.util.Calendar.MONTH, /* 2 */
com.ibm.icu.util.Calendar.WEEK_OF_YEAR, /* 3 */
com.ibm.icu.util.Calendar.WEEK_OF_MONTH, /* 4 */
com.ibm.icu.util.Calendar.DATE, /* 5 */
com.ibm.icu.util.Calendar.DAY_OF_YEAR, /* 6 */
com.ibm.icu.util.Calendar.DAY_OF_WEEK, /* 7 */
com.ibm.icu.util.Calendar.DAY_OF_WEEK_IN_MONTH, /* 8 */
com.ibm.icu.util.Calendar.AM_PM, /* 9 */
com.ibm.icu.util.Calendar.HOUR, /* 10 */
com.ibm.icu.util.Calendar.HOUR_OF_DAY, /* 11 */
com.ibm.icu.util.Calendar.MINUTE, /* 12 */
com.ibm.icu.util.Calendar.SECOND, /* 13 */
com.ibm.icu.util.Calendar.MILLISECOND, /* 14 */
com.ibm.icu.util.Calendar.ZONE_OFFSET, /* 15 */
com.ibm.icu.util.Calendar.DST_OFFSET, /* 16 */
com.ibm.icu.util.Calendar.YEAR_WOY, /* 17 */
com.ibm.icu.util.Calendar.DOW_LOCAL, /* 18 */
com.ibm.icu.util.Calendar.EXTENDED_YEAR, /* 19 */
com.ibm.icu.util.Calendar.JULIAN_DAY, /* 20 */
com.ibm.icu.util.Calendar.MILLISECONDS_IN_DAY, /* 21 */
},
/* UCalendarMonths, 2 */
{
com.ibm.icu.util.Calendar.JANUARY, /* 0 */
com.ibm.icu.util.Calendar.FEBRUARY, /* 1 */
com.ibm.icu.util.Calendar.MARCH, /* 2 */
com.ibm.icu.util.Calendar.APRIL, /* 3 */
com.ibm.icu.util.Calendar.MAY, /* 4 */
com.ibm.icu.util.Calendar.JUNE, /* 5 */
com.ibm.icu.util.Calendar.JULY, /* 6 */
com.ibm.icu.util.Calendar.AUGUST, /* 7 */
com.ibm.icu.util.Calendar.SEPTEMBER, /* 8 */
com.ibm.icu.util.Calendar.OCTOBER, /* 9 */
com.ibm.icu.util.Calendar.NOVEMBER, /* 10 */
com.ibm.icu.util.Calendar.DECEMBER, /* 11 */
com.ibm.icu.util.Calendar.UNDECIMBER, /* 12 */
},
};
}
/** Copyright (C) 2007, International Business Machines Corporation and Others. All Rights Reserved. **/
/* NOTE: this file is AUTOMATICALLY GENERATED by gentest. */
package com.ibm.icu.dev.test.util;
public class DebugUtilitiesData extends Object {
public static final String ICU4C_VERSION="3.8";
public static final int UDebugEnumType = 0;
public static final int UCalendarDateFields = 1;
public static final int UCalendarMonths = 2;
public static final int UDateFormatStyle = 3;
public static final String [] TYPES = {
"UDebugEnumType", /* 0 */
"UCalendarDateFields", /* 1 */
"UCalendarMonths", /* 2 */
"UDateFormatStyle", /* 3 */
};
public static final String [][] NAMES = {
/* UDebugEnumType, 0 */
{
"UDebugEnumType", /* 0 */
"UCalendarDateFields", /* 1 */
"UCalendarMonths", /* 2 */
"UDateFormatStyle", /* 3 */
},
/* UCalendarDateFields, 1 */
{
"ERA", /* 0 */
"YEAR", /* 1 */
"MONTH", /* 2 */
"WEEK_OF_YEAR", /* 3 */
"WEEK_OF_MONTH", /* 4 */
"DATE", /* 5 */
"DAY_OF_YEAR", /* 6 */
"DAY_OF_WEEK", /* 7 */
"DAY_OF_WEEK_IN_MONTH", /* 8 */
"AM_PM", /* 9 */
"HOUR", /* 10 */
"HOUR_OF_DAY", /* 11 */
"MINUTE", /* 12 */
"SECOND", /* 13 */
"MILLISECOND", /* 14 */
"ZONE_OFFSET", /* 15 */
"DST_OFFSET", /* 16 */
"YEAR_WOY", /* 17 */
"DOW_LOCAL", /* 18 */
"EXTENDED_YEAR", /* 19 */
"JULIAN_DAY", /* 20 */
"MILLISECONDS_IN_DAY", /* 21 */
},
/* UCalendarMonths, 2 */
{
"JANUARY", /* 0 */
"FEBRUARY", /* 1 */
"MARCH", /* 2 */
"APRIL", /* 3 */
"MAY", /* 4 */
"JUNE", /* 5 */
"JULY", /* 6 */
"AUGUST", /* 7 */
"SEPTEMBER", /* 8 */
"OCTOBER", /* 9 */
"NOVEMBER", /* 10 */
"DECEMBER", /* 11 */
"UNDECIMBER", /* 12 */
},
/* UDateFormatStyle, 3 */
{
"FULL", /* 0 */
"LONG", /* 1 */
"MEDIUM", /* 2 */
"SHORT", /* 3 */
},
};
public static final int [][] VALUES = {
/* UDebugEnumType, 0 */
{
0, /* UDebugEnumType */
1, /* UCalendarDateFields */
2, /* UCalendarMonths */
3, /* UDateFormatStyle */
},
/* UCalendarDateFields, 1 */
{
com.ibm.icu.util.Calendar.ERA, /* 0 */
com.ibm.icu.util.Calendar.YEAR, /* 1 */
com.ibm.icu.util.Calendar.MONTH, /* 2 */
com.ibm.icu.util.Calendar.WEEK_OF_YEAR, /* 3 */
com.ibm.icu.util.Calendar.WEEK_OF_MONTH, /* 4 */
com.ibm.icu.util.Calendar.DATE, /* 5 */
com.ibm.icu.util.Calendar.DAY_OF_YEAR, /* 6 */
com.ibm.icu.util.Calendar.DAY_OF_WEEK, /* 7 */
com.ibm.icu.util.Calendar.DAY_OF_WEEK_IN_MONTH, /* 8 */
com.ibm.icu.util.Calendar.AM_PM, /* 9 */
com.ibm.icu.util.Calendar.HOUR, /* 10 */
com.ibm.icu.util.Calendar.HOUR_OF_DAY, /* 11 */
com.ibm.icu.util.Calendar.MINUTE, /* 12 */
com.ibm.icu.util.Calendar.SECOND, /* 13 */
com.ibm.icu.util.Calendar.MILLISECOND, /* 14 */
com.ibm.icu.util.Calendar.ZONE_OFFSET, /* 15 */
com.ibm.icu.util.Calendar.DST_OFFSET, /* 16 */
com.ibm.icu.util.Calendar.YEAR_WOY, /* 17 */
com.ibm.icu.util.Calendar.DOW_LOCAL, /* 18 */
com.ibm.icu.util.Calendar.EXTENDED_YEAR, /* 19 */
com.ibm.icu.util.Calendar.JULIAN_DAY, /* 20 */
com.ibm.icu.util.Calendar.MILLISECONDS_IN_DAY, /* 21 */
},
/* UCalendarMonths, 2 */
{
com.ibm.icu.util.Calendar.JANUARY, /* 0 */
com.ibm.icu.util.Calendar.FEBRUARY, /* 1 */
com.ibm.icu.util.Calendar.MARCH, /* 2 */
com.ibm.icu.util.Calendar.APRIL, /* 3 */
com.ibm.icu.util.Calendar.MAY, /* 4 */
com.ibm.icu.util.Calendar.JUNE, /* 5 */
com.ibm.icu.util.Calendar.JULY, /* 6 */
com.ibm.icu.util.Calendar.AUGUST, /* 7 */
com.ibm.icu.util.Calendar.SEPTEMBER, /* 8 */
com.ibm.icu.util.Calendar.OCTOBER, /* 9 */
com.ibm.icu.util.Calendar.NOVEMBER, /* 10 */
com.ibm.icu.util.Calendar.DECEMBER, /* 11 */
com.ibm.icu.util.Calendar.UNDECIMBER, /* 12 */
},
/* UDateFormatStyle, 3 */
{
0, /* FULL */
1, /* LONG */
2, /* MEDIUM */
3, /* SHORT */
},
};
}

View File

@ -0,0 +1,238 @@
/*
*******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.dev.test.util;
/**
* @author srl
*
* analog of FieldsSet in C++
*/
public class FieldsSet {
public static final int NO_ENUM = -1;
protected FieldsSet(int whichEnum, int fieldsCount) {
if (fieldsCount <= 0 && whichEnum != NO_ENUM) {
fieldsCount = DebugUtilities.enumCount(whichEnum);
}
fEnum = whichEnum;
fFieldsCount = fieldsCount;
if(fieldsCount<0) {
throw new InternalError("Preposterous field count " + fieldsCount);
}
fValues = new int[fFieldsCount];
fIsSet = new boolean[fFieldsCount];
clear();
}
protected int fEnum = NO_ENUM;
protected int fFieldsCount = 0;
protected int fValues[] = null;
protected boolean fIsSet[] = null;
public void clear() {
for (int i = 0; i < fFieldsCount; i++) {
clear(i);
}
}
public void clear(int field) {
fValues[field] = -1;
fIsSet[field] = false;
}
public void set(int field, int amount) {
fValues[field] = amount;
fIsSet[field] = true;
}
public boolean isSet(int field) {
return fIsSet[field];
}
public int get(int field) {
if (fIsSet[field]) {
return fValues[field];
} else {
return -1;
}
}
public boolean isSameType(FieldsSet other) {
return ((other.fEnum == fEnum) && (other.fFieldsCount == fFieldsCount));
}
public int fieldCount() {
return fFieldsCount;
}
/**
* @param other "expected" set to match against
* @return a formatted string listing which fields are set in this, with the
* comparison made agaainst those fields in other, or, 'null' if there is no difference.
*/
public String diffFrom(FieldsSet other) {
StringBuffer str = new StringBuffer();
if(!isSameType(other)) {
throw new IllegalArgumentException("U_ILLEGAL_ARGUMENT_ERROR: FieldsSet of a different type!");
}
for (int i=0; i<fieldCount(); i++) {
if (isSet(i)) {
int myVal = get(i);
int theirVal = other.get(i);
if(fEnum != NO_ENUM) {
String fieldName = DebugUtilities.enumString(fEnum, i);
String aval = Integer.toString(myVal);
String bval = Integer.toString(theirVal);
str.append(fieldName +"="+aval+" not "+bval+", ");
} else {
str.append(Integer.toString(i) + "=" + myVal+" not " + theirVal+", ");
}
}
}
if(str.length()==0) {
return null;
}
return str.toString();
}
/**
* @param str string to parse
* @param status formatted string for status
*/
public int parseFrom(String str) {
return parseFrom(str, null);
}
public int parseFrom(String str, FieldsSet inheritFrom) {
int goodFields = 0;
String[] fields = str.split(",");
for(int i=0;i<fields.length;i++) {
String fieldStr = fields[i];
String kv[] = fieldStr.split("=");
if(kv.length < 1 || kv.length > 2) {
throw new InternalError("split around '=' failed: " + fieldStr);
}
String key = kv[0];
String value = "";
if(kv.length>1) {
value = kv[1];
}
int field = handleParseName(inheritFrom, key, value);
if(field != -1) {
handleParseValue(inheritFrom, field, value);
goodFields++;
}
}
return goodFields;
}
/**
* Callback interface for subclass. This function is called when parsing a
* field name, such as "MONTH" in "MONTH=4". Base implementation is to
* lookup the enum value using udbg_* utilities, or else as an integer if
* enum is not available.
*
* If there is a special directive, the implementer can catch it here and
* return -1 after special processing completes.
*
* @param inheritFrom the set inheriting from - may be null.
* @param name the field name (key side)
* @param substr the string in question (value side)
* @param status error status - set to error for failure.
* @return field number, or negative if field should be skipped.
*/
protected int handleParseName(FieldsSet inheritFrom, String name,
String substr) {
int field = -1;
if(fEnum != NO_ENUM) {
field = DebugUtilities.enumByString(fEnum, name);
}
if(field < 0) {
field = Integer.parseInt(name);
}
return field;
}
/**
* Callback interface for subclass. Base implementation is to call
* parseValueDefault(...)
*
* @param inheritFrom the set inheriting from - may be null.
* @param field which field is being parsed
* @param substr the string in question (value side)
* @param status error status - set to error for failure.
* @see parseValueDefault
*/
protected void handleParseValue(FieldsSet inheritFrom, int field,
String substr) {
parseValueDefault(inheritFrom, field, substr);
}
/**
* the default implementation for handleParseValue. Base implementation is
* to parse a decimal integer value, or inherit from inheritFrom if the
* string is 0-length. Implementations of this function should call
* set(field,...) on successful parse.
*
* @see handleParseValue
*/
protected void parseValueDefault(FieldsSet inheritFrom, int field,
String substr) {
if(substr.length()==0) {
if(inheritFrom == null) {
throw new InternalError("Trying to inherit from field " + field + " but inheritFrom is null");
}
if(!inheritFrom.isSet(field)) {
throw new InternalError("Trying to inherit from field " + field + " but inheritFrom["+field+"] is not set");
}
set(field,inheritFrom.get(field));
} else {
int value = Integer.parseInt(substr);
set(field, value);
}
}
/**
* convenience implementation for handleParseValue attempt to load a value
* from an enum value using udbg_enumByString() if fails, will call
* parseValueDefault()
*
* @see handleParseValue
*/
protected void parseValueEnum(int type, FieldsSet inheritFrom, int field,
String substr) {
int value = DebugUtilities.enumByString(type, substr);
if(value>=0) {
set(field,value);
return;
}
parseValueDefault(inheritFrom, field, substr);
}
public String fieldName(int field) {
return (fEnum!=NO_ENUM)?DebugUtilities.enumString(fEnum, field):Integer.toString(field);
}
public String toString() {
String str = getClass().getName()+" ["+fFieldsCount+","+(fEnum!=NO_ENUM?DebugUtilities.typeString(fEnum):fEnum)+"]: ";
for(int i=0;i<fFieldsCount;i++) {
if(isSet(i)) {
str = str + fieldName(i)+"="+get(i)+",";
}
}
return str;
}
}