package com.thaiopensource.relaxng.pattern; import com.thaiopensource.xml.util.Name; class OverlapDetector implements NameClassVisitor { private final NameClass nc1; private final NameClass nc2; private Name overlapExample = null; private static final String IMPOSSIBLE = "\u0000"; private OverlapDetector(NameClass nc1, NameClass nc2) { this.nc1 = nc1; this.nc2 = nc2; nc1.accept(this); nc2.accept(this); } private void probe(Name name) { if (nc1.contains(name) && nc2.contains(name)) overlapExample = name; } public void visitChoice(NameClass nc1, NameClass nc2) { nc1.accept(this); nc2.accept(this); } public void visitNsName(String ns) { probe(new Name(ns, IMPOSSIBLE)); } public void visitNsNameExcept(String ns, NameClass ex) { probe(new Name(ns, IMPOSSIBLE)); ex.accept(this); } public void visitAnyName() { probe(new Name(IMPOSSIBLE, IMPOSSIBLE)); } public void visitAnyNameExcept(NameClass ex) { probe(new Name(IMPOSSIBLE, IMPOSSIBLE)); ex.accept(this); } public void visitName(Name name) { probe(name); } public void visitNull() { } public void visitError() { } static void checkOverlap(NameClass nc1, NameClass nc2, String messageForName, String messageForNs, String messageForOther) throws RestrictionViolationException { if (nc2 instanceof SimpleNameClass) { SimpleNameClass snc = (SimpleNameClass)nc2; if (nc1.contains(snc.getName())) throw new RestrictionViolationException(messageForName, snc.getName()); } else if (nc1 instanceof SimpleNameClass) { SimpleNameClass snc = (SimpleNameClass)nc1; if (nc2.contains(snc.getName())) throw new RestrictionViolationException(messageForName, snc.getName()); } else { Name name = new OverlapDetector(nc1, nc2).overlapExample; if (name != null) { String localName = name.getLocalName(); if (localName == IMPOSSIBLE) { String ns = name.getNamespaceUri(); if (ns == IMPOSSIBLE) throw new RestrictionViolationException(messageForOther); else throw new RestrictionViolationException(messageForNs, ns); } else throw new RestrictionViolationException(messageForName, name); } } } }