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: import org.mmbase.bridge.*;
014: import org.mmbase.util.Casting;
015: import org.mmbase.util.LocalizedString;
016:
017: /**
018: * @javadoc
019: *
020: * @author Pierre van Rooden
021: * @author Michiel Meeuwissen
022: * @version $Id: ListDataType.java,v 1.24 2007/09/16 17:55:28 michiel Exp $
023: * @since MMBase-1.8
024: */
025: public class ListDataType extends AbstractLengthDataType<List> {
026: private static final long serialVersionUID = 1L; // increase this if object serialization changes (which we shouldn't do!)
027:
028: protected ItemRestriction itemRestriction = new ItemRestriction(
029: Constants.DATATYPE_UNKNOWN);
030:
031: /**
032: * Constructor for List field.
033: */
034: public ListDataType(String name) {
035: super (name, List.class);
036: }
037:
038: protected void inheritRestrictions(BasicDataType origin) {
039: super .inheritRestrictions(origin);
040: if (origin instanceof ListDataType) {
041: ListDataType dataType = (ListDataType) origin;
042: itemRestriction.inherit(dataType.itemRestriction);
043: }
044: }
045:
046: protected void cloneRestrictions(BasicDataType origin) {
047: super .cloneRestrictions(origin);
048: if (origin instanceof ListDataType) {
049: ListDataType dataType = (ListDataType) origin;
050: itemRestriction = new ItemRestriction(
051: dataType.itemRestriction);
052: }
053: }
054:
055: public long getLength(Object value) {
056: return ((Collection) value).size();
057: }
058:
059: /**
060: * Returns the datatype of items in this list.
061: * @return the datatype as a DataType object, <code>null</code> if there are no restrictions
062: */
063: public DataType getItemDataType() {
064: return itemRestriction.getItemDataType();
065: }
066:
067: /**
068: * Returns the 'itemDataType' restriction, containing the value, errormessages, and fixed status of this attribute.
069: * @return the restriction as a {@link DataType.Restriction}
070: */
071: public DataType.Restriction getItemDataTypeRestriction() {
072: return itemRestriction;
073: }
074:
075: /**
076: * Sets the datatype of items in this list.
077: * @param value the datatype as a DataType object, <code>null</code> if there are no restrictions
078: */
079: public void setItemDataType(DataType value) {
080: itemRestriction.setValue(value);
081: }
082:
083: public int getEnforceStrength() {
084: return Math.max(super .getEnforceStrength(), itemRestriction
085: .getEnforceStrength());
086: }
087:
088: protected Collection<LocalizedString> validateCastValue(
089: Collection<LocalizedString> errors, Object castValue,
090: Object value, Node node, Field field) {
091: errors = super .validateCastValue(errors, castValue, value,
092: node, field);
093: errors = itemRestriction.validate(errors, castValue, node,
094: field);
095: return errors;
096: }
097:
098: protected StringBuilder toStringBuilder() {
099: StringBuilder buf = super .toStringBuilder();
100: buf.append("items: " + getItemDataType());
101: return buf;
102: }
103:
104: protected class ItemRestriction extends AbstractRestriction {
105: ItemRestriction(ItemRestriction me) {
106: super (me);
107: }
108:
109: ItemRestriction(DataType v) {
110: super ("itemDataType", v);
111: }
112:
113: DataType getItemDataType() {
114: return (DataType) value;
115: }
116:
117: protected boolean simpleValid(Object v, Node node, Field field) {
118: DataType itemDataType = getItemDataType();
119: if (itemDataType == Constants.DATATYPE_UNKNOWN)
120: return true;
121: List listValue = Casting.toList(v);
122: for (Iterator i = listValue.iterator(); i.hasNext();) {
123: try {
124: Collection col = itemDataType.validate(i.next());
125: if (col != VALID)
126: return false;
127: } catch (ClassCastException cce) {
128: return false;
129: }
130: }
131: return true;
132: }
133:
134: protected Collection validate(Collection errors, Object v,
135: Node node, Field field) {
136: if (!enforce(v, node, field)) {
137: return errors;
138: }
139: DataType itemDataType = getItemDataType();
140: if (itemDataType == Constants.DATATYPE_UNKNOWN)
141: return errors;
142: List listValue = Casting.toList(v);
143: for (Iterator i = listValue.iterator(); i.hasNext();) {
144: Collection col = itemDataType.validate(i.next());
145: try {
146: if (col != VALID) {
147: if (errors == VALID)
148: errors = new ArrayList<LocalizedString>();
149: errors.addAll(col);
150: }
151: } catch (ClassCastException cce) {
152: errors = addError(errors, v, node, field);
153: }
154: }
155: return errors;
156: }
157:
158: }
159:
160: }
|