I agree with Andy in that we should introduce new interface(s) for grammar
loading, but got some different ideas about how to define such
interface(s).

First of all, we need classes to actually load different kinds of grammars.
To allow the user to implement a loader for new kinds of grammars, we need
an interface for these loaders. We can call it XMLGrammarLoader. It needs
the following methods (please refer to Andy's XMLGrammarParser interface)
- methods for features/properties
- methods for error handler, entity resolver, and grammar pool
- a loadGrammar() method

Note that in Xerces implementation, error handler, entity resolver, and
grammar pool are all properties, so we can ignore this set of methods. Now
we can see how similar this interface is to XMLComponent. Let's keep this
in mind.

Then how will the users use the loader classes? The implementation classes
are deep inside the impl package, and we shouldn't ask/encourage the users
to call them directly. An idea would be to provide a class (possibly in
xerces.parser package), which has a loadGrammar(grammarType, input) method.
This maps to Andy's XMLGrammarCache class. But I don't like the idea that
it implements XMLGrammarPool. I think the relationship between grammar pool
and grammar loader is that the loader uses the pool to store/cache
grammars, instead of that the pool calls the loader to load grammars. So
I'd like to see that the grammar pool is passed to grammar loader as a
property. (This is how we implemented the schema grammar loader.) Let's
call this class XMLGrammarCache for now, but we really need a better name.
Methods required on XMLGrammarCache:
- methods for features/properties
- methods for error handler, entity resolver, and grammar pool
- a loadGrammar() method
- an addGrammarLoader() method (please refer to Neil's response)

Now recall the similarity between XMLGrammarLoader and XMLComponent, and
apparent XMLGrammarCache managers XMLGrammarLoader, so why don't we derive
XMLGrammarLoader from XMLComponent, and make XMLGrammarCache implement
XMLComponentManager?

    interface XMLGrammarLoader extends XMLComponent {
      public Grammar loadGrammar(XMLInputSource) throws ...;
    }

    class XMLGrammarCache implements XMLComponentManager {
      public void setFeature(...) throws ...;
      public void setProperty(...) throws ...;
      public XMLEntityResolver getEntityResolver();
      public void setEntityResolver(...);
      public XMLErrorHandler getErrorHandler();
      public void setErrorHandler(...);
      public Grammar loadGrammar(String, XMLInputSource) throws ...;
      public void addGrammarLoader(String, XMLGrammarLoader) throws ...;
    }

The constructor of XMLGrammarCache can register loaders for DTD and schema
(just like the standard parser configuration has DTD and schema validators
in it). Now anyone who wants to load a grammar can instantiate an
XMLGrammarCache, and call loadGrammar on it.

The last question is how the validators (in the parser pipeline) load
grammars. One way of doing it is to make XMLGrammarCache a
component/property of the parser. The configuration creates/registers it,
and validators query/use it. Of course, this requires XMLGrammarCache to be
both a component, and a component manager. Another approach is not to use
XMLGrammarCache in the configuration, but each validator uses the proper
loader class directly. I don't have a preference here.

Cheers,
Sandy Gao
Software Developer, IBM Canada
(1-905) 413-3255
[EMAIL PROTECTED]



                                                                                       
                            
                    Andy Clark                                                         
                            
                    <andyc@apache.       To:     [EMAIL PROTECTED]           
                            
                    org>                 cc:                                           
                            
                                         Subject:     Re: grammar preparsing API:  
some options                    
                    04/10/2002                                                         
                            
                    06:53 AM                                                           
                            
                    Please respond                                                     
                            
                    to                                                                 
                            
                    xerces-j-dev                                                       
                            
                                                                                       
                            
                                                                                       
                            



[EMAIL PROTECTED] wrote:
> [...]

Let me rehash your options as one-liners:

  (a) Convenience methods on configuration impl and/or grammar impl.
  (b) Extend parser config interface to add grammar loading methods.
  (c) Add method to grammar interface.
  (d) Create new grammar cache interface.
  (e) Make grammar pool do both loading and caching.

> Note we haven't addressed the question as to what the parseGrammar method
> should do when presented with a grammar type it doesn't understand; my
> thought would be to throw an XMLConfigurationException but Andy probably
> has a different view.  :-)

Am I that transparent? ;) Yes, I do have a different view. The
configuration exception doesn't make sense for this purpose.

> My own preferences would be (b) then (e) then (d).  I don't like the
other
> two much at all.

I hate (b); I don't like (c); and (e) doesn't seem appropriate
because caching is not the only reason to parse grammars. A
user may want to parse a grammar to investigate its content
models, etc. without caching or validating anything.

It's true that at the moment we haven't defined how a person
would generically access the contents of a DTD, XML Schema, or
other kind of grammar. But there's nothing preventing us from
doing that in the future (perhaps in xni.grammars.dtd and
xni.grammars.xs packages???). This is just like the situation
where grammar caching was an implementation detail until we
understood their usage enough to design appropriate interfaces.

I like (d) the most but I wouldn't call it XMLGrammarCache
-- otherwise, what's the difference with (e)? And I wouldn't
append "Configuration" either because I don't see any reason
for grammar parsing pipelines.

How about just "XMLGrammarParser"? It would share many of
the same methods as the XMLParserConfiguration -- but this
does *not* mean we should extend that interface as suggested
by choice (b).

  interface XMLGrammarParser

    setFeature(String,boolean) throws XMLConfigurationException
    getFeature(String):boolean throws XMLConfigurationException
    setProperty(String,Object) throws XMLConfigurationException
    getProperty(String):Object throws XMLConfigurationException

    setLocale(Locale)
    getLocale():Locale

    setErrorHandler(XMLErrorHandler)
    getErrorHandler():XMLErrorHandler
    setEntityResolver(XMLEntityResolver)
    getEntityResolver():XMLEntityResolver

    parseGrammar(XMLInputSource source):Grammar
      throws IOException, XNIException

Following this approach, we would *not* put parseGrammar
methods on the grammar implementations themselves but would
rather have a separate parser class for those grammar impls.
For example, we would have the "DTDGrammar" and its
corresponding "DTDGrammarParser" which would implement the
XMLGrammarParser interface.

The next thing is that we would probably want to have a
grammar cache implementation that would have a method to
load grammars of different types. Notice the difference in
that its "parseGrammar" method takes a String parameter
for the grammar type:

  class XMLGrammarCache implements XMLGrammarPool

    setFeature(String,boolean) throws XMLConfigurationException
    getFeature(String):boolean throws XMLConfigurationException
    setProperty(String,Object) throws XMLConfigurationException
    getProperty(String):Object throws XMLConfigurationException

    setLocale(Locale)
    getLocale():Locale

    setErrorHandler(XMLErrorHandler)
    getErrorHandler():XMLErrorHandler
    setEntityResolver(XMLEntityResolver)
    getEntityResolver():XMLEntityResolver

    loadGrammar(String,XMLInputSource) throws IOException,
      XNIException

We could even implement this class generically so that
grammar parsers are "installed" in much the same way that
message providers are installed on the error reporter
component. This way, the standard parser configuration
would install parsers for DTDs and XML Schemas but other
people can re-use the grammar cache impl when they make
new configurations with the grammar/validator(s) of
their choice.

Suddenly my head hurts... I hope this makes sense and/or
seems like a reasonable solution.

Comments?

--
Andy Clark * [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to