KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > repository > DjDomain


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  * Redistribution and use in source and binary forms, with or without
4  * modification, is permitted provided that the following conditions are met: -
5  * Redistributions of source code must retain the above copyright notice, this
6  * list of conditions and the following disclaimer. - Redistributions in binary
7  * form must reproduce the above copyright notice, this list of conditions and
8  * the following disclaimer in the documentation and/or other materials
9  * provided with the distribution. - All advertising materials mentioning
10  * features or use of this software must display the following acknowledgment:
11  * "This product includes Djeneric." - Products derived from this software may
12  * not be called "Djeneric" nor may "Djeneric" appear in their names without
13  * prior written permission of Genimen BV. - Redistributions of any form
14  * whatsoever must retain the following acknowledgment: "This product includes
15  * Djeneric." THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND
16  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
17  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV,
19  * DJENERIC.ORG, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */

27 package com.genimen.djeneric.repository;
28
29 import java.io.UnsupportedEncodingException JavaDoc;
30 import java.math.BigDecimal JavaDoc;
31 import java.text.ParseException JavaDoc;
32 import java.text.SimpleDateFormat JavaDoc;
33 import java.util.ArrayList JavaDoc;
34 import java.util.Arrays JavaDoc;
35 import java.util.Collections JavaDoc;
36 import java.util.Date JavaDoc;
37
38 import org.apache.regexp.RE;
39 import org.apache.regexp.RESyntaxException;
40
41 import com.genimen.djeneric.language.Messages;
42 import com.genimen.djeneric.repository.exceptions.CatalogException;
43 import com.genimen.djeneric.repository.exceptions.DjenericException;
44 import com.genimen.djeneric.repository.exceptions.DomainViolationException;
45 import com.genimen.djeneric.util.DjLogger;
46
47 /**
48  * A domain restricts the values a property can hold by specifying a type and
49  * optionally by defining ranges or values that are valid witin the domain.
50  * Examples of domains: a Percentage domain based on type BigDecimal with a
51  * range of 0-100 or a YesNo domain based on a String, with valid values Y and
52  * N
53  *
54  * @author Wido Riezebos @created 24 mei 2002
55  */

