1 package com.thaiopensource.datatype.xsd; 2 3 import java.util.ResourceBundle ; 4 import java.text.MessageFormat ; 5 6 import org.relaxng.datatype.Datatype; 7 import org.relaxng.datatype.DatatypeBuilder; 8 import org.relaxng.datatype.ValidationContext; 9 import org.relaxng.datatype.DatatypeException; 10 import com.thaiopensource.datatype.xsd.regex.RegexSyntaxException; 11 import com.thaiopensource.util.Localizer; 12 13 class DatatypeBuilderImpl implements DatatypeBuilder { 14 static final Localizer localizer = new Localizer(DatatypeBuilderImpl.class); 15 16 private DatatypeBase base; 17 private final DatatypeLibraryImpl library; 18 19 DatatypeBuilderImpl(DatatypeLibraryImpl library, DatatypeBase base) throws DatatypeException { 20 this.library = library; 21 this.base = base; 22 } 23 24 public void addParameter(String name, 25 String value, 26 ValidationContext context) throws DatatypeException { 27 if (name.equals("pattern")) 28 addPatternParam(value); 29 else if (name.equals("minInclusive")) 30 addMinInclusiveParam(value, context); 31 else if (name.equals("maxInclusive")) 32 addMaxInclusiveParam(value, context); 33 else if (name.equals("minExclusive")) 34 addMinExclusiveParam(value, context); 35 else if (name.equals("maxExclusive")) 36 addMaxExclusiveParam(value, context); 37 else if (name.equals("length")) 38 addLengthParam(value); 39 else if (name.equals("minLength")) 40 addMinLengthParam(value); 41 else if (name.equals("maxLength")) 42 addMaxLengthParam(value); 43 else if (name.equals("fractionDigits")) 44 addScaleParam(value); 45 else if (name.equals("totalDigits")) 46 addPrecisionParam(value); 47 else if (name.equals("enumeration")) 48 error("enumeration_param"); 49 else if (name.equals("whiteSpace")) 50 error("whiteSpace_param"); 51 else 52 error("unrecognized_param", name); 53 } 54 55 private void addPatternParam(String value) throws DatatypeException { 56 try { 57 base = new PatternRestrictDatatype(base, 58 library.getRegexEngine().compile(value)); 59 } 60 catch (RegexSyntaxException e) { 61 int pos = e.getPosition(); 62 if (pos == RegexSyntaxException.UNKNOWN_POSITION) 63 pos = DatatypeException.UNKNOWN; 64 error("invalid_regex", e.getMessage(), pos); 65 } 66 } 67 68 private void addMinInclusiveParam(String value, ValidationContext context) 69 throws DatatypeException { 70 base = new MinInclusiveRestrictDatatype(base, 71 getLimit(value, context)); 72 } 73 74 private void addMaxInclusiveParam(String value, ValidationContext context) 75 throws DatatypeException { 76 base = new MaxInclusiveRestrictDatatype(base, 77 getLimit(value, context)); 78 } 79 80 private void addMinExclusiveParam(String value, ValidationContext context) 81 throws DatatypeException { 82 base = new MinExclusiveRestrictDatatype(base, 83 getLimit(value, context)); 84 } 85 86 private void addMaxExclusiveParam(String value, ValidationContext context) 87 throws DatatypeException { 88 base = new MaxExclusiveRestrictDatatype(base, 89 getLimit(value, context)); 90 } 91 92 private Object getLimit(String str, ValidationContext context) 93 throws DatatypeException { 94 if (base.getOrderRelation() == null) 95 error("not_ordered"); 96 Object value = base.createValue(str, context); 97 if (value == null) 98 error("invalid_limit", str); 99 return value; 100 } 101 102 private void addLengthParam(String value) throws DatatypeException { 103 base = new LengthRestrictDatatype(base, getLength(value)); 104 } 105 106 private void addMinLengthParam(String value) throws DatatypeException { 107 base = new MinLengthRestrictDatatype(base, getLength(value)); 108 } 109 110 private void addMaxLengthParam(String value) throws DatatypeException { 111 base = new MaxLengthRestrictDatatype(base, getLength(value)); 112 } 113 114 private int getLength(String str) throws DatatypeException { 115 if (base.getMeasure() == null) 116 error("no_length"); 117 int len = convertNonNegativeInteger(str); 118 if (len < 0) 119 error("value_not_non_negative_integer"); 120 return len; 121 } 122 123 private void addScaleParam(String str) throws DatatypeException { 124 if (!(base.getPrimitive() instanceof DecimalDatatype)) 125 error("scale_not_derived_from_decimal"); 126 int scale = convertNonNegativeInteger(str); 127 if (scale < 0) 128 error("value_not_non_negative_integer"); 129 base = new ScaleRestrictDatatype(base, scale); 130 } 131 132 private void addPrecisionParam(String str) throws DatatypeException { 133 if (!(base.getPrimitive() instanceof DecimalDatatype)) 134 error("precision_not_derived_from_decimal"); 135 int scale = convertNonNegativeInteger(str); 136 if (scale <= 0) 137 error("value_not_positive_integer"); 138 base = new PrecisionRestrictDatatype(base, scale); 139 } 140 141 public Datatype createDatatype() { 142 return base; 143 } 144 145 private static void error(String key) throws DatatypeException { 146 throw new DatatypeException(localizer.message(key)); 147 } 148 149 private static void error(String key, String arg) throws DatatypeException { 150 throw new DatatypeException(localizer.message(key, arg)); 151 } 152 153 private static void error(String key, String arg, int pos) throws DatatypeException { 154 throw new DatatypeException(pos, localizer.message(key, arg)); 155 } 156 157 160 private int convertNonNegativeInteger(String str) { 161 str = str.trim(); 162 DecimalDatatype decimal = new DecimalDatatype(); 163 if (!decimal.lexicallyAllows(str)) 164 return -1; 165 str = decimal.getValue(str, null).toString(); 167 if (str.charAt(0) == '-' || str.indexOf('.') >= 0) 169 return -1; 170 try { 171 return Integer.parseInt(str); 172 } 173 catch (NumberFormatException e) { 174 return Integer.MAX_VALUE; 176 } 177 } 178 } 179 | Popular Tags |