001 package com.thaiopensource.relaxng.impl; 002 003 import com.thaiopensource.xml.util.Name; 004 005 import java.util.Hashtable; 006 007 class FindElementFunction extends AbstractPatternFunction { 008 private final ValidatorPatternBuilder builder; 009 private final Name name; 010 private final Hashtable processed = new Hashtable(); 011 private int specificity = NameClass.SPECIFICITY_NONE; 012 private Pattern pattern = null; 013 014 static public Pattern findElement(ValidatorPatternBuilder builder, Name name, Pattern start) { 015 FindElementFunction f = new FindElementFunction(builder, name); 016 start.apply(f); 017 if (f.pattern == null) 018 return builder.makeNotAllowed(); 019 return f.pattern; 020 } 021 022 private FindElementFunction(ValidatorPatternBuilder builder, Name name) { 023 this.builder = builder; 024 this.name = name; 025 } 026 027 private boolean haveProcessed(Pattern p) { 028 if (processed.get(p) != null) 029 return true; 030 processed.put(p, p); 031 return false; 032 } 033 034 private Object caseBinary(BinaryPattern p) { 035 if (!haveProcessed(p)) { 036 p.getOperand1().apply(this); 037 p.getOperand2().apply(this); 038 } 039 return null; 040 041 } 042 043 public Object caseGroup(GroupPattern p) { 044 return caseBinary(p); 045 } 046 047 public Object caseInterleave(InterleavePattern p) { 048 return caseBinary(p); 049 } 050 051 public Object caseChoice(ChoicePattern p) { 052 return caseBinary(p); 053 } 054 055 public Object caseOneOrMore(OneOrMorePattern p) { 056 if (!haveProcessed(p)) 057 p.getOperand().apply(this); 058 return null; 059 } 060 061 public Object caseElement(ElementPattern p) { 062 if (!haveProcessed(p)) { 063 int s = p.getNameClass().containsSpecificity(name); 064 if (s > specificity) { 065 specificity = s; 066 pattern = p.getContent(); 067 } 068 else if (s == specificity && s != NameClass.SPECIFICITY_NONE) 069 pattern = builder.makeChoice(pattern, p.getContent()); 070 p.getContent().apply(this); 071 } 072 return null; 073 } 074 075 public Object caseOther(Pattern p) { 076 return null; 077 } 078 }