001    package com.thaiopensource.relaxng.impl;
002    
003    class DataDerivTypeFunction extends AbstractPatternFunction {
004      private final ValidatorPatternBuilder builder;
005    
006      DataDerivTypeFunction(ValidatorPatternBuilder builder) {
007        this.builder = builder;
008      }
009    
010      static DataDerivType dataDerivType(ValidatorPatternBuilder builder, Pattern pattern) {
011        return (DataDerivType)pattern.apply(builder.getDataDerivTypeFunction());
012      }
013    
014      public Object caseOther(Pattern p) {
015        return new SingleDataDerivType();
016      }
017    
018      public Object caseAfter(AfterPattern p) {
019        Pattern p1 = p.getOperand1();
020        DataDerivType ddt = apply(p.getOperand1());
021        if (!p1.isNullable())
022          return ddt;
023        return ddt.combine(new BlankDataDerivType());
024      }
025    
026      private Object caseBinary(BinaryPattern p) {
027        return apply(p.getOperand1()).combine(apply(p.getOperand2()));
028      }
029    
030      public Object caseChoice(ChoicePattern p) {
031        return caseBinary(p);
032      }
033    
034      public Object caseGroup(GroupPattern p) {
035        return caseBinary(p);
036      }
037    
038      public Object caseInterleave(InterleavePattern p) {
039        return caseBinary(p);
040      }
041    
042      public Object caseOneOrMore(OneOrMorePattern p) {
043        return apply(p.getOperand());
044      }
045    
046      public Object caseList(ListPattern p) {
047        return InconsistentDataDerivType.getInstance();
048      }
049    
050      public Object caseValue(ValuePattern p) {
051        return new ValueDataDerivType(p.getDatatype());
052      }
053    
054      public Object caseData(DataPattern p) {
055        if (p.allowsAnyString())
056          return new SingleDataDerivType();
057        return new DataDataDerivType(p.getDatatype());
058      }
059    
060      public Object caseDataExcept(DataExceptPattern p) {
061        if (p.allowsAnyString())
062          return apply(p.getExcept());
063        return new DataDataDerivType(p.getDatatype()).combine(apply(p.getExcept()));
064      }
065    
066      private DataDerivType apply(Pattern p) {
067        return builder.getPatternMemo(p).dataDerivType();
068      }
069    }