001package clone.prototype;
002import java.util.Random;
003public class PersonFactory {
004        private static SSNObj prototypeSSN = new SSNObj();
005        private static PersonObj prototypePerson = new PersonObj();
006
007        private PersonFactory() {}
008        static private Random random = new Random();
009        static public SSN newSSN(String s) {
010                final int REQUIREDLENGTH = 9;
011                if (null == s || REQUIREDLENGTH != s.length())
012                        throw new IllegalArgumentException();
013                boolean someNonZeroDigit = false;
014                for (int i=0; i<REQUIREDLENGTH; i++) {
015                        char c = s.charAt(i);
016                        if (!Character.isDigit(c))
017                                throw new IllegalArgumentException();
018                        if (0 != Character.digit(c,10))
019                                someNonZeroDigit = true;
020                }
021                if (!someNonZeroDigit)
022                        throw new IllegalArgumentException();
023                return ((SSNObj)prototypeSSN.clone()).initialize(s);
024        }
025        static public Person newRandomPerson() {
026                return ((PersonObj)prototypePerson.clone()).
027                                initialize(Integer.toString(random.nextInt()),SSN.INVALID);
028        }
029        static public Person newPerson(String name, String ssn) {
030                return ((PersonObj)prototypePerson.clone()).initialize(name,ssn);
031        }
032        static public Person newPerson(String name, SSN ssn) {
033                return ((PersonObj)prototypePerson.clone()).initialize(name,ssn);
034        }
035}
036
037final class SSNObj implements SSN {
038        private String s;
039        private long l;
040        SSNObj() {}
041        SSNObj initialize(String s) {
042                this.s = s;
043                this.l = Long.parseLong(s);
044                return this;
045        }
046        public String toString() { return s; }
047        public long toLong() { return l; }
048        // TODO: define equals, hashcode, compareTo
049        public int compareTo(SSN o) { return -1; }
050        public Object clone() {
051                try {
052                        return super.clone();
053                } catch (CloneNotSupportedException e) {
054                        throw new RuntimeException(e);
055                }
056        }
057}
058
059final class PersonObj implements Person {
060        private String name;
061        private SSN ssn;
062        PersonObj() {}
063        PersonObj initialize(String name, SSN ssn) {
064                if (null == name || 0 == name.trim().length())
065                        throw new IllegalArgumentException();
066                this.name = name.trim();
067                this.ssn = ssn;
068                return this;
069        }
070        PersonObj initialize(String name, String ssn) {
071                return initialize(name,PersonFactory.newSSN(ssn));
072        }
073        public String name() { return name; }
074        public SSN ssn() { return ssn; }
075        // TODO: define equals, hashcode, compareTo
076        public int compareTo(Person o) { return -1; }
077        public Object clone() {
078                try {
079                        return super.clone();
080                } catch (CloneNotSupportedException e) {
081                        throw new RuntimeException(e);
082                }
083        }
084}