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 }