KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > datatypes > ComparableDataType


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

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 JavaDoc;
19
20 /**
21  * Comparable datatypes have values which are {@link java.lang.Comparable}, so can be ordered, and
22  * therefore can have a minimum and a maximum value.
23  *
24  * @author Michiel Meeuwissen
25  * @version $Id: ComparableDataType.java,v 1.21 2006/07/18 12:58:40 michiel Exp $
26  * @since MMBase-1.8
27  */

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 JavaDoc name, Class JavaDoc 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 JavaDoc currentMin = (Comparable JavaDoc)minRestriction.getValue();
47             // cast origin minimum type to new datatype type
48
Comparable JavaDoc originMin = (Comparable JavaDoc)cast(compOrigin.minRestriction.getValue(), null, null);
49             // Only apply the new min if it is higher
50
if (currentMin == null || (originMin != null && (currentMin.compareTo(originMin) < 0))) {
51                 minRestriction.inherit(compOrigin.minRestriction, true);
52             }
53
54             Comparable JavaDoc currentMax = (Comparable JavaDoc)maxRestriction.getValue();
55             // cast origin maximum type to new datatype type
56
Comparable JavaDoc originMax = (Comparable JavaDoc)cast(compOrigin.maxRestriction.getValue(), null, null);
57             // Only apply the new max if it is lower
58
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     /**
74      */

75     public DataType.Restriction getMinRestriction() {
76         return minRestriction;
77     }
78
79     /**
80      * Returns whether the minimum value for this data type is inclusive or not.
81      * @return <code>true</code> if the minimum value if inclusive, <code>false</code> if it is not, or if there is no minimum.
82      */

83     public boolean isMinInclusive() {
84         return minRestriction.isInclusive();
85     }
86
87     /**
88      */

89     public DataType.Restriction getMaxRestriction() {
90         return maxRestriction;
91     }
92
93
94     /**
95      * Returns whether the maximum value for this data type is inclusive or not.
96      * @return <code>true</code> if the maximum value if inclusive, <code>false</code> if it is not, or if there is no minimum.
97      */

98     public boolean isMaxInclusive() {
99         return maxRestriction.isInclusive();
100     }
101
102     /**
103      * @inheritDoc
104      *
105      * If the default value of comparable datatype is somewhy out the range, it will be truncated into it.
106      */

107     public final Object JavaDoc getDefaultValue() {
108         Object JavaDoc 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 JavaDoc 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     /**
139      * Sets the minimum Date value for this data type.
140      * @param value the minimum as an <code>Comparable</code> (and <code>Serializable</code>), or <code>null</code> if there is no minimum.
141      * @param inclusive whether the minimum value is inclusive or not
142      * @throws Class Identifier: java.lang.UnsupportedOperationException if this data type is read-only (i.e. defined by MMBase)
143      */

144     public void setMin(Comparable JavaDoc value, boolean inclusive) {
145         edit();
146         checkType(value);
147         if (inclusive != minRestriction.isInclusive()) minRestriction = new MinRestriction(inclusive);
148         minRestriction.setValue((java.io.Serializable JavaDoc) value);
149     }
150
151
152     /**
153      * Sets the maximum Date value for this data type.
154      * @param value the maximum as an <code>Comparable</code> (and <code>Serializable</code>), or <code>null</code> if there is no maximum.
155      * @param inclusive whether the maximum value is inclusive or not
156      * @throws Class Identifier: java.lang.UnsupportedOperationException if this data type is read-only (i.e. defined by MMBase)
157      */

158     public void setMax(Comparable JavaDoc value, boolean inclusive) {
159         edit();
160         checkType(value);
161         if (inclusive != maxRestriction.isInclusive()) maxRestriction = new MaxRestriction(inclusive);
162         maxRestriction.setValue((java.io.Serializable JavaDoc) value);
163     }
164
165
166
167     protected Collection validateCastValue(Collection errors, Object JavaDoc castValue, Object JavaDoc 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 JavaDoc clone(String JavaDoc name) {
175         ComparableDataType clone = (ComparableDataType) super.clone(name);
176         return clone;
177     }
178
179     protected StringBuffer JavaDoc toStringBuffer() {
180         StringBuffer JavaDoc buf = super.toStringBuffer();
181         Object JavaDoc minValue = minRestriction.getValue();
182         Object JavaDoc maxValue = maxRestriction.getValue();
183         if (minValue != null) {
184             buf.append(minRestriction.isInclusive() ? '[' : '<');
185             buf.append(minValue);
186             if (minValue instanceof Date) {
187                 // tss, the toString of Date object doesn't have BC in it if needed!
188
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 JavaDoc v, Node node, Field field) {
219             if ((v == null) || (getValue() == null)) return true;
220             Comparable JavaDoc comparable = (Comparable JavaDoc) v;
221             Comparable JavaDoc minimum;
222             try {
223                 minimum = (Comparable JavaDoc) ComparableDataType.this.castToValidate(getValue(), node, field);
224             } catch (CastException ce) {
225                 log.error(ce); // probably config error.
226
// invalid value, but not because of min-restriction
227
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 JavaDoc v, Node node, Field field) {
247             if ((v == null) || (getValue() == null)) return true;
248             Comparable JavaDoc comparable = (Comparable JavaDoc) v;
249             Comparable JavaDoc maximum;
250             try {
251                 maximum = (Comparable JavaDoc) ComparableDataType.this.castToValidate(getValue(), node, field);
252             } catch (CastException ce) {
253                 log.error(ce); // probably config error.
254
// invalid value, but not because of max-restriction
255
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