001 package com.thaiopensource.relaxng.impl; 002 003 class InterleavePattern extends BinaryPattern { 004 InterleavePattern(Pattern p1, Pattern p2) { 005 super(p1.isNullable() && p2.isNullable(), 006 combineHashCode(INTERLEAVE_HASH_CODE, p1.hashCode(), p2.hashCode()), 007 p1, 008 p2); 009 } 010 Pattern expand(SchemaPatternBuilder b) { 011 Pattern ep1 = p1.expand(b); 012 Pattern ep2 = p2.expand(b); 013 if (ep1 != p1 || ep2 != p2) 014 return b.makeInterleave(ep1, ep2); 015 else 016 return this; 017 } 018 void checkRestrictions(int context, DuplicateAttributeDetector dad, Alphabet alpha) 019 throws RestrictionViolationException { 020 switch (context) { 021 case START_CONTEXT: 022 throw new RestrictionViolationException("start_contains_interleave"); 023 case DATA_EXCEPT_CONTEXT: 024 throw new RestrictionViolationException("data_except_contains_interleave"); 025 case LIST_CONTEXT: 026 throw new RestrictionViolationException("list_contains_interleave"); 027 } 028 if (context == ELEMENT_REPEAT_CONTEXT) 029 context = ELEMENT_REPEAT_INTERLEAVE_CONTEXT; 030 Alphabet a1; 031 if (alpha != null && alpha.isEmpty()) 032 a1 = alpha; 033 else 034 a1 = new Alphabet(); 035 p1.checkRestrictions(context, dad, a1); 036 if (a1.isEmpty()) 037 p2.checkRestrictions(context, dad, a1); 038 else { 039 Alphabet a2 = new Alphabet(); 040 p2.checkRestrictions(context, dad, a2); 041 a1.checkOverlap(a2); 042 if (alpha != null) { 043 if (alpha != a1) 044 alpha.addAlphabet(a1); 045 alpha.addAlphabet(a2); 046 } 047 } 048 if (!contentTypeGroupable(p1.getContentType(), p2.getContentType())) 049 throw new RestrictionViolationException("interleave_string"); 050 if (p1.getContentType() == MIXED_CONTENT_TYPE 051 && p2.getContentType() == MIXED_CONTENT_TYPE) 052 throw new RestrictionViolationException("interleave_text_overlap"); 053 } 054 055 void accept(PatternVisitor visitor) { 056 visitor.visitInterleave(p1, p2); 057 } 058 Object apply(PatternFunction f) { 059 return f.caseInterleave(this); 060 } 061 }