1 package com.thaiopensource.datatype.xsd; 2 3 import java.util.Hashtable ; 4 import java.util.Enumeration ; 5 6 import com.thaiopensource.util.Service; 7 import com.thaiopensource.datatype.xsd.regex.RegexEngine; 8 import com.thaiopensource.datatype.xsd.regex.RegexSyntaxException; 9 10 import org.relaxng.datatype.DatatypeLibrary; 11 import org.relaxng.datatype.Datatype; 12 import org.relaxng.datatype.DatatypeException; 13 import org.relaxng.datatype.DatatypeBuilder; 14 15 public class DatatypeLibraryImpl implements DatatypeLibrary { 16 private final Hashtable typeTable = new Hashtable (); 17 private final RegexEngine regexEngine; 18 19 static private final String LONG_MAX = "9223372036854775807"; 20 static private final String LONG_MIN = "-9223372036854775808"; 21 static private final String INT_MAX = "2147483647"; 22 static private final String INT_MIN = "-2147483648"; 23 static private final String SHORT_MAX = "32767"; 24 static private final String SHORT_MIN = "-32768"; 25 static private final String BYTE_MAX = "127"; 26 static private final String BYTE_MIN = "-128"; 27 28 static private final String UNSIGNED_LONG_MAX = "18446744073709551615"; 29 static private final String UNSIGNED_INT_MAX = "4294967295"; 30 static private final String UNSIGNED_SHORT_MAX = "65535"; 31 static private final String UNSIGNED_BYTE_MAX = "255"; 32 static private final String LANGUAGE_PATTERN = "[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"; 34 35 public DatatypeLibraryImpl() { 36 this.regexEngine = findRegexEngine(); 37 typeTable.put("string", new StringDatatype()); 38 typeTable.put("normalizedString", new CdataDatatype()); 39 typeTable.put("token", new TokenDatatype()); 40 typeTable.put("boolean", new BooleanDatatype()); 41 42 DatatypeBase decimalType = new DecimalDatatype(); 43 typeTable.put("decimal", decimalType); 44 DatatypeBase integerType = new IntegerRestrictDatatype(decimalType); 45 typeTable.put("integer", integerType); 46 typeTable.put("nonPositiveInteger", restrictMax(integerType, "0")); 47 typeTable.put("negativeInteger", restrictMax(integerType, "-1")); 48 typeTable.put("long", restrictMax(restrictMin(integerType, LONG_MIN), LONG_MAX)); 49 typeTable.put("int", restrictMax(restrictMin(integerType, INT_MIN), INT_MAX)); 50 typeTable.put("short", restrictMax(restrictMin(integerType, SHORT_MIN), SHORT_MAX)); 51 typeTable.put("byte", restrictMax(restrictMin(integerType, BYTE_MIN), BYTE_MAX)); 52 DatatypeBase nonNegativeIntegerType = restrictMin(integerType, "0"); 53 typeTable.put("nonNegativeInteger", nonNegativeIntegerType); 54 typeTable.put("unsignedLong", restrictMax(nonNegativeIntegerType, UNSIGNED_LONG_MAX)); 55 typeTable.put("unsignedInt", restrictMax(nonNegativeIntegerType, UNSIGNED_INT_MAX)); 56 typeTable.put("unsignedShort", restrictMax(nonNegativeIntegerType, UNSIGNED_SHORT_MAX)); 57 typeTable.put("unsignedByte", restrictMax(nonNegativeIntegerType, UNSIGNED_BYTE_MAX)); 58 typeTable.put("positiveInteger", restrictMin(integerType, "1")); 59 typeTable.put("double", new DoubleDatatype()); 60 typeTable.put("float", new FloatDatatype()); 61 62 typeTable.put("Name", new NameDatatype()); 63 typeTable.put("QName", new QNameDatatype()); 64 65 DatatypeBase ncNameType = new NCNameDatatype(); 66 typeTable.put("NCName", ncNameType); 67 68 DatatypeBase nmtokenDatatype = new NmtokenDatatype(); 69 typeTable.put("NMTOKEN", nmtokenDatatype); 70 typeTable.put("NMTOKENS", list(nmtokenDatatype)); 71 72 typeTable.put("ID", new IdDatatype()); 73 DatatypeBase idrefType = new IdrefDatatype(); 74 typeTable.put("IDREF", idrefType); 75 typeTable.put("IDREFS", list(idrefType)); 76 77 typeTable.put("NOTATION", new QNameDatatype()); 78 79 typeTable.put("base64Binary", new Base64BinaryDatatype()); 80 typeTable.put("hexBinary", new HexBinaryDatatype()); 81 typeTable.put("anyURI", new AnyUriDatatype()); 82 typeTable.put("language", new RegexDatatype(LANGUAGE_PATTERN)); 83 84 typeTable.put("dateTime", new DateTimeDatatype("Y-M-DTt")); 85 typeTable.put("time", new DateTimeDatatype("t")); 86 typeTable.put("date", new DateTimeDatatype("Y-M-D")); 87 typeTable.put("gYearMonth", new DateTimeDatatype("Y-M")); 88 typeTable.put("gYear", new DateTimeDatatype("Y")); 89 typeTable.put("gMonthDay", new DateTimeDatatype("--M-D")); 90 typeTable.put("gDay", new DateTimeDatatype("---D")); 91 typeTable.put("gMonth", new DateTimeDatatype("--M")); 92 93 DatatypeBase entityType = new EntityDatatype(); 94 typeTable.put("ENTITY", entityType); 95 typeTable.put("ENTITIES", list(entityType)); 96 typeTable.put("duration", new DurationDatatype()); 98 } 99 100 public DatatypeBuilder createDatatypeBuilder(String localName) throws DatatypeException { 101 DatatypeBase base = (DatatypeBase)typeTable.get(localName); 102 if (base == null) 103 throw new DatatypeException(); 104 if (base instanceof RegexDatatype) { 105 try { 106 ((RegexDatatype)base).compile(getRegexEngine()); 107 } 108 catch (RegexSyntaxException e) { 109 throw new DatatypeException(DatatypeBuilderImpl.localizer.message("regex_internal_error", localName)); 110 } 111 } 112 return new DatatypeBuilderImpl(this, base); 113 } 114 115 RegexEngine getRegexEngine() throws DatatypeException { 116 if (regexEngine == null) 117 throw new DatatypeException(DatatypeBuilderImpl.localizer.message("regex_impl_not_found")); 118 return regexEngine; 119 } 120 121 private static DatatypeBase restrictMax(DatatypeBase base, String limit) { 122 return new MaxInclusiveRestrictDatatype(base, base.getValue(limit, null)); 123 } 124 125 private static DatatypeBase restrictMin(DatatypeBase base, String limit) { 126 return new MinInclusiveRestrictDatatype(base, base.getValue(limit, null)); 127 } 128 129 private static DatatypeBase list(DatatypeBase base) { 130 return new MinLengthRestrictDatatype(new ListDatatype(base), 1); 131 } 132 133 private static RegexEngine findRegexEngine() { 134 Enumeration e = new Service(RegexEngine.class).getProviders(); 135 if (!e.hasMoreElements()) 136 return null; 137 return (RegexEngine)e.nextElement(); 138 } 139 140 public Datatype createDatatype(String type) throws DatatypeException { 141 return createDatatypeBuilder(type).createDatatype(); 142 } 143 144 static public void main(String [] args) throws DatatypeException { 145 System.err.println(new DatatypeLibraryImpl().createDatatype(args[0]).isValid(args[1], null) 146 ? "valid" 147 : "invalid"); 148 } 149 } 150 | Popular Tags |