001 package com.thaiopensource.relaxng.impl;
002
003 import com.thaiopensource.xml.util.Name;
004
005 class StartTagOpenDerivFunction extends AbstractPatternFunction {
006 private final Name name;
007 private final ValidatorPatternBuilder builder;
008
009 StartTagOpenDerivFunction(Name name, ValidatorPatternBuilder builder) {
010 this.name = name;
011 this.builder = builder;
012 }
013
014 public Object caseChoice(ChoicePattern p) {
015 return builder.makeChoice(memoApply(p.getOperand1()),
016 memoApply(p.getOperand2()));
017 }
018
019 public Object caseGroup(GroupPattern p) {
020 final Pattern p1 = p.getOperand1();
021 final Pattern p2 = p.getOperand2();
022 Pattern tem = memoApply(p1).applyForPattern(
023 new ApplyAfterFunction(builder) {
024 Pattern apply(Pattern x) {
025 return builder.makeGroup(x, p2);
026 }
027 });
028 return p1.isNullable() ? builder.makeChoice(tem, memoApply(p2)) : tem;
029 }
030
031 public Object caseInterleave(InterleavePattern p) {
032 final Pattern p1 = p.getOperand1();
033 final Pattern p2 = p.getOperand2();
034 return builder.makeChoice(
035 memoApply(p1).applyForPattern(new ApplyAfterFunction(builder) {
036 Pattern apply(Pattern x) {
037 return builder.makeInterleave(x, p2);
038 }
039 }),
040 memoApply(p2).applyForPattern(new ApplyAfterFunction(builder) {
041 Pattern apply(Pattern x) {
042 return builder.makeInterleave(p1, x);
043 }
044 }));
045 }
046
047 public Object caseAfter(AfterPattern p) {
048 final Pattern p1 = p.getOperand1();
049 final Pattern p2 = p.getOperand2();
050 return memoApply(p1).applyForPattern(
051 new ApplyAfterFunction(builder) {
052 Pattern apply(Pattern x) {
053 return builder.makeAfter(x, p2);
054 }
055 });
056 }
057
058 public Object caseOneOrMore(final OneOrMorePattern p) {
059 final Pattern p1 = p.getOperand();
060 return memoApply(p1).applyForPattern(
061 new ApplyAfterFunction(builder) {
062 Pattern apply(Pattern x) {
063 return builder.makeGroup(x,
064 builder.makeOptional(p));
065 }
066 });
067 }
068
069
070 public Object caseElement(ElementPattern p) {
071 if (!p.getNameClass().contains(name))
072 return builder.makeNotAllowed();
073 return builder.makeAfter(p.getContent(), builder.makeEmpty());
074 }
075
076 public Object caseOther(Pattern p) {
077 return builder.makeNotAllowed();
078 }
079
080 final Pattern memoApply(Pattern p) {
081 return apply(builder.getPatternMemo(p)).getPattern();
082 }
083
084 PatternMemo apply(PatternMemo memo) {
085 return memo.startTagOpenDeriv(this);
086 }
087
088 Name getName() {
089 return name;
090 }
091
092 ValidatorPatternBuilder getPatternBuilder() {
093 return builder;
094 }
095 }