KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.util.regex.Pattern JavaDoc;
15 import org.mmbase.bridge.*;
16 import org.mmbase.util.Casting;
17 import org.mmbase.util.logging.*;
18
19 /**
20  * The datatype for String fields. Strings can be constrained by a regular expression, and have a
21  * property 'password' which indicates that the contents should not be shown.
22  *
23  * @author Pierre van Rooden
24  * @author Michiel Meeuwissen
25  * @version $Id: StringDataType.java,v 1.35 2006/07/17 07:32:29 pierre Exp $
26  * @since MMBase-1.8
27  */

28 public class StringDataType extends ComparableDataType implements LengthDataType {
29     private static final Logger log = Logging.getLoggerInstance(StringDataType.class);
30
31     private static final long serialVersionUID = 1L; // increase this if object serialization changes (which we shouldn't do!)
32

33     protected PatternRestriction patternRestriction = new PatternRestriction(Pattern.compile("(?s)\\A.*\\z"));
34     private boolean isPassword = false;
35     protected AbstractLengthDataType.MinRestriction minLengthRestriction = new AbstractLengthDataType.MinRestriction(this, 0);
36     protected AbstractLengthDataType.MaxRestriction maxLengthRestriction = new AbstractLengthDataType.MaxRestriction(this, Long.MAX_VALUE);
37
38     /**
39      * Constructor for string data type.
40      * @param name the name of the data type
41      */

42     public StringDataType(String JavaDoc name) {
43         super(name, String JavaDoc.class);
44     }
45
46     protected void inheritProperties(BasicDataType origin) {
47         super.inheritProperties(origin);
48         if (origin instanceof StringDataType) {
49             StringDataType dataType = (StringDataType)origin;
50             isPassword = dataType.isPassword();
51         }
52     }
53
54     public static final Pattern JavaDoc DOUBLE_PATTERN;
55     static {
56         // copied from javadoc of Double: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Double.html#valueOf(java.lang.String)
57
final String JavaDoc Digits = "(\\p{Digit}+)";
58         final String JavaDoc HexDigits = "(\\p{XDigit}+)";
59         // an exponent is 'e' or 'E' followed by an optionally
60
// signed decimal integer.
61
final String JavaDoc Exp = "[eE][+-]?"+Digits;
62         final String JavaDoc fpRegex =
63             ("[\\x00-\\x20]*"+ // Optional leading "whitespace"
64
"[+-]?(" + // Optional sign character
65
"NaN|" + // "NaN" string
66
"Infinity|" + // "Infinity" string
67

68              // A decimal floating-point string representing a finite positive
69
// number without a leading sign has at most five basic pieces:
70
// Digits . Digits ExponentPart FloatTypeSuffix
71
//
72
// Since this method allows integer-only strings as input
73
// in addition to strings of floating-point literals, the
74
// two sub-patterns below are simplifications of the grammar
75
// productions from the Java Language Specification, 2nd
76
// edition, section 3.10.2.
77

78              // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
79
"((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+
80
81              // . Digits ExponentPart_opt FloatTypeSuffix_opt
82
"(\\.("+Digits+")("+Exp+")?)|"+
83
84              // Hexadecimal strings
85
"((" +
86              // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
87
"(0[xX]" + HexDigits + "(\\.)?)|" +
88
89              // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
90
"(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
91
92              ")[pP][+-]?" + Digits + "))" +
93              "[fFdD]?))" +
94              "[\\x00-\\x20]*");// Optional trailing "whitespace"
95

96         DOUBLE_PATTERN = Pattern.compile(fpRegex);
97     }
98     public static final Pattern JavaDoc BOOLEAN_PATTERN = Pattern.compile("\\A(1|0|true|false)\\z");
99     public static final Pattern JavaDoc INTEGER_PATTERN = Pattern.compile("\\A-?[0-9]+\\z");
100     public static final Pattern JavaDoc NON_NEGATIVE_INTEGER_PATTERN = Pattern.compile("\\A[0-9]+\\z");
101     public static final Pattern JavaDoc LONG_PATTERN = INTEGER_PATTERN;
102
103     protected void inheritRestrictions(BasicDataType origin) {
104         super.inheritRestrictions(origin);
105         if (origin instanceof StringDataType) {
106             StringDataType dataType = (StringDataType)origin;
107             patternRestriction.inherit(dataType.patternRestriction);
108             minLengthRestriction.inherit(dataType.minLengthRestriction);
109             maxLengthRestriction.inherit(dataType.maxLengthRestriction);
110         } else if (origin instanceof BooleanDataType) {
111             patternRestriction.setValue(BOOLEAN_PATTERN);
112         } else if (origin instanceof IntegerDataType) {
113             PatternRestriction parent = new PatternRestriction(INTEGER_PATTERN);
114             parent.setEnforceStrength(ENFORCE_ABSOLUTE);
115             patternRestriction = new PatternRestriction( parent);
116         } else if (origin instanceof LongDataType) {
117             PatternRestriction parent = new PatternRestriction(LONG_PATTERN);
118             parent.setEnforceStrength(ENFORCE_ABSOLUTE);
119             patternRestriction = new PatternRestriction( parent);
120         } else if (origin instanceof FloatDataType) {
121             PatternRestriction parent = new PatternRestriction(DOUBLE_PATTERN);
122             parent.setEnforceStrength(ENFORCE_ABSOLUTE);
123             patternRestriction = new PatternRestriction( parent);
124         } else if (origin instanceof DoubleDataType) {
125             PatternRestriction parent = new PatternRestriction(DOUBLE_PATTERN);
126             parent.setEnforceStrength(ENFORCE_ABSOLUTE);
127             patternRestriction = new PatternRestriction( parent);
128         }
129         if (origin instanceof NumberDataType) {
130             // number datatypes intrinsicly have a minimal and a maximal value, so these would have been interhited.
131
// but on a string they would never work (strings are compared alphabeticly), so remove those restrictions:
132
setMin(null, true);
133             setMax(null, true);
134         }
135     }
136
137     protected void cloneRestrictions(BasicDataType origin) {
138         super.cloneRestrictions(origin);
139         if (origin instanceof StringDataType) {
140             StringDataType dataType = (StringDataType)origin;
141             patternRestriction = new PatternRestriction(dataType.patternRestriction);
142             minLengthRestriction = new AbstractLengthDataType.MinRestriction(this, dataType.minLengthRestriction);
143             maxLengthRestriction = new AbstractLengthDataType.MaxRestriction(this, dataType.maxLengthRestriction);
144         }
145     }
146
147     public long getLength(Object JavaDoc value) {
148         return ((String JavaDoc) value).length();
149     }
150     /**
151      * {@inheritDoc}
152      */

153     public long getMinLength() {
154         return Casting.toLong(minLengthRestriction.getValue());
155     }
156
157     /**
158      * {@inheritDoc}
159      */

160     public DataType.Restriction getMinLengthRestriction() {
161         return minLengthRestriction;
162     }
163
164     /**
165      * {@inheritDoc}
166      */

167     public void setMinLength(long value) {
168         getMinLengthRestriction().setValue(new Long JavaDoc(value));
169     }
170
171     /**
172      * {@inheritDoc}
173      */

174     public long getMaxLength() {
175         return Casting.toLong(getMaxLengthRestriction().getValue());
176     }
177
178     /**
179      * {@inheritDoc}
180      */

181     public DataType.Restriction getMaxLengthRestriction() {
182         return maxLengthRestriction;
183     }
184     /**
185      * {@inheritDoc}
186      */

187     public void setMaxLength(long value) {
188         getMaxLengthRestriction().setValue(new Long JavaDoc(value));
189     }
190
191
192
193     /**
194      * Returns the regular expression pattern used to validate values for this datatype.
195      * @return the pattern.
196      */

197     public Pattern JavaDoc getPattern() {
198         return patternRestriction.getPattern();
199     }
200
201     /**
202      * Returns the 'pattern' restriction, containing the value, error messages, and fixed status of this attribute.
203      * @return the restriction as a {@link DataType.Restriction}
204      */

205     public DataType.Restriction getPatternRestriction() {
206         return patternRestriction;
207     }
208
209     /**
210      * Sets the regular expression pattern used to validate values for this datatype.
211      * @param value the pattern as a <code>Pattern</code>, or <code>null</code> if no pattern should be applied.
212      * @throws java.lang.UnsupportedOperationException if this datatype is read-only (i.e. defined by MMBase)
213      */

214     public void setPattern(Pattern JavaDoc value) {
215         getPatternRestriction().setValue(value);
216     }
217
218
219     /**
220      * Whether or not the data represents sensitive information, in which case e.g. an input
221      * interface may present asterisks in stead of letters.
222      */

223     public boolean isPassword() {
224         return isPassword;
225     }
226     public void setPassword(boolean pw) {
227         edit();
228         isPassword = pw;
229     }
230
231     public void toXml(org.w3c.dom.Element JavaDoc parent) {
232         super.toXml(parent);
233         getElement(parent, "minLength", "description,class,property,default,unique,required,(minInclusive|minExclusive),(maxIncluse|maxExclusive),minLength").setAttribute("value", Casting.toString(minLengthRestriction.getValue()));
234         getElement(parent, "maxLength", "description,class,property,default,unique,required,(minInclusive|minExclusive),(maxIncluse|maxExclusive),minLength,maxLength").setAttribute("value", Casting.toString(maxLengthRestriction.getValue()));
235         getElement(parent, "pattern", "description,class,property,default,unique,required,(minInclusive|minExclusive),(maxIncluse|maxExclusive),minLength,maxLength,length,pattern").setAttribute("value", Casting.toString(patternRestriction.getPattern().pattern()));
236
237     }
238
239     protected Collection validateCastValue(Collection errors, Object JavaDoc castValue, Object JavaDoc value, Node node, Field field) {
240         errors = super.validateCastValue(errors, castValue, value, node, field);
241         errors = patternRestriction.validate(errors, castValue, node, field);
242         errors = minLengthRestriction.validate(errors, castValue, node, field);
243         errors = maxLengthRestriction.validate(errors, castValue, node, field);
244         return errors;
245     }
246
247     protected StringBuffer JavaDoc toStringBuffer() {
248         StringBuffer JavaDoc buf = super.toStringBuffer();
249         Pattern JavaDoc p = getPattern();
250         if (p != null && ! (p.pattern().equals(".*"))) {
251             buf.append(" pattern:").append(p.pattern());
252         }
253         if (isPassword()) {
254             buf.append(" password");
255         }
256         return buf;
257     }
258
259     protected class PatternRestriction extends AbstractRestriction {
260         PatternRestriction(PatternRestriction source) {
261             super(source);
262         }
263         PatternRestriction(Pattern JavaDoc v) {
264             super("pattern", v);
265         }
266         Pattern JavaDoc getPattern() {
267             return (Pattern JavaDoc) value;
268         }
269         protected boolean simpleValid(Object JavaDoc v, Node node, Field field) {
270             String JavaDoc s = Casting.toString(v);
271             boolean res = value == null ? true : getPattern().matcher(s).matches();
272             //log.info("VALIDATING " + v + " with " + getPattern() + " -> " + res);
273
return res;
274         }
275     }
276
277     public static void main(String JavaDoc [] argv) {
278         Pattern JavaDoc p = Pattern.compile(argv[0]);
279         System.out.println(p.matcher(argv[1]).matches());
280     }
281
282 }
283
Popular Tags