001    package market;
002    
003    import java.text.SimpleDateFormat;
004    
005    /**
006     * A ValueChecker, which checks if a String is in the format dd.MM.yyyy (e.g. 01.01.2000).<br>
007     * Notations like 1.1.2000 are also not allowed.<br>
008     * <br>
009     * As this ValueChecker is only used by {@link market.swing.JTFCheckable checkable text fields},
010     * an identifier is passed via the constructor. This descriptive identifier is used in the error string,
011     * to enable the user to associate an error message with the causative text field.
012     */
013    public class VCDate implements ValueChecker {
014    
015        /**
016             * ID for serialization.
017             */
018            private static final long serialVersionUID = -5194876720743799136L;
019    
020            /**
021         * The identifier used by {@link #getErrorString()}.
022         */
023        protected String identifier;
024    
025        /**
026         * Defines if an empty String is considered to be an error or not.
027         */
028        protected boolean mayBeEmpty;
029    
030        /**
031         * Internal error code. Set by {@link #isValidValue(String)}, queried by {@link #getErrorString()}.
032         */
033        private int error = 0;
034    
035        /**
036         * @param identifier the identifier.
037         * @param mayBeEmpty <code>true</code> if an empty should be considered valid, otherwise <code>false</code>.
038         */
039        public VCDate(String identifier, boolean mayBeEmpty) {
040            this.identifier = identifier;
041            this.mayBeEmpty = mayBeEmpty;
042        }
043    
044        /**
045         * @param identifier the identifier.
046         */
047        public VCDate(String identifier) {
048            this.identifier = identifier;
049            this.mayBeEmpty = false;
050        }
051    
052        /**
053         * Checks String for validity and, if necessary, sets an internal error code according to the
054         * detected error.
055         * @param content the String to be checked.
056         * @return <code>true</code> if the String is in a valid date format, otherwise <code>false</code>.
057         */
058        public boolean isValidValue(String content) {
059            error = 0;
060            if (!mayBeEmpty && content.equals("")) {
061                error = 1;
062            } else {
063                //dd.MM.yyyy: strict check - the days' values are checked regarding the month, including leap years
064                SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
065                sdf.setLenient(false);
066                try {
067                    sdf.parse(content);
068                    //Parsing also accepts dates without left handed zeros, so this extra check for the
069                    //String's length is being done
070                    if (content.length() != 10) {
071                        error = 2;
072                    }
073                }
074                catch (java.text.ParseException e) {
075                    error = 2;
076                }
077            }
078            return error == 0;
079        }
080    
081        /**
082         * @return an error message depending on the value of {@link #error}.
083         */
084        public String getErrorString() {
085            String returnValue = "";
086            switch (error) {
087                case 1:
088                    returnValue = "Fehlerhafte Eingabe im Feld " + identifier +
089                            ": Das Feld darf nicht leer sein.";
090                    break;
091                case 2:
092                    returnValue = "Fehlerhafte Eingabe im Feld " + identifier +
093                            ": Das Datum muss in der Form 01.01.2000 angegeben werden.";
094                    break;
095            }
096            error = 0;
097            return returnValue;
098        }
099    }