/*
* @(#)$Id: TREXBaseReader.java,v 1.19 2002/03/04 00:53:48 kk122374 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.reader.trex;
import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.Map;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.SAXException;
import org.relaxng.datatype.Datatype;
import org.iso_relax.dispatcher.IslandSchema;
import org.iso_relax.verifier.Schema;
import com.sun.msv.datatype.xsd.StringType;
import com.sun.msv.grammar.*;
import com.sun.msv.grammar.trex.*;
import com.sun.msv.reader.*;
import com.sun.msv.reader.datatype.DataTypeVocabulary;
import com.sun.msv.util.StartTagInfo;
import com.sun.msv.util.LightStack;
/**
* reads TREX grammar from SAX2 and constructs abstract grammar model.
*
* @author <a href="mailto:kohsuke.kawaguchi@eng.sun.com">Kohsuke KAWAGUCHI</a>
*/
public abstract class TREXBaseReader extends GrammarReader {
/** full constructor */
public TREXBaseReader(
GrammarReaderController controller,
SAXParserFactory parserFactory,
ExpressionPool pool,
StateFactory stateFactory,
State rootState ) {
super(controller,parserFactory,pool,rootState);
this.sfactory = stateFactory;
}
protected String localizeMessage( String propertyName, Object[] args ) {
String format;
try {
format = ResourceBundle.getBundle("com.sun.msv.reader.trex.Messages").getString(propertyName);
} catch( Exception e ) {
format = ResourceBundle.getBundle("com.sun.msv.reader.Messages").getString(propertyName);
}
return MessageFormat.format(format, args );
}
/** grammar object currently being loaded. */
protected TREXGrammar grammar;
/** obtains parsed grammar object only if parsing was successful. */
public final TREXGrammar getResult() {
if(controller.hadError()) return null;
else return grammar;
}
public Grammar getResultAsGrammar() {
return getResult();
}
/** stack that stores value of ancestor 'ns' attribute. */
private LightStack nsStack = new LightStack();
/** target namespace: currently active 'ns' attribute */
protected String targetNamespace ="";
public final String getTargetNamespace() { return targetNamespace; }
/**
* creates various State object, which in turn parses grammar.
* parsing behavior can be customized by implementing custom StateFactory.
*/
public static abstract class StateFactory {
public State nsName ( State parent, StartTagInfo tag ) { return new NameClassNameState(); }
public State nsAnyName ( State parent, StartTagInfo tag ) { return new NameClassAnyNameState(); }
public State nsNsName ( State parent, StartTagInfo tag ) { return new NameClassNsNameState(); }
public State nsNot ( State parent, StartTagInfo tag ) { return new NameClassNotState(); }
public State nsDifference( State parent, StartTagInfo tag ) { return new NameClassDifferenceState(); }
public State nsChoice ( State parent, StartTagInfo tag ) { return new NameClassChoiceState(); }
public State element ( State parent, StartTagInfo tag ) { return new ElementState(); }
public State attribute ( State parent, StartTagInfo tag ) { return new AttributeState(); }
public State group ( State parent, StartTagInfo tag ) { return new SequenceState(); }
public State interleave ( State parent, StartTagInfo tag ) { return new InterleaveState(); }
public State choice ( State parent, StartTagInfo tag ) { return new ChoiceState(); }
public State optional ( State parent, StartTagInfo tag ) { return new OptionalState(); }
public State zeroOrMore ( State parent, StartTagInfo tag ) { return new ZeroOrMoreState(); }
public State oneOrMore ( State parent, StartTagInfo tag ) { return new OneOrMoreState(); }
public State mixed ( State parent, StartTagInfo tag ) { return new MixedState(); }
public State empty ( State parent, StartTagInfo tag ) { return new TerminalState(Expression.epsilon); }
public State notAllowed ( State parent, StartTagInfo tag ) { return new TerminalState(Expression.nullSet); }
public State includeGrammar( State parent, StartTagInfo tag ) { return new IncludeMergeState(); }
public State grammar ( State parent, StartTagInfo tag ) { return new GrammarState(); }
public State start ( State parent, StartTagInfo tag ) { return new StartState(); }
public abstract State define( State parent, StartTagInfo tag );
public State ref ( State parent, StartTagInfo tag ) {
return new RefState("true".equals(tag.getAttribute("parent")));
}
// <div>s in the <grammar> element is not available by default.
public State divInGrammar( State parent, StartTagInfo tag ) { return null; }
public TREXGrammar createGrammar( ExpressionPool pool, TREXGrammar parent ) {
return new TREXGrammar(pool,parent);
}
}
public final StateFactory sfactory;
protected State createNameClassChildState( State parent, StartTagInfo tag )
{
if(tag.localName.equals("name")) return sfactory.nsName(parent,tag);
if(tag.localName.equals("anyName")) return sfactory.nsAnyName(parent,tag);
if(tag.localName.equals("nsName")) return sfactory.nsNsName(parent,tag);
if(tag.localName.equals("not")) return sfactory.nsNot(parent,tag);
if(tag.localName.equals("difference")) return sfactory.nsDifference(parent,tag);
if(tag.localName.equals("choice")) return sfactory.nsChoice(parent,tag);
return null; // unknown element. let the default error be thrown.
}
public State createExpressionChildState( State parent, StartTagInfo tag )
{
if(tag.localName.equals("element")) return sfactory.element(parent,tag);
if(tag.localName.equals("attribute")) return sfactory.attribute(parent,tag);
if(tag.localName.equals("group")) return sfactory.group(parent,tag);
if(tag.localName.equals("interleave")) return sfactory.interleave(parent,tag);
if(tag.localName.equals("choice")) return sfactory.choice(parent,tag);
// if(tag.localName.equals("concur")) return sfactory.concur(parent,tag);
if(tag.localName.equals("optional")) return sfactory.optional(parent,tag);
if(tag.localName.equals("zeroOrMore")) return sfactory.zeroOrMore(parent,tag);
if(tag.localName.equals("oneOrMore")) return sfactory.oneOrMore(parent,tag);
if(tag.localName.equals("mixed")) return sfactory.mixed(parent,tag);
if(tag.localName.equals("ref")) return sfactory.ref(parent,tag);
if(tag.localName.equals("empty")) return sfactory.empty(parent,tag);
// if(tag.localName.equals("anyString")) return sfactory.anyString(parent,tag);
// if(tag.localName.equals("string")) return sfactory.string(parent,tag);
// if(tag.localName.equals("data")) return sfactory.data(parent,tag);
if(tag.localName.equals("notAllowed")) return sfactory.notAllowed(parent,tag);
if(tag.localName.equals("grammar")) return sfactory.grammar(parent,tag);
return null; // unknown element. let the default error be thrown.
}
/**
* performs final wrap-up.
* This method is called from the RootState object, after the parsing is completed.
*
* <p>
* This method has to be called after the run-away expression check is done.
*/
public void wrapUp() {}
// SAX event interception
//--------------------------------
public void startElement( String a, String b, String c, Attributes d ) throws SAXException
{
// handle 'ns' attribute propagation
nsStack.push(targetNamespace);
if( d.getIndex("ns")!=-1 )
targetNamespace = d.getValue("ns");
// if nothing specified, targetNamespace stays the same.
// for root state, startTag is null.
super.startElement(a,b,c,d);
}
public void endElement( String a, String b, String c ) throws SAXException
{
super.endElement(a,b,c);
targetNamespace = (String)nsStack.pop();
}
// error messages
public static final String ERR_MISSING_CHILD_NAMECLASS = // arg:0
"TREXGrammarReader.MissingChildNameClass";
public static final String ERR_MORE_THAN_ONE_NAMECLASS = // arg:0
"TREXGrammarReader.MoreThanOneNameClass";
public static final String ERR_UNDECLARED_PREFIX = // arg:1
"TREXGrammarReader.UndeclaredPrefix";
public static final String ERR_UNDEFINED_PATTERN = // arg:1
"TREXGrammarReader.UndefinedPattern";
public static final String ERR_UNKNOWN_DATATYPE_VOCABULARY = // arg:1
"TREXGrammarReader.UnknownDataTypeVocabulary";
public static final String ERR_BAD_COMBINE = // arg:1
"TREXGrammarReader.BadCombine";
public static final String ERR_COMBINE_MISSING = // arg:1
"TREXGrammarReader.CombineMissing";
public static final String WRN_COMBINE_IGNORED =
"TREXGrammarReader.Warning.CombineIgnored";
public static final String WRN_OBSOLETED_XMLSCHEMA_NAMSPACE =
"TREXGrammarReader.Warning.ObsoletedXMLSchemaNamespace";
public static final String ERR_DUPLICATE_DEFINITION =
"TREXGrammarReader.DuplicateDefinition";
public static final String ERR_NONEXISTENT_PARENT_GRAMMAR =
"TREXGrammarReader.NonExistentParentGrammar";
public static final String ERR_INTERLEAVED_STRING =
"TREXGrammarReader.InterleavedString";
public static final String ERR_SEQUENCED_STRING =
"TREXGrammarReader.SequencedString";
public static final String ERR_REPEATED_STRING =
"TREXGrammarReader.RepeatedString";
public static final String ERR_INTERLEAVED_ANYSTRING =
"TREXGrammarReader.InterleavedAnyString";
}