001    package com.thaiopensource.relaxng.impl;
002    
003    public class PatternBuilder {
004      private final EmptyPattern empty;
005      protected final NotAllowedPattern notAllowed;
006      protected final PatternInterner interner;
007    
008      public PatternBuilder() {
009        empty = new EmptyPattern();
010        notAllowed = new NotAllowedPattern();
011        interner = new PatternInterner();
012      }
013    
014      public PatternBuilder(PatternBuilder parent) {
015        empty = parent.empty;
016        notAllowed = parent.notAllowed;
017        interner = new PatternInterner(parent.interner);
018      }
019    
020      Pattern makeEmpty() {
021        return empty;
022      }
023    
024      Pattern makeNotAllowed() {
025        return notAllowed;
026      }
027    
028      Pattern makeGroup(Pattern p1, Pattern p2) {
029        if (p1 == empty)
030          return p2;
031        if (p2 == empty)
032          return p1;
033        if (p1 == notAllowed || p2 == notAllowed)
034          return notAllowed;
035        if (false && p1 instanceof GroupPattern) {
036          GroupPattern sp = (GroupPattern)p1;
037          return makeGroup(sp.p1, makeGroup(sp.p2, p2));
038        }
039        Pattern p = new GroupPattern(p1, p2);
040        return interner.intern(p);
041      }
042    
043      Pattern makeInterleave(Pattern p1, Pattern p2) {
044        if (p1 == empty)
045          return p2;
046        if (p2 == empty)
047          return p1;
048        if (p1 == notAllowed || p2 == notAllowed)
049          return notAllowed;
050        if (false && p1 instanceof InterleavePattern) {
051          InterleavePattern ip = (InterleavePattern)p1;
052          return makeInterleave(ip.p1, makeInterleave(ip.p2, p2));
053        }
054        if (false) {
055        if (p2 instanceof InterleavePattern) {
056          InterleavePattern ip = (InterleavePattern)p2;
057          if (p1.hashCode() > ip.p1.hashCode())
058            return makeInterleave(ip.p1, makeInterleave(p1, ip.p2));
059        }
060        else if (p1.hashCode() > p2.hashCode())
061          return makeInterleave(p2, p1);
062        }
063        Pattern p = new InterleavePattern(p1, p2);
064        return interner.intern(p);
065      }
066    
067      Pattern makeChoice(Pattern p1, Pattern p2) {
068        if (p1 == empty && p2.isNullable())
069          return p2;
070        if (p2 == empty && p1.isNullable())
071          return p1;
072        Pattern p = new ChoicePattern(p1, p2);
073        return interner.intern(p);
074      }
075    
076      Pattern makeOneOrMore(Pattern p) {
077        if (p == empty
078            || p == notAllowed
079            || p instanceof OneOrMorePattern)
080          return p;
081        Pattern p1 = new OneOrMorePattern(p);
082        return interner.intern(p1);
083      }
084    
085      Pattern makeOptional(Pattern p) {
086        return makeChoice(p, empty);
087      }
088    
089      Pattern makeZeroOrMore(Pattern p) {
090        return makeOptional(makeOneOrMore(p));
091      }
092    }