56 public class DjDomain implements Comparable JavaDoc, DjPropertyType
57 {
58   private static SimpleDateFormat JavaDoc sf = new SimpleDateFormat JavaDoc("yyyy.MM.dd HH:mm:ss.SSS");
59
60   public static final String JavaDoc CASE_NONE = "N";
61   public static final String JavaDoc CASE_UPPER = "U";
62   public static final String JavaDoc CASE_LOWER = "L";
63
64   // These indexes MUST CORRESPOND to the string array compTypes below
65
/**
66    * Representation using a textfield component
67    */

68   public final static int COMP_TEXTFIELD = 0;
69   /**
70    * Representation using a combobox component
71    */

72   public final static int COMP_COMBOBOX = 1;
73   /**
74    * Representation using a combobox component
75    */

76   public final static int COMP_CHOOSER = 2;
77   /**
78    * Representation using a checkbox component
79    */

80   public final static int COMP_CHECKBOX = 3;
81   /**
82    * Representation using a Date Chooser component
83    */

84   public final static int COMP_DATECHOOSER = 4;
85   /**
86    * Representation using a memo component
87    */

88   public final static int COMP_MEMO = 5;
89   /**
90    * Representation using a memo component
91    */

92   public final static int COMP_HTML_MEMO = 6;
93   /**
94    * Representation using a password component
95    */

96   public final static int COMP_PASSWORD = 7;
97   /**
98    * Representation using a LABEL component
99    */

100   public final static int COMP_LABEL = 8;
101
102   public final static int COMP_CUSTOM = 9;
103
104   public final static int COMP_CUSTOM_MEMO = 10;
105
106   // The indexes above MUST CORRESPOND to the string array compTypes below
107
private static String JavaDoc[] compTypes = {"TextField", "Combobox", "Chooser", "Checkbox", "DateChooser",
108       "Memo", "HTML", "Password", "Label", "[Custom]", "[CustomMemo]"};
109
110   /**
111    * Type java.lang.String
112    */

113   public final static int STRING_TYPE = 1;
114   /**
115    * Type java.lang.Integer
116    */

117   public final static int INT_TYPE = 2;
118   /**
119    * Type java.lang.Long
120    */

121   public final static int LONG_TYPE = 3;
122   /**
123    * Type java.util.Date
124    */

125   public final static int DATE_TYPE = 4;
126   /**
127    * Type java.math.BigDecimal
128    */

129   public final static int BIGDECIMAL_TYPE = 5;
130   /**
131    * Type byte[]
132    */

133   public final static int BYTE_TYPE = 6;
134
135   private static String JavaDoc[] nativeTypes = {"String", "int", "long", "Date", "BigDecimal", "byte[]"};
136
137   String JavaDoc _name;
138   String JavaDoc _description;
139   String JavaDoc _formatMask;
140   int _componentType;
141   int _nativeTypeId;
142   int _length;
143   int _decimals;
144   int _displayWidth;
145   int _displayHeight;
146   boolean _enforce;
147   boolean _isDynamic = false;
148   DjDomain _superDomain;
149   String JavaDoc _reValidationMask;
150   String JavaDoc _reFailureMessage;
151   String JavaDoc _caseConversion;
152   DjPackage _package = null;
153
154   ArrayList JavaDoc _domainValues = new ArrayList JavaDoc();
155
156   public void copyInto(DjDomain dest)
157   {
158     dest._name = _name;
159     dest._description = _description;
160     dest._formatMask = _formatMask;
161     dest._componentType = _componentType;
162     dest._nativeTypeId = _nativeTypeId;
163     dest._length = _length;
164     dest._decimals = _decimals;
165     dest._displayWidth = _displayWidth;
166     dest._displayHeight = _displayHeight;
167     dest._enforce = _enforce;
168     dest._isDynamic = _isDynamic;
169     dest._superDomain = _superDomain;
170     dest._reValidationMask = _reValidationMask;
171     dest._reFailureMessage = _reFailureMessage;
172     dest._caseConversion = _caseConversion;
173     dest._package = _package;
174     dest._domainValues = new ArrayList JavaDoc();
175     dest._domainValues.addAll(_domainValues);
176   }
177
178   /**
179    * Constructor for the DjDomain object
180    */

181   public DjDomain()
182   {
183     _name = "";
184     _nativeTypeId = STRING_TYPE;
185     _enforce = true;
186     _description = "";
187     _length = 0;
188     _decimals = 0;
189     _formatMask = "";
190     _displayWidth = 0;
191     _displayHeight = 0;
192     _reValidationMask = "";
193     _reFailureMessage = "";
194     _caseConversion = CASE_NONE;
195   }
196
197   // See DjProperty types for valid values of type
198
/**
199    * Convenience constructor for the DjDomain object
200    *
201    * @param name
202    * Name of the domain
203    * @param type
204    * Type of the domain (see translateType())
205    * @param length
206    * Maximum length (if applicable)
207    * @param decimals
208    * Decimals (if applicable)
209    * @param formatMask
210    * Format mask (see java.text)
211    * @param description
212    * Description of the domain
213    * @param enforce
214    * True if the value should be enforced to be one of the valid
215    * values or just regarded as a helpfull list
216    * @exception CatalogException
217    * Thrown if the type conversion (parameter type) fails
218    */

219   public DjDomain(String JavaDoc name, String JavaDoc type, int length, int decimals, String JavaDoc formatMask, String JavaDoc description,
220                   boolean enforce) throws CatalogException
221   {
222     _name = name;
223     _nativeTypeId = translateType(type);
224     _enforce = enforce;
225     _description = description;
226     _length = length;
227     _decimals = decimals;
228     _formatMask = formatMask;
229     _displayWidth = 0;
230     _displayHeight = 0;
231     _caseConversion = CASE_NONE;
232   }
233
234   /**
235    * Constructor for the DjDomain object
236    *
237    * @param name
238    * Name of the domain
239    * @param nativeType
240    * Type of the domain
241    * @param length
242    * Maximum length (if applicable)
243    * @param decimals
244    * Decimals (if applicable)
245    * @param formatMask
246    * Format mask (see java.text)
247    * @param description
248    * Description of the domain
249    * @param enforce
250    * True if the value should be enforced to be one of the valid
251    * values or just regarded as a helpfull list
252    */

253   public DjDomain(String JavaDoc name, int nativeType, int length, int decimals, String JavaDoc formatMask, String JavaDoc description,
254                   boolean enforce)
255   {
256     _name = name;
257     _nativeTypeId = nativeType;
258     _enforce = enforce;
259     _description = description;
260     _length = length;
261     _decimals = decimals;
262     _formatMask = formatMask;
263     _displayWidth = 0;
264     _displayHeight = 0;
265     _caseConversion = CASE_NONE;
266   }
267
268   /**
269    * Constructor for the DjDomain object
270    *
271    * @param superDomain
272    * The domain this domain is extended from (much like inheritance)
273    * @param name
274    * Name of the domain
275    * @param type
276    * Type of the domain (see translateType())
277    * @param length
278    * Maximum length (if applicable)
279    * @param decimals
280    * Decimals (if applicable)
281    * @param formatMask
282    * Format mask (see java.text)
283    * @param description
284    * Description of the domain
285    * @param enforce
286    * True if the value should be enforced to be one of the valid
287    * values or just regarded as a helpfull list
288    * @exception CatalogException
289    * Thrown if the type conversion (parameter type) fails
290    */

291   public DjDomain(DjDomain superDomain, String JavaDoc name, String JavaDoc type, int length, int decimals, String JavaDoc formatMask,
292                   String JavaDoc description, boolean enforce) throws CatalogException
293   {
294     this(name, type, length, decimals, formatMask, description, enforce);
295     _superDomain = superDomain;
296   }
297
298   /**
299    * Returns true if this domain is built in or additionally defined by the
300    * modeler. Built in domains are String, int, long, BigDecimal, byte[] and
301    * Date
302    *
303    * @return True if this domain is built in
304    */

305   public boolean isBuiltIn()
306   {
307     return isDynamic() || getName().equals("String") || getName().equals("int") || getName().equals("long")
308            || getName().equals("BigDecimal") || getName().equals("byte[]") || getName().equals("Date");
309   }
310
311   /**
312    * Converts a string to a date using the format mask provided
313    *
314    * @param dateString
315    * String representing the date
316    * @param mask
317    * The mask to be used during conversion
318    * @return The converted date
319    * @exception ParseException
320    * Thrown is the conversion fails (invalid representation /
321    * mask)
322    */

323   protected Date JavaDoc convertString2Date(String JavaDoc dateString, String JavaDoc mask) throws ParseException JavaDoc
324   {
325     if (mask == null) return sf.parse(dateString);
326
327     SimpleDateFormat JavaDoc m = new SimpleDateFormat JavaDoc(mask);
328     return m.parse(dateString);
329   }
330
331   /**
332    * Makes sure that the object provided as a parameter is the type as
333    * specified by the domain. For instance if a String value "100" is coersed
334    * for a domain that is actually a BigDecimal domain, a BigDecimal with value
335    * 100 is returned.
336    *
337    * @param obj
338    * The object to coerse
339    * @return The object correctly typed according to the domain
340    * @exception DjenericException
341    * Thrown if the coersion fails
342    */

343   public Object JavaDoc coerse(Object JavaDoc obj) throws DjenericException
344   {
345     int tc = getTypeCode();
346
347     if (obj == null) return null;
348
349     if (obj.toString().trim().length() == 0) return null;
350
351     if (tc == DjDomain.STRING_TYPE)
352     {
353       return obj.toString();
354     }
355
356     try
357     {
358       if (tc == DjDomain.BIGDECIMAL_TYPE)
359       {
360         if (obj instanceof BigDecimal JavaDoc) return obj;
361         return new BigDecimal JavaDoc(obj.toString());
362       }
363       else if (tc == DjDomain.BYTE_TYPE)
364       {
365         if (obj instanceof byte[]) return obj;
366         try
367         {
368           return obj.toString().getBytes(DjPersistenceManager.ENCODING_METHOD);
369         }
370         catch (UnsupportedEncodingException JavaDoc uee)
371         {
372           DjLogger.log(uee);
373           return obj.toString().getBytes();
374         }
375       }
376       else if (tc == DjDomain.DATE_TYPE)
377       {
378         if (obj instanceof Date JavaDoc) return obj;
379         return convertString2Date(obj.toString(), null);
380       }
381       else if (tc == DjDomain.INT_TYPE)
382       {
383         if (obj instanceof Integer JavaDoc) return obj;
384         return new Integer JavaDoc(obj.toString());
385       }
386       else if (tc == DjDomain.LONG_TYPE)
387       {
388         if (obj instanceof Long JavaDoc) return obj;
389         return new Long JavaDoc(obj.toString());
390       }
391     }
392     catch (ParseException JavaDoc x)
393     {
394       throw new DjenericException(Messages.getString("DjDomain.InvalidValue", obj, int2nativeType(tc)));
395     }
396     throw new CatalogException(Messages.getString("DjDomain.CannotCoerse", String.valueOf(tc)));
397   }
398
399   /**
400    * Sets the display width in pixels of the DjDomain object; for use in
401    * editors, reports etc.
402    *
403    * @param w
404    * The new display width value
405    */

406   public void setDisplayWidth(int w)
407   {
408     _displayWidth = w;
409   }
410
411   /**
412    * Returns the display width of the DjDomain object in pixels
413    *
414    * @return The display width
415    */

416   public int getDisplayWidth()
417   {
418     return _displayWidth;
419   }
420
421   /**
422    * Sets the displayHeight in pixels of the DjDomain object; for use in
423    * editors, reports etc.
424    *
425    * @param h
426    * The new display height
427    */

428   public void setDisplayHeight(int h)
429   {
430     _displayHeight = h;
431   }
432
433   /**
434    * Returns the display height in pixels of the DjDomain object
435    *
436    * @return The display height
437    */

438   public int getDisplayHeight()
439   {
440     return _displayHeight;
441   }
442
443   /**
444    * Returns the type name of the DjDomain object
445    *
446    * @return The type name
447    */

448   public String JavaDoc getTypeName()
449   {
450     return _name;
451   }
452
453   public String JavaDoc getTypeClassName()
454   {
455     return getNativeTypeClass().getName();
456   }
457
458   /**
459    * Returns the type code of the DjDomain object (one of COMP_TEXTFIELD,
460    * COMP_MEMO, COMP_COMBOBOX, COMP_CHECKBOX, COMP_PASSWORD)
461    *
462    * @return The typeCode value
463    */

464   public int getTypeCode()
465   {
466     if (_superDomain != null) return _superDomain.getTypeCode();
467     return _nativeTypeId;
468   }
469
470   /**
471    * Returns the format mask used for display and coersion purposes
472    *
473    * @return The formatMask value
474    */

475   public String JavaDoc getFormatMask()
476   {
477     return _formatMask;
478   }
479
480   /**
481    * Sets the format mask used for display and coersion purposes
482    *
483    * @param mask
484    * The new formatMask value
485    */

486   public void setFormatMask(String JavaDoc mask)
487   {
488     _formatMask = mask;
489   }
490
491   /**
492    * Compares two domains; returns true if the names match (ignoring case)
493    *
494    * @param o
495    * Description of the Parameter
496    * @return Description of the Return Value
497    */

498   public int compareTo(Object JavaDoc o)
499   {
500     if (!(o instanceof DjDomain)) return -1;
501
502     return getName().toLowerCase().compareTo(o.toString().toLowerCase());
503   }
504
505   /**
506    * Adds a DjDomainValue (range or value) to the list of valid values
507    *
508    * @param dv
509    * The DjDomainValue to be added to the list of valid values
510    */

511   public void addDomainValue(DjDomainValue dv)
512   {
513     _domainValues.add(dv);
514   }
515
516   /**
517    * Adds a DjDomainValue (range or value) to the list of valid values at a
518    * specified index
519    *
520    * @param atIdx
521    * The index of the value to be added
522    * @param dv
523    * The DjDomainValue to be added to the list of valid values
524    */

525   public void addDomainValue(int atIdx, DjDomainValue dv)
526   {
527     _domainValues.add(atIdx, dv);
528   }
529
530   /**
531    * Removes a DjDomainValue from the list of valid values
532    *
533    * @param dv
534    * The DjDomainValue to be removed
535    */

536   public void removeDomainValue(DjDomainValue dv)
537   {
538     _domainValues.remove(dv);
539   }
540
541   /**
542    * Returns the name of the DjDomain
543    *
544    * @return The name
545    */

546   public String JavaDoc getName()
547   {
548     return _name;
549   }
550
551   /**
552    * Sets the name of the DjDomain
553    *
554    * @param name
555    * The new name
556    */

557   public void setName(String JavaDoc name)
558   {
559     _name = name;
560   }
561
562   /**
563    * Sets the super domain of this domain; the domain that this domain must
564    * inherit from. Is allowed to be null for top-level domains
565    *
566    * @param s
567    * The new superDomain value
568    */

569   public void setSuperDomain(DjDomain s)
570   {
571     _superDomain = s;
572   }
573
574   /**
575    * Returns the super domain of this domain; the domain that this domain
576    * inherits from
577    *
578    * @return The super domain or null if there is no super
579    */

580   public DjDomain getSuperDomain()
581   {
582     return _superDomain;
583   }
584
585   /**
586    * Returns the description of the domain
587    *
588    * @return The description
589    */

590   public String JavaDoc getDescription()
591   {
592     return _description;
593   }
594
595   /**
596    * Returns true if values should be enforced according to the valid values
597    * defined for this domain. If not enforced the list of values will be
598    * interpreted as just being helpfull for screens etc.
599    *
600    * @return True if enforced
601    */

602   public boolean isEnforced()
603   {
604     return _enforce;
605   }
606
607   /**
608    * Set this to true if values should be enforced according to the valid
609    * values defined for this domain. If not enforced the list of values will be
610    * interpreted as just being helpfull for screens etc.
611    *
612    * @param b
613    * The new enforced value
614    */

615   public void setEnforced(boolean b)
616   {
617     _enforce = b;
618   }
619
620   /**
621    * Sets the description of the domain
622    *
623    * @param descr
624    * The new description
625    */

626   public void setDescription(String JavaDoc descr)
627   {
628     _description = descr;
629   }
630
631   /**
632    * Returns the size of the list of valid values
633    *
634    * @return The size of the list of valid values
635    */

636   public int getDomainValueCount()
637   {
638     int count = 0;
639     if (_superDomain != null) count = _superDomain.getDomainValueCount();
640     return _domainValues.size() + count;
641   }
642
643   /**
644    * Returns the size of the list of personal valid values
645    *
646    * @return The size of the list of valid values
647    */

648   public int getPersonalDomainValueCount()
649   {
650     return _domainValues.size();
651   }
652
653   /**
654    * Returns an ArrayList containing the domain values of this domain excluding
655    * any values that are inherited from a super domain (if applicable)
656    *
657    * @return The domain values
658    */

659   public ArrayList JavaDoc getPersonalDomainValues()
660   {
661     return _domainValues;
662   }
663
664   /**
665    * Translates a String value to a type code. Supported translations are
666    * String, int, Integer, long, Long, BigDecimal, byte[] and Date. The
667    * returned value is one of STRING_TYPE, INT_TYPE, LONG_TYPE, DATE_TYPE,
668    * BIGDECIMAL_TYPE and BYTE_TYPE
669    *
670    * @param type
671    * The type to translate
672    * @return The type code
673    * @exception CatalogException
674    * Thrown for unsupported types
675    */

676   protected int translateType(String JavaDoc type) throws CatalogException
677   {
678     if (type.equals("String"))
679     {
680       return STRING_TYPE;
681     }
682     if (type.equals("int"))
683     {
684       return INT_TYPE;
685     }
686     if (type.equals("Integer"))
687     {
688       return INT_TYPE;
689     }
690     if (type.equals("long"))
691     {
692       return LONG_TYPE;
693     }
694     if (type.equals("Long"))
695     {
696       return LONG_TYPE;
697     }
698     if (type.equals("Date"))
699     {
700       return DATE_TYPE;
701     }
702     if (type.equals("BigDecimal"))
703     {
704       return BIGDECIMAL_TYPE;
705     }
706     if (type.equals("byte[]"))
707     {
708       return BYTE_TYPE;
709     }
710     throw new CatalogException(Messages.getString("DjDomain.Unsupported_type", type));
711   }
712
713   /**
714    * Returns the Java native type of the domain (without the package prefix)
715    * The value returned is one of String, int, long, Date, byte[] and
716    * BigDecimal
717    *
718    * @return The Java native type as a String value
719    */

720   public String JavaDoc getNativeType()
721   {
722     if (_superDomain != null) return _superDomain.getNativeType();
723
724     if (_nativeTypeId == STRING_TYPE) return "String";
725     if (_nativeTypeId == INT_TYPE) return "int";
726     if (_nativeTypeId == LONG_TYPE) return "long";
727     if (_nativeTypeId == DATE_TYPE) return "Date";
728     if (_nativeTypeId == BYTE_TYPE) return "byte[]";
729     if (_nativeTypeId == BIGDECIMAL_TYPE) return "BigDecimal";
730
731     return "String";
732   }
733
734   public Class JavaDoc getNativeTypeClass()
735   {
736     if (_superDomain != null) return _superDomain.getNativeTypeClass();
737
738     if (_nativeTypeId == STRING_TYPE) return String JavaDoc.class;
739     if (_nativeTypeId == INT_TYPE) return Integer JavaDoc.class;
740     if (_nativeTypeId == LONG_TYPE) return Long JavaDoc.class;
741     if (_nativeTypeId == DATE_TYPE) return Date JavaDoc.class;
742     if (_nativeTypeId == BYTE_TYPE) return Byte JavaDoc[].class;
743     if (_nativeTypeId == BIGDECIMAL_TYPE) return BigDecimal JavaDoc.class;
744
745     return String JavaDoc.class;
746   }
747
748   /**
749    * Returns the Java native Object type of the domain (without the package
750    * prefix) The value returned is one of String, Integer, Long, Date, byte[]
751    * and BigDecimal
752    *
753    * @return The native Java Object type
754    */

755   public String JavaDoc getNativeTypeAsObject()
756   {
757     if (_superDomain != null) return _superDomain.getNativeType();
758
759     if (_nativeTypeId == STRING_TYPE) return "String";
760     if (_nativeTypeId == INT_TYPE) return "Integer";
761     if (_nativeTypeId == LONG_TYPE) return "Long";
762     if (_nativeTypeId == DATE_TYPE) return "Date";
763     if (_nativeTypeId == BYTE_TYPE) return "byte[]";
764     if (_nativeTypeId == BIGDECIMAL_TYPE) return "BigDecimal";
765
766     return "String";
767   }
768
769   /**
770    * Sets the native type of the domain. Valid values are String, int, Integer,
771    * long, Long, Date, byte[] and BigDecimal
772    *
773    * @param str
774    * The new nativeType value
775    * @exception DjenericException
776    * Thrown for unsupported types
777    */

778   public void setNativeType(String JavaDoc str) throws DjenericException
779   {
780     _nativeTypeId = translateType(str);
781   }
782
783   /**
784    * Returns the DjDomainValue at the index provided; use getDomainValueCount()
785    * to determine the number of valid valued/ranges defined for this domain.
786    * (this includes any values defined by a super domain)
787    *
788    * @param idx
789    * index of the value to be retruned
790    * @return The requested DjDomainValue
791    */

792   public DjDomainValue getDomainValue(int idx)
793   {
794     int count = 0;
795     if (_superDomain != null)
796     {
797       count = _superDomain.getDomainValueCount();
798       if (idx < count) return _superDomain.getDomainValue(idx);
799     }
800     idx -= count;
801     return (DjDomainValue) _domainValues.get(idx);
802   }
803
804   /**
805    * Returns the personal DjDomainValue at the index provided; use
806    * getPersonalDomainValueCount() to determine the number of valid
807    * valued/ranges defined for this domain. (this excludes any values defined
808    * by a super domain)
809    *
810    * @param idx
811    * index of the value to be retruned
812    * @return The requested DjDomainValue
813    */

814   public DjDomainValue getPersonalDomainValue(int idx)
815   {
816     return (DjDomainValue) _domainValues.get(idx);
817   }
818
819   /**
820    * Removes the domain value at the index provided; this call might be
821    * delegated to a super domain if the value is defined by a super domain.
822    *
823    * @param idx
824    * The index of the value to be removed
825    */

826   public void removeDomainValue(int idx)
827   {
828     int count = 0;
829     if (_superDomain != null)
830     {
831       count = _superDomain.getDomainValueCount();
832       if (idx < count) _superDomain.removeDomainValue(idx);
833     }
834     idx -= count;
835     _domainValues.remove(idx);
836   }
837
838   /**
839    * Removes the domain value at the index provided; this call might be
840    * delegated to a super domain if the value is defined by a super domain.
841    *
842    * @param idx
843    * The index of the value to be removed
844    */

845   public void removePersonalDomainValue(int idx)
846   {
847     _domainValues.remove(idx);
848   }
849
850   /**
851    * Validates a given value according to the valid values of the domain. If
852    * this domain is not enforced true is returned at all times. This method
853    * does NOT check the length/decimals of the value
854    *
855    * @param value
856    * Description of the Parameter
857    * @exception DomainViolationException
858    * Description of the Exception
859    */

860   public void validateValue(Object JavaDoc value) throws DomainViolationException
861   {
862     if (value == null) return;
863
864     if (getReValidationMask() != null)
865     {
866       String JavaDoc regExp = getReValidationMask().trim();
867       try
868       {
869         RE re = new RE("^" + regExp.trim() + "$");
870         if (!re.match(value.toString()))
871         {
872           String JavaDoc errMsg = getReFailureMessage();
873           if (errMsg == null || errMsg.trim().length() == 0)
874           {
875             errMsg = Messages.getString("DjDomain.ValueInvalid");
876           }
877           throw new DomainViolationException(errMsg);
878         }
879       }
880       catch (RESyntaxException rese)
881       {
882         throw new DomainViolationException(Messages.getString("global.CheckMask", getName(), regExp));
883       }
884     }
885     // First check the length
886
int propType = getTypeCode();
887     if (getLength() != 0)
888     {
889       try
890       {
891         value = coerse(value);
892         if (value == null) return;
893       }
894       catch (DjenericException de)
895       {
896         throw new DomainViolationException(de);
897       }
898
899       if (propType == DjDomain.BIGDECIMAL_TYPE)
900       {
901         BigDecimal JavaDoc bdv = (BigDecimal JavaDoc) value;
902         if (bdv.doubleValue() >= Math.pow(10, getLength()))
903         {
904           throw new DomainViolationException(Messages.getString("DjDomain.NumericLengthExceeded", String
905               .valueOf(getLength())));
906         }
907       }
908       else if (propType == DjDomain.STRING_TYPE)
909       {
910         if (value.toString().length() > getLength())
911         {
912           throw new DomainViolationException(Messages.getString("DjDomain.StringLengthExceeded", String
913               .valueOf(getLength())));
914         }
915       }
916       else if (propType == DjDomain.INT_TYPE)
917       {
918         Integer JavaDoc iv = (Integer JavaDoc) value;
919
920         if (iv.intValue() >= Math.pow(10, getLength()))
921         {
922           throw new DomainViolationException(Messages.getString("DjDomain.NumericLengthExceeded", String
923               .valueOf(getLength())));
924         }
925       }
926       else if (propType == DjDomain.LONG_TYPE)
927       {
928         Long JavaDoc lv = (Long JavaDoc) value;
929         if (lv.longValue() >= Math.pow(10, getLength()))
930         {
931           throw new DomainViolationException(Messages.getString("DjDomain.NumericLengthExceeded", String
932               .valueOf(getLength())));
933         }
934       }
935     }
936
937     if (_enforce)
938     {
939       boolean matched = false;
940
941       int valueCount = getDomainValueCount();
942
943       if (valueCount == 0) return;
944
945       for (int i = 0; i < valueCount && !matched; i++)
946       {
947         matched = getDomainValue(i).isValid(value);
948       }
949       if (!matched) throw new DomainViolationException(Messages.getString("DjDomain.IsNotValidValue", value));
950     }
951   }
952
953   /**
954    * Returns the maximum length of the values this domain can hold.
955    *
956    * @return The maximum length
957    */

958   public int getLength()
959   {
960     return _length;
961   }
962
963   /**
964    * Sets the maximum length of the values this domain can hold.
965    *
966    * @param length
967    * The new maimum length
968    */

969   public void setLength(int length)
970   {
971     _length = length;
972   }
973
974   /**
975    * Returns the maximum number of decimals of the values this domain can hold.
976    *
977    * @return The number of decimals
978    */

979   public int getDecimals()
980   {
981     return _decimals;
982   }
983
984   /**
985    * Sets the maximum number of decimals of the values this domain can hold.
986    *
987    * @param decimals
988    * The new number of decimals
989    */

990   public void setDecimals(int decimals)
991   {
992     _decimals = decimals;
993   }
994
995   /**
996    * Returns true if there is at least one valid valud/range defined for this
997    * domain (or at one of it's super domains)
998    *
999    * @return True if there is at least one valid valud/range defined
1000   */

1001  public boolean hasValidValues()
1002  {
1003    boolean has = false;
1004    if (_superDomain != null)
1005    {
1006      has |= _superDomain.hasValidValues();
1007    }
1008    if (has) return true;
1009    has |= getDomainValueCount() > 0;
1010    return has;
1011  }
1012
1013  /**
1014   * Translates a value into it's description using the valid values defined
1015   * for this domain. If no matching value is found null is returned.
1016   *
1017   * @param code
1018   * The code to be translated
1019   * @return Description of the Return Value
1020   */

1021  public String JavaDoc translateCode(String JavaDoc code)
1022  {
1023    DjDomainValue[] vals = getValidValues();
1024    for (int i = 0; i < vals.length; i++)
1025    {
1026      if (vals[i].getValue().toString().equals(code))
1027      {
1028        String JavaDoc descr = vals[i].getDescription();
1029        if (descr != null && descr.length() > 0) return descr;
1030        return code;
1031      }
1032    }
1033    return null;
1034  }
1035
1036  /**
1037   * Translates a description into it's corresponding value using the valid
1038   * values defined for this domain. If no matching description is found null
1039   * is returned.
1040   *
1041   * @param description
1042   * Description of the Parameter
1043   * @return Corresponding value
1044   */

1045  public String JavaDoc translateDescription(String JavaDoc description)
1046  {
1047    if (description == null) return null;
1048
1049    DjDomainValue[] vals = getValidValues();
1050    for (int i = 0; i < vals.length; i++)
1051    {
1052      String JavaDoc descr = vals[i].getDescription();
1053      if (descr == null || descr.length() == 0) descr = vals[i].getValue().toString();
1054
1055      if (descr.equals(description))
1056      {
1057        return vals[i].getValue().toString();
1058      }
1059    }
1060    return null;
1061  }
1062
1063  /**
1064   * Returns an array of all valid values for this domain. This includes the
1065   * values defined at the super domain(s) The result is sorted by sequence as
1066   * set in the model.
1067   *
1068   * @return Array of valid values
1069   */

1070  public DjDomainValue[] getValidValues()
1071  {
1072    ArrayList JavaDoc result = new ArrayList JavaDoc();
1073
1074    if (_superDomain != null)
1075    {
1076      DjDomainValue[] sups = _superDomain.getValidValues();
1077      for (int i = 0; i < sups.length; i++)
1078      {
1079        result.add(sups[i]);
1080      }
1081    }
1082
1083    for (int i = 0; i < getPersonalDomainValueCount(); i++)
1084    {
1085      DjDomainValue dv = getPersonalDomainValue(i);
1086      if (!dv.isRange()) result.add(dv);
1087    }
1088
1089    Collections.sort(result, new DomainValueComparator());
1090
1091    return (DjDomainValue[]) result.toArray(new DjDomainValue[0]);
1092  }
1093
1094  /**
1095   * Returns the name of the domain
1096   *
1097   * @return The name of the domain
1098   */

1099  public String JavaDoc toString()
1100  {
1101    return _name;
1102  }
1103
1104  /**
1105   * Validates the definition of the domain; used by the validateModel method
1106   * of the persistence manager
1107   *
1108   * @param mgr
1109   * The manager the domain should be validated against
1110   * @param strictChecking
1111   * If true; all constraints must be met. If not relax them a bit
1112   * if applicable
1113   * @exception CatalogException
1114   * Throw if a problem is detected
1115   */

1116  protected void validate(DjPersistenceManager mgr, boolean strictChecking) throws CatalogException
1117  {
1118    if (_name.trim().length() == 0) throw new CatalogException(Messages.getString("DjDomain.NameUnique"));
1119    for (int i = 0; i < mgr.getDomainCount(); i++)
1120    {
1121      if (mgr.getDomain(i) != this && mgr.getDomain(i).getName().toLowerCase().equals(getName()))
1122      {
1123        throw new CatalogException(Messages.getString("DjDomain.NameUniqueNotUnqiue", getName()));
1124      }
1125    }
1126
1127    if ((getTypeCode() != BIGDECIMAL_TYPE) && (getDecimals() != 0))
1128    {
1129      throw new CatalogException(Messages.getString("DjDomain.ShouldNotHaveDecs", getName(), getNativeType()));
1130    }
1131
1132    if ((getTypeCode() == DATE_TYPE) && (getLength() != 0))
1133    {
1134      throw new CatalogException(Messages.getString("DjDomain.ShouldNotHaveLen", getName()));
1135    }
1136
1137    for (int i = 0; i < getDomainValueCount(); i++)
1138    {
1139      DjDomainValue dv = getDomainValue(i);
1140      if (dv.getValue() == null)
1141      {
1142        throw new CatalogException(Messages.getString("DjDomain.DomainValueNull", getName()));
1143      }
1144
1145      if (dv.getDescription() == null || dv.getDescription().trim().length() == 0)
1146      {
1147        throw new CatalogException(Messages.getString("DjDomain.DomainValueDescrNull", (getName() + "." + dv.getValue()
1148            .toString())));
1149      }
1150    }
1151
1152    for (int i = 0; i < getDomainValueCount(); i++)
1153    {
1154      DjDomainValue dv1 = getDomainValue(i);
1155      String JavaDoc code = dv1.getValue().toString();
1156      code = dv1.getValue().toString();
1157
1158      if (getTypeCode() == INT_TYPE || getTypeCode() == LONG_TYPE || getTypeCode() == STRING_TYPE)
1159      {
1160        if (getLength() != 0 && code.length() > getLength())
1161        {
1162          throw new CatalogException(Messages.getString("DjDomain.DomainMaxLengthExceeded", (getName() + "." + dv1
1163              .getValue().toString())));
1164        }
1165      }
1166      for (int j = 0; j < getDomainValueCount(); j++)
1167      {
1168        DjDomainValue dv2 = getDomainValue(j);
1169        if (dv1 != dv2 && dv1.getDescription().trim().equals(dv2.getDescription().trim()))
1170        {
1171          throw new CatalogException(Messages.getString("DjDomain.ValueDescrUnique", getName() + "."
1172                                                                                     + dv1.getValue().toString()));
1173        }
1174      }
1175    }
1176
1177    if (getReValidationMask() != null)
1178    {
1179      String JavaDoc regExp = getReValidationMask().trim();
1180
1181      try
1182      {
1183        RE re = new RE("^" + regExp.trim() + "$");
1184
1185        for (int j = 0; j < getDomainValueCount(); j++)
1186        {
1187          DjDomainValue dv = getDomainValue(j);
1188          if (!re.match(dv.getValue().toString()))
1189          {
1190            throw new CatalogException(Messages.getString("DjDomain.MaskFails", getName() + "."
1191                                                                                + dv.getValue().toString()));
1192          }
1193        }
1194      }
1195      catch (RESyntaxException rese)
1196      {
1197        throw new CatalogException(Messages.getString("global.CheckMask", getName(), regExp));
1198      }
1199    }
1200
1201    // if (isEnforced() && getDomainValueCount() == 0)
1202
// {
1203
// throw new CatalogException(
1204
// "Domain "
1205
// + getName()
1206
// + " is requested to enforce it's value to be one of the listed values
1207
// but no valid values are defined");
1208
// }
1209
}
1210
1211  /**
1212   * Sets the component type to be used to display/edit the values in this
1213   * domain. Supported types are "TextField", "Memo", "Combobox", "Checkbox",
1214   * "Password"
1215   *
1216   * @param typeName
1217   * The new component type
1218   * @exception DjenericException
1219   * Thrown for unsupported types
1220   */

1221  public void setComponentType(String JavaDoc typeName) throws DjenericException
1222  {
1223    _componentType = componentType2int(typeName);
1224  }
1225
1226  /**
1227   * Sets the component type to be used to display/edit the values in this
1228   * domain. Supported types are COMP_TEXTFIELD, COMP_MEMO, COMP_COMBOBOX,
1229   * COMP_CHECKBOX, COMP_PASSWORD
1230   *
1231   * @param type
1232   * The new component type
1233   */

1234  public void setComponentType(int type)
1235  {
1236    _componentType = type;
1237  }
1238
1239  /**
1240   * Returns the component type to be used to display/edit the values in this
1241   * domain. One of COMP_TEXTFIELD, COMP_MEMO, COMP_COMBOBOX, COMP_CHECKBOX,
1242   * COMP_PASSWORD
1243   *
1244   * @return The componentType value
1245   */

1246  public int getComponentType()
1247  {
1248    return _componentType;
1249  }
1250
1251  /**
1252   * Returns the component type to be used to display/edit the values in this
1253   * domain. One of "TextField", "Memo", "Combobox", "Checkbox", "Password"
1254   *
1255   * @return The component type name
1256   */

1257  public String JavaDoc getComponentTypeName()
1258  {
1259    return int2componentType(_componentType);
1260  }
1261
1262  /**
1263   * Converts a component type (COMP_TEXTFIELD, COMP_MEMO, COMP_COMBOBOX,
1264   * COMP_CHECKBOX, COMP_PASSWORD) to a String representation ("TextField",
1265   * "Memo", "Combobox", "Checkbox", "Password")
1266   *
1267   * @param componentType
1268   * The type
1269   * @return The String representation
1270   */

1271  public static String JavaDoc int2componentType(int componentType)
1272  {
1273    return compTypes[componentType];
1274  }
1275
1276  /**
1277   * Converts a component type code (COMP_TEXTFIELD, COMP_MEMO, COMP_COMBOBOX,
1278   * COMP_CHECKBOX, COMP_PASSWORD) into the corresponding String representation
1279   * ("TextField", "Memo", "Combobox", "Checkbox", "Password")
1280   *
1281   * @param typeCode
1282   * The type
1283   * @return The String representation
1284   */

1285  public static String JavaDoc int2nativeType(int typeCode)
1286  {
1287    return nativeTypes[typeCode];
1288  }
1289
1290  /**
1291   * Converts a component type String representation ("TextField", "Memo",
1292   * "Combobox", "Checkbox", "Password") into the corresponding code:
1293   * (COMP_TEXTFIELD, COMP_MEMO, COMP_COMBOBOX, COMP_CHECKBOX, COMP_PASSWORD)
1294   *
1295   * @param typeName
1296   * Description of the Parameter
1297   * @return The String representation
1298   * @exception CatalogException
1299   * Description of the Exception
1300   */

1301  public static int componentType2int(String JavaDoc typeName) throws CatalogException
1302  {
1303    if (typeName == null) typeName = "";
1304    if (typeName.length() == 0)
1305    {
1306      return COMP_TEXTFIELD;
1307    }
1308
1309    for (int i = 0; i < compTypes.length; i++)
1310    {
1311      if (compTypes[i].equalsIgnoreCase(typeName))
1312      {
1313        return i;
1314      }
1315    }
1316    throw new CatalogException(Messages.getString("DjDomain.InvalidComponentType", typeName));
1317  }
1318
1319  /**
1320   * Returns a String array of all supported component type String
1321   * representations {"TextField", "Memo", "Combobox", "Checkbox", "Password"}
1322   *
1323   * @return The representations
1324   */

1325  public static String JavaDoc[] getComponentTypeNames()
1326  {
1327    return compTypes;
1328  }
1329
1330  /**
1331   * Sorts the domain values by their sequence
1332   */

1333  public void sort()
1334  {
1335    Collections.sort(_domainValues, new DomainValueComparator());
1336  }
1337
1338  /**
1339   * Returns the valid value that is the closest to the supplied value If no
1340   * value is found, null is returned
1341   *
1342   * @param value
1343   * The value to look for
1344   * @return The matching valid value
1345   */

1346  public DjDomainValue looselyMatchValue(String JavaDoc value)
1347  {
1348    return looselyMatchValue(getValidValues(), value);
1349  }
1350
1351  /**
1352   * Returns the valid value who's description is the closest to the supplied
1353   * value If no value is found, null is returned
1354   *
1355   * @param value
1356   * The description to look for
1357   * @return The matching valid value
1358   */

1359  public DjDomainValue looselyMatchDescription(String JavaDoc value)
1360  {
1361    return looselyMatchDescription(getValidValues(), value);
1362  }
1363
1364  /**
1365   * Converts a list of DjObjects to an array of valid values using the object
1366   * as value and the descriptor of the object as the description of the value.
1367   *
1368   * @param list
1369   * List of DjObjects to be converted
1370   * @return Array of valid values
1371   * @exception DjenericException
1372   * Thrown if the descriptor of an object fails
1373   */

1374  public static DjDomainValue[] convertToValueList(DjList list) throws DjenericException
1375  {
1376    DjDomainValue[] valids = new DjDomainValue[list.size()];
1377    for (int i = 0; i < list.size(); i++)
1378    {
1379      valids[i] = new DjDomainValue(null, list.getDjenericObjectAt(i), list.getDjenericObjectAt(i).getDescriptor());
1380    }
1381    Arrays.sort(valids, new DomainValueDescrComparator());
1382    return valids;
1383  }
1384
1385  /**
1386   * Returns the valid value that is the closest to the supplied value If no
1387   * value is found, null is returned
1388   *
1389   * @param values
1390   * The values to use for the search
1391   * @param value
1392   * The value to search for
1393   * @return The matched DjDomainValue
1394   */

1395  public static DjDomainValue looselyMatchValue(DjDomainValue[] values, String JavaDoc value)
1396  {
1397    if (value == null) return null;
1398
1399    // first match strict..
1400
for (int i = 0; i < values.length; i++)
1401    {
1402      if (values[i] == null || values[i].getValue() == null) continue;
1403      if (values[i].getValue().toString().equals(value)) return values[i];
1404    }
1405    // match first part
1406
for (int i = 0; i < values.length; i++)
1407    {
1408      if (values[i] == null || values[i].getValue() == null) continue;
1409      if (values[i].getValue().toString().startsWith(value)) return values[i];
1410    }
1411    // match ignore case
1412
for (int i = 0; i < values.length; i++)
1413    {
1414      if (values[i] == null || values[i].getValue() == null) continue;
1415      if (values[i].getValue().toString().equalsIgnoreCase(value)) return values[i];
1416    }
1417    // match first part ignore case
1418
for (int i = 0; i < values.length; i++)
1419    {
1420      if (values[i] == null || values[i].getValue() == null) continue;
1421      if (values[i].getValue().toString().toLowerCase().startsWith(value.toLowerCase())) return values[i];
1422    }
1423    return null;
1424  }
1425
1426  /**
1427   * Returns the valid value who's description is the closest to the supplied
1428   * value If no value is found, null is returned
1429   *
1430   * @param values
1431   * The values to use for the search
1432   * @param value
1433   * The value to search for
1434   * @return The matched DjDomainValue
1435   */

1436  public static DjDomainValue looselyMatchDescription(DjDomainValue[] values, String JavaDoc value)
1437  {
1438    if (value == null || value.length() == 0) return null;
1439
1440    // first match strict..
1441
for (int i = 0; i < values.length; i++)
1442    {
1443      String JavaDoc descr = values[i].getDescription();
1444      if (descr == null) descr = "";
1445
1446      if (descr.equals(value)) return values[i];
1447    }
1448    // match first part
1449
for (int i = 0; i < values.length; i++)
1450    {
1451      String JavaDoc descr = values[i].getDescription();
1452      if (descr == null) descr = "";
1453
1454      if (descr.startsWith(value)) return values[i];
1455    }
1456    // match ignore case
1457
for (int i = 0; i < values.length; i++)
1458    {
1459      String JavaDoc descr = values[i].getDescription();
1460      if (descr == null) descr = "";
1461
1462      if (descr.equalsIgnoreCase(value)) return values[i];
1463    }
1464    // match first part ignore case
1465
for (int i = 0; i < values.length; i++)
1466    {
1467      String JavaDoc descr = values[i].getDescription();
1468      if (descr == null) descr = "";
1469
1470      if (descr.toLowerCase().startsWith(value.toLowerCase())) return values[i];
1471    }
1472    return null;
1473  }
1474
1475  public static boolean isMemoComponent(int type)
1476  {
1477    return type == COMP_MEMO || type == COMP_HTML_MEMO || type == COMP_CUSTOM_MEMO;
1478  }
1479
1480  public String JavaDoc getReFailureMessage()
1481  {
1482    return _reFailureMessage;
1483  }
1484
1485  public String JavaDoc getReValidationMask()
1486  {
1487    return _reValidationMask;
1488  }
1489
1490  public void setReFailureMessage(String JavaDoc msg)
1491  {
1492    if (msg != null && msg.trim().length() == 0) msg = null;
1493    _reFailureMessage = msg;
1494  }
1495
1496  public void setReValidationMask(String JavaDoc mask)
1497  {
1498    if (mask != null && mask.trim().length() == 0) mask = null;
1499    _reValidationMask = mask;
1500  }
1501
1502  public String JavaDoc getCaseConversion()
1503  {
1504    return _caseConversion;
1505  }
1506
1507  public void setCaseConversion(String JavaDoc caseConversion)
1508  {
1509    _caseConversion = caseConversion;
1510  }
1511
1512  public boolean hasListValues()
1513  {
1514    boolean has = false;
1515    if (_superDomain != null)
1516    {
1517      has |= _superDomain.hasListValues();
1518    }
1519    if (has) return true;
1520    for (int i = 0; !has && i < getDomainValueCount(); i++)
1521    {
1522      has = getDomainValue(i).getHigh() == null;
1523    }
1524    return has;
1525  }
1526
1527  // Returns true if it is a domain created by the persistence manager at
1528
// run-time
1529
public boolean isDynamic()
1530  {
1531    return _isDynamic;
1532  }
1533
1534  public void setDynamic(boolean isDynamic)
1535  {
1536    _isDynamic = isDynamic;
1537  }
1538
1539  public DjPackage getPackage()
1540  {
1541    return _package;
1542  }
1543
1544  public void setPackage(DjPackage pack)
1545  {
1546    _package = pack;
1547  }
1548
1549}
Popular Tags