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.Collection;
013: import org.mmbase.util.Casting;
014: import org.mmbase.util.LocalizedString;
015: import org.mmbase.bridge.*;
016: import org.mmbase.util.logging.*;
017:
018: /**
019: * The Node data type describes a data type which is based on an MMBase 'node' field. So the value
020: * is an MMBase node, which can normally be described by a foreign key.
021: *
022: * @author Pierre van Rooden
023: * @author Michiel Meeuwissen
024: * @version $Id: NodeDataType.java,v 1.33 2007/06/21 07:32:31 pierre Exp $
025: * @since MMBase-1.8
026: */
027: public class NodeDataType extends BasicDataType<Node> {
028:
029: private static final Logger log = Logging
030: .getLoggerInstance(NodeDataType.class);
031:
032: private static final long serialVersionUID = 1L; // increase this if object serialization changes (which we shouldn't do!)
033:
034: protected MustExistRestriction mustExistRestriction = new MustExistRestriction();
035:
036: /**
037: * Constructor for node field.
038: */
039: public NodeDataType(String name) {
040: super (name, Node.class);
041: }
042:
043: protected void inheritRestrictions(BasicDataType origin) {
044: super .inheritRestrictions(origin);
045: if (origin instanceof NodeDataType) {
046: mustExistRestriction
047: .inherit(((NodeDataType) origin).mustExistRestriction);
048: }
049: }
050:
051: protected void cloneRestrictions(BasicDataType origin) {
052: super .cloneRestrictions(origin);
053: if (origin instanceof NodeDataType) {
054: mustExistRestriction = new MustExistRestriction(
055: ((NodeDataType) origin).mustExistRestriction);
056: }
057: }
058:
059: protected Object castToValidate(Object value, Node node, Field field)
060: throws CastException {
061: if (value == null)
062: return null;
063: Object preCast = preCast(value, node, field); // resolves enumerations
064: if (preCast instanceof Node) {
065: return preCast;
066: } else {
067: Object res = Casting.toType(Node.class, getCloud(node,
068: field), preCast);
069: if (res == null) {
070: if (Casting.toString(value).equals("-1")) {
071: return null;
072: }
073: throw new CastException("No such node " + preCast);
074: } else {
075: return res;
076: }
077: }
078: }
079:
080: /**
081: * Whether the Node of the value must exist
082: *
083: * XXX MM: How can you have a non-existing node? I don't really get it. AFAIK all nodes exist.
084: * especially since a node field is essentially a foreign key.
085: */
086: public boolean mustExist() {
087: return mustExistRestriction.getValue().equals(Boolean.TRUE);
088: }
089:
090: public MustExistRestriction getMustExistRestriction() {
091: mustExistRestriction.setFixed(true);
092: return mustExistRestriction;
093: }
094:
095: public int getEnforceStrength() {
096: return Math.max(super .getEnforceStrength(),
097: mustExistRestriction.getEnforceStrength());
098: }
099:
100: protected Collection<LocalizedString> validateCastValue(
101: Collection<LocalizedString> errors, Object castValue,
102: Object value, Node node, Field field) {
103: errors = super .validateCastValue(errors, castValue, value,
104: node, field);
105: errors = mustExistRestriction.validate(errors, value, node,
106: field);
107: return errors;
108: }
109:
110: private class MustExistRestriction extends
111: AbstractRestriction<Boolean> {
112: MustExistRestriction(MustExistRestriction me) {
113: super (me);
114: enforceStrength = DataType.ENFORCE_ONCHANGE;
115: }
116:
117: MustExistRestriction() {
118: super ("mustExist", Boolean.TRUE);
119: enforceStrength = DataType.ENFORCE_ONCHANGE;
120: }
121:
122: protected Cloud getCloud(Node node, Field field) {
123: Cloud cloud = node != null ? node.getCloud() : null;
124: if (cloud == null)
125: cloud = field != null ? field.getNodeManager()
126: .getCloud() : null;
127: if (cloud == null) {
128: cloud = ContextProvider.getDefaultCloudContext()
129: .getCloud("mmbase", "class", null);
130: }
131: return cloud;
132: }
133:
134: protected boolean simpleValid(Object v, Node node, Field field) {
135: if (getValue().equals(Boolean.TRUE)) {
136: if (v != null) {
137: if (v instanceof String) {
138: Cloud cloud = getCloud(node, field);
139: return cloud != null
140: && cloud.hasNode((String) v);
141: } else if (v instanceof Number) {
142: int num = ((Number) v).intValue();
143: if (num < 0)
144: return false;
145: Cloud cloud = getCloud(node, field);
146: return cloud != null && cloud.hasNode(num);
147: } else if (v instanceof Node) {
148: return true;
149: } else {
150: //log.info("Not valid because node value is a " + v.getClass());
151: return false;
152: }
153: }
154: }
155: return true;
156: }
157: }
158:
159: }
|