001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.datatypes;
011:
012: import java.util.*;
013:
014: import org.mmbase.bridge.*;
015: import org.mmbase.util.Casting;
016: import org.mmbase.util.LocalizedString;
017: import org.w3c.dom.Element;
018:
019: /**
020: * A LengthDataType is a datatype that defines a length for its values ({@link #getLength(Object)}) ,
021: * and restrictions on that (minimal an maximal length).
022: *
023: * @author Pierre van Rooden
024: * @author Michiel Meeuwissen
025: * @version $Id: AbstractLengthDataType.java,v 1.24 2007/09/16 17:55:28 michiel Exp $
026: * @since MMBase-1.8
027: */
028: abstract public class AbstractLengthDataType<E> extends
029: BasicDataType<E> implements LengthDataType<E> {
030:
031: protected MinRestriction minLengthRestriction = new MinRestriction(
032: this , 0);
033: protected MaxRestriction maxLengthRestriction = new MaxRestriction(
034: this , Long.MAX_VALUE);
035:
036: /**
037: * Constructor for big data field.
038: * @param name the name of the data type
039: * @param classType the class of the data type's possible value
040: */
041: public AbstractLengthDataType(String name, Class<E> classType) {
042: super (name, classType);
043: minLengthRestriction.setEnforceStrength(ENFORCE_ABSOLUTE);
044: }
045:
046: protected void cloneRestrictions(BasicDataType<E> origin) {
047: super .cloneRestrictions(origin);
048: if (origin instanceof AbstractLengthDataType) {
049: AbstractLengthDataType<E> dataType = (AbstractLengthDataType<E>) origin;
050: // make new instances because of this can be called from a clone .. We hate java.
051: minLengthRestriction = new MinRestriction(this ,
052: dataType.minLengthRestriction);
053: maxLengthRestriction = new MaxRestriction(this ,
054: dataType.maxLengthRestriction);
055: }
056: }
057:
058: protected void inheritRestrictions(BasicDataType<E> origin) {
059: super .inheritRestrictions(origin);
060: if (origin instanceof AbstractLengthDataType) {
061: AbstractLengthDataType<E> dataType = (AbstractLengthDataType<E>) origin;
062: // make new instances because of this can be called from a clone .. We hate java.
063: minLengthRestriction.inherit(dataType.minLengthRestriction);
064: maxLengthRestriction.inherit(dataType.maxLengthRestriction);
065: }
066: }
067:
068: /**
069: * {@inheritDoc}
070: */
071: public abstract long getLength(Object value);
072:
073: /**
074: * {@inheritDoc}
075: */
076: public long getMinLength() {
077: return minLengthRestriction.getValue();
078: }
079:
080: /**
081: * {@inheritDoc}
082: */
083: public DataType.Restriction<Long> getMinLengthRestriction() {
084: return minLengthRestriction;
085: }
086:
087: /**
088: * {@inheritDoc}
089: */
090: public void setMinLength(long value) {
091: getMinLengthRestriction().setValue(Long.valueOf(value));
092: }
093:
094: /**
095: * {@inheritDoc}
096: */
097: public long getMaxLength() {
098: return getMaxLengthRestriction().getValue();
099: }
100:
101: /**
102: * {@inheritDoc}
103: */
104: public DataType.Restriction<Long> getMaxLengthRestriction() {
105: return maxLengthRestriction;
106: }
107:
108: /**
109: * Sets the maximum length of binary values for this datatype.
110: * @param value the maximum length as an <code>int</code>, or -1 if there is no maximum length.
111: * @throws Class Identifier: java.lang.UnsupportedOperationException if this datatype is finished
112: */
113: public void setMaxLength(long value) {
114: getMaxLengthRestriction().setValue(Long.valueOf(value));
115: }
116:
117: public int getEnforceStrength() {
118: int enforceStrength = Math.max(super .getEnforceStrength(),
119: minLengthRestriction.getEnforceStrength());
120: return Math.max(enforceStrength, maxLengthRestriction
121: .getEnforceStrength());
122: }
123:
124: protected Collection<LocalizedString> validateCastValueOrNull(
125: Collection<LocalizedString> errors, Object castValue,
126: Object value, Node node, Field field) {
127: errors = super .validateCastValueOrNull(errors, castValue,
128: value, node, field);
129: errors = minLengthRestriction.validate(errors, castValue, node,
130: field);
131: return errors;
132:
133: }
134:
135: protected Collection<LocalizedString> validateCastValue(
136: Collection<LocalizedString> errors, Object castValue,
137: Object value, Node node, Field field) {
138: errors = super .validateCastValue(errors, castValue, value,
139: node, field);
140: errors = maxLengthRestriction.validate(errors, castValue, node,
141: field);
142: return errors;
143: }
144:
145: public void toXml(Element parent) {
146: super .toXml(parent);
147: addRestriction(
148: parent,
149: "minLength",
150: "description,class,property,default,unique,required,(minInclusive|minExclusive),(maxInclusive|maxExclusive),minLength",
151: minLengthRestriction);
152: addRestriction(
153: parent,
154: "maxLength",
155: "description,class,property,default,unique,required,(minInclusive|minExclusive),(maxInclusive|maxExclusive),minLength,maxLength",
156: maxLengthRestriction);
157:
158: }
159:
160: protected StringBuilder toStringBuilder() {
161: StringBuilder buf = super .toStringBuilder();
162: if (getMinLength() > 0) {
163: buf.append("minLength:" + getMinLength() + " ");
164: }
165: if (getMaxLength() < Long.MAX_VALUE) {
166: buf.append("maxLength:" + getMaxLength() + " ");
167: }
168: return buf;
169: }
170:
171: static class MinRestriction extends StaticAbstractRestriction<Long> {
172: MinRestriction(BasicDataType<?> dt, MinRestriction source) {
173: super (dt, source);
174: }
175:
176: MinRestriction(BasicDataType<?> dt, long min) {
177: super (dt, "minLength", Long.valueOf(min));
178: }
179:
180: protected boolean simpleValid(Object v, Node node, Field field) {
181: if (v == null)
182: return true; // depends on 'required'
183: long min = Casting.toLong(getValue());
184: return ((LengthDataType<?>) parent).getLength(v) >= min;
185: }
186: }
187:
188: static class MaxRestriction extends StaticAbstractRestriction<Long> {
189: MaxRestriction(BasicDataType<?> dt, MaxRestriction source) {
190: super (dt, source);
191: }
192:
193: MaxRestriction(BasicDataType<?> dt, long max) {
194: super (dt, "maxLength", Long.valueOf(max));
195: }
196:
197: protected boolean simpleValid(Object v, Node node, Field field) {
198: if (v == null)
199: return true; // depends on 'required'
200: long max = Casting.toLong(getValue());
201: long length = ((LengthDataType<?>) parent).getLength(v);
202: return length <= max;
203: }
204: }
205:
206: }
|