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 }