1 10 package org.mmbase.datatypes; 11 12 import java.util.*; 13 14 import org.mmbase.bridge.*; 15 import org.mmbase.util.Casting; 16 import org.mmbase.util.logging.*; 17 import org.mmbase.util.DynamicDate; 18 import org.w3c.dom.Element ; 19 20 28 public abstract class ComparableDataType extends BasicDataType { 29 30 private static final Logger log = Logging.getLoggerInstance(ComparableDataType.class); 31 32 private static final long serialVersionUID = 1L; 33 34 protected MinRestriction minRestriction = new MinRestriction(true); 35 protected MaxRestriction maxRestriction = new MaxRestriction(true); 36 37 protected ComparableDataType(String name, Class classType) { 38 super(name, classType); 39 } 40 41 protected void inheritRestrictions(BasicDataType origin) { 42 super.inheritRestrictions(origin); 43 if (origin instanceof ComparableDataType) { 44 ComparableDataType compOrigin = (ComparableDataType) origin; 45 46 Comparable currentMin = (Comparable )minRestriction.getValue(); 47 Comparable originMin = (Comparable )cast(compOrigin.minRestriction.getValue(), null, null); 49 if (currentMin == null || (originMin != null && (currentMin.compareTo(originMin) < 0))) { 51 minRestriction.inherit(compOrigin.minRestriction, true); 52 } 53 54 Comparable currentMax = (Comparable )maxRestriction.getValue(); 55 Comparable originMax = (Comparable )cast(compOrigin.maxRestriction.getValue(), null, null); 57 if (currentMax == null || (originMax != null && (currentMax.compareTo(originMax) > 0))) { 59 maxRestriction.inherit(compOrigin.maxRestriction, true); 60 } 61 } 62 } 63 64 protected void cloneRestrictions(BasicDataType origin) { 65 super.cloneRestrictions(origin); 66 if (origin instanceof ComparableDataType) { 67 ComparableDataType dataType = (ComparableDataType) origin; 68 minRestriction = new MinRestriction(dataType.minRestriction); 69 maxRestriction = new MaxRestriction(dataType.maxRestriction); 70 } 71 } 72 73 75 public DataType.Restriction getMinRestriction() { 76 return minRestriction; 77 } 78 79 83 public boolean isMinInclusive() { 84 return minRestriction.isInclusive(); 85 } 86 87 89 public DataType.Restriction getMaxRestriction() { 90 return maxRestriction; 91 } 92 93 94 98 public boolean isMaxInclusive() { 99 return maxRestriction.isInclusive(); 100 } 101 102 107 public final Object getDefaultValue() { 108 Object def = super.getDefaultValue(); 109 if (! minRestriction.valid(def, null, null)) { 110 def = minRestriction.getValue(); 111 } else if (! maxRestriction.valid(def, null, null)) { 112 def = maxRestriction.getValue(); 113 } 114 return def; 115 } 116 117 118 public void toXml(Element parent) { 119 super.toXml(parent); 120 121 if (minRestriction.isInclusive()) { 122 getElement(parent, "minInclusive", "description,class,property,default,uniue,required,(minInclusive|minExclusive)") 123 .setAttribute("value", xmlValue(minRestriction.getValue())); 124 } else { 125 getElement(parent, "minExclusive", "description,class,property,default,uniue,required,(minInclusive|minExclusive)") 126 .setAttribute("value", xmlValue(minRestriction.getValue())); 127 } 128 if (maxRestriction.isInclusive()) { 129 getElement(parent, "maxInclusive", "description,class,property,default,uniue,required,(minInclusive|minExclusive),(maxInclusive|maxExclusive)") 130 .setAttribute("value", xmlValue(maxRestriction.getValue())); 131 } else { 132 getElement(parent, "maxExclusive", "description,class,property,default,uniue,required,(minInclusive|minExclusive),(maxInclusive|maxExclusive)") 133 .setAttribute("value", xmlValue(maxRestriction.getValue())); 134 } 135 136 } 137 138 144 public void setMin(Comparable value, boolean inclusive) { 145 edit(); 146 checkType(value); 147 if (inclusive != minRestriction.isInclusive()) minRestriction = new MinRestriction(inclusive); 148 minRestriction.setValue((java.io.Serializable ) value); 149 } 150 151 152 158 public void setMax(Comparable value, boolean inclusive) { 159 edit(); 160 checkType(value); 161 if (inclusive != maxRestriction.isInclusive()) maxRestriction = new MaxRestriction(inclusive); 162 maxRestriction.setValue((java.io.Serializable ) value); 163 } 164 165 166 167 protected Collection validateCastValue(Collection errors, Object castValue, Object value, Node node, Field field) { 168 errors = super.validateCastValue(errors, castValue, value, node, field); 169 errors = minRestriction.validate(errors, castValue, node, field); 170 errors = maxRestriction.validate(errors, castValue, node, field); 171 return errors; 172 } 173 174 public Object clone(String name) { 175 ComparableDataType clone = (ComparableDataType) super.clone(name); 176 return clone; 177 } 178 179 protected StringBuffer toStringBuffer() { 180 StringBuffer buf = super.toStringBuffer(); 181 Object minValue = minRestriction.getValue(); 182 Object maxValue = maxRestriction.getValue(); 183 if (minValue != null) { 184 buf.append(minRestriction.isInclusive() ? '[' : '<'); 185 buf.append(minValue); 186 if (minValue instanceof Date) { 187 Calendar cal = Calendar.getInstance(); 189 cal.setTime((Date) minValue); 190 if (cal.get(Calendar.ERA) == GregorianCalendar.BC) { 191 buf.append(" BC"); 192 } 193 } 194 buf.append(minRestriction.enforceStrength == DataType.ENFORCE_NEVER ? "*" : ""); 195 } 196 if (minValue != null || maxValue != null) { 197 buf.append("..."); 198 } 199 if (maxValue != null) { 200 buf.append(maxValue); 201 buf.append(maxRestriction.enforceStrength == DataType.ENFORCE_NEVER ? "*" : ""); 202 buf.append(maxRestriction.isInclusive() ? ']' : '>'); 203 } 204 return buf; 205 } 206 207 protected class MinRestriction extends AbstractRestriction { 208 private boolean inclusive; 209 MinRestriction(MinRestriction source) { 210 super(source); 211 inclusive = source.inclusive; 212 } 213 MinRestriction(boolean inc) { 214 super("min" + (inc ? "Inclusive" : "Exclusive"), null); 215 inclusive = inc; 216 } 217 218 protected boolean simpleValid(Object v, Node node, Field field) { 219 if ((v == null) || (getValue() == null)) return true; 220 Comparable comparable = (Comparable ) v; 221 Comparable minimum; 222 try { 223 minimum = (Comparable ) ComparableDataType.this.castToValidate(getValue(), node, field); 224 } catch (CastException ce) { 225 log.error(ce); return true; 228 } 229 if (inclusive && (comparable.equals(minimum))) return true; 230 return comparable.compareTo(minimum) > 0; 231 } 232 public boolean isInclusive() { 233 return inclusive; 234 } 235 } 236 protected class MaxRestriction extends AbstractRestriction { 237 private boolean inclusive; 238 MaxRestriction(MaxRestriction source) { 239 super(source); 240 inclusive = source.inclusive; 241 } 242 MaxRestriction(boolean inc) { 243 super("max" + (inc ? "Inclusive" : "Exclusive"), null); 244 inclusive = inc; 245 } 246 protected boolean simpleValid(Object v, Node node, Field field) { 247 if ((v == null) || (getValue() == null)) return true; 248 Comparable comparable = (Comparable ) v; 249 Comparable maximum; 250 try { 251 maximum = (Comparable ) ComparableDataType.this.castToValidate(getValue(), node, field); 252 } catch (CastException ce) { 253 log.error(ce); return true; 256 } 257 if (inclusive && (comparable.equals(maximum))) return true; 258 boolean res = comparable.compareTo(maximum) < 0; 259 return res; 260 } 261 262 263 public boolean isInclusive() { 264 return inclusive; 265 } 266 } 267 268 269 } 270 | Popular Tags |