/* * @(#)$Id: ComplexAcceptorBaseImpl.java,v 1.7 2001/08/10 22:24:13 Bear Exp $ * * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * * This software is the proprietary information of Sun Microsystems, Inc. * Use is subject to license terms. * */ package com.sun.msv.verifier.regexp; import com.sun.msv.grammar.Expression; import com.sun.msv.grammar.ElementExp; import com.sun.msv.grammar.IDContextProvider; import com.sun.msv.verifier.Acceptor; import com.sun.msv.verifier.regexp.StringToken; import com.sun.msv.verifier.regexp.Token; import com.sun.msv.verifier.regexp.AnyElementToken; import com.sun.msv.verifier.regexp.ElementToken; import com.sun.msv.verifier.regexp.ResidualCalculator; import com.sun.msv.util.StringRef; import com.sun.msv.util.DatatypeRef; import com.sun.msv.util.StartTagInfo; /** * base implementation of ComplexAcceptor. * * @author <a href="mailto:kohsuke.kawaguchi@eng.sun.com">Kohsuke KAWAGUCHI</a> */ public abstract class ComplexAcceptorBaseImpl extends ContentModelAcceptor { protected final Expression[] contents; public ComplexAcceptorBaseImpl( REDocumentDeclaration docDecl, Expression combined, Expression[] contents, boolean ignoreUndeclaredAttributes ) { super( docDecl, combined, ignoreUndeclaredAttributes ); this.contents = contents; } /** eats string literal */ public final boolean onText( String literal, IDContextProvider context, StringRef refErr, DatatypeRef refType ) { if(!super.onText(literal,context,refErr,refType)) return false; final StringToken token = new StringToken(docDecl,literal,context); final ResidualCalculator res = docDecl.resCalc; // some may become invalid, but at least one always remain valid for( int i=0; i<contents.length; i++ ) contents[i] = res.calcResidual( contents[i], token ); return true; } public final boolean stepForward( Acceptor child, StringRef errRef ) { if(!super.stepForward(child,errRef)) return false; final ResidualCalculator res = docDecl.resCalc; Token token; if( child instanceof SimpleAcceptor ) { // this is possible although it is very rare. // continuation cannot be used here, because // some contents[i] may reject this owner. ElementExp cowner = ((SimpleAcceptor)child).owner; if( cowner==null ) // cowner==null means we are currently recovering from an error. // so use AnyElementToken to make contents[i] happy. token = AnyElementToken.theInstance; else token = new ElementToken( new ElementExp[]{cowner} ); } else { if( errRef!=null ) // in error recovery mode // pretend that every candidate of child ComplexAcceptor is happy token = new ElementToken( ((ComplexAcceptor)child).owners ); else // in normal mode, collect only those satisfied owners. token = new ElementToken( ((ComplexAcceptor)child).getSatisfiedOwners() ); } for( int i=0; i<contents.length; i++ ) contents[i] = res.calcResidual( contents[i], token ); return true; } protected boolean onAttribute( AttributeToken token, StringRef refErr ) { if(!super.onAttribute(token,refErr)) return false; for( int i=0; i<contents.length; i++ ) contents[i] = docDecl.attFeeder.feed( contents[i], token, ignoreUndeclaredAttributes ); return true; } public boolean onEndAttributes( StartTagInfo sti, StringRef refErr ) { if(!super.onEndAttributes(sti,refErr)) return false; for( int i=0; i<contents.length; i++ ) contents[i] = docDecl.attPruner.prune(contents[i]); return true; } }