Hi Andy,

> Neil, thanks for such a detailed posting. I think you've captured
the problems with a decent solution, as well.

Thanks!

> Of course, as always,
I have some tweaks to suggest. :)

We'd all get worried if you didn't!  :-)

>You introduce an interface called XMLGrammarDescription which is
actually more like an XMLLocator (sans the row and column info).
And then you proceed to use it in a modified XMLEntityResolver
interface. If it's going to be a generic locator, of sorts, then
I think we should definitely change the name to indicate its
more general purpose.

Good point; the similarity between XMLGrammarDescription and the current
XMLLocator had escaped me.  So how about this:  create an
XMLResourceDescription interface which contains all information about the
physical location of any XML resource (publicId, systemId, baseURI).
XMLLocator then ixtends this interface, as does XMLGrammarDescription,
which also stores the type of the grammar.  I've attached the complete,
reworked interfaces to this message.

>Since we need a resolver for both entities and for locating
grammars, perhaps we should define a more generic location
interface in the core XNI that would then be used by the entity
resolver interface. It could then be extended for use by the
grammar resolution mechanism.

Right; see below.

>But I need to ask if you have a
solution for the grammar resolver needs access to the entity
resolver problem?

I claim that this should never be necessary, and would in fact be
dangerous.  It isn't necessary because the GrammarPool's job is to identify
objects whose location is totally under the application's control; figuring
out which of potentially thousands of objects to return is its special
concern.  The EntityResolver may have to contend with all kinds of
different physical resources (dealing with firewalls, compressed files
etc.); if it can lay hold of the resource its job will in most cases be
done.  To my mind there's little potential for code sharing here.

Interaction would be dangerous because, for instance, if a schema parser
requests a grammar and the GrammarPool goes to parse it, then if the new
grammar refers to the one which triggered the call to the GrammarPool an
infinite recursion could easily result.

So I think we should clearly state in the documentation that there should
be no interaction between these objects, and that they'll be called
GrammarPool first, EntityResolver second.  If the user violates this
injunction it's their business of course--no way to stop folks writing
buggy applications...

>The DTDDescription interface has a method called "getEntityName".
The documentation states that this method can return the root
element name *or* the name of an entity declaration. If the
method serves this dual purpose then the name is wrong. I don't
have an alternate suggestion at the moment, though, but we
should change it.

Actually that's a class (a fact that perhaps needs to change), but point
taken.  I agree with you and there's more about that class about which I'm
uncertain--should we expose what the purpose of the entity being requested
is (general, parameter)?  I'd really love it if someone more experienced
with dTD's would adopt this class and make appropriate changes.

// The Grammar Pool interface
public interface XMLGrammarPool {

    // we are trying to make this XMLGrammarPool work for all kinds of
    // grammars, so we have a parameter "grammarType" for each of the methods.
    // It could be "schema", "dtd, etc., or it could be recast into an
    // integer.

    // retrieve the initial known set of grammars. this method is
    // called by a validator before the validation starts. the application
    // can provide an initial set of grammars available to the current
    // validation attempt.
    public Grammar[] retrieveInitialGrammarSet(String grammarType);

    // return the final set of grammars that the validator ended up
    // with.
    // This method is called after the
    // validation finishes. The application may then choose to cache some
    // of the returned grammars.
    public void cacheGrammars(String grammarType, Grammar[] grammars);

    // This method requests that the application retrieve a grammar
    // corresponding to the given GrammarDescription from its cache.
    // If it cannot do so it must return null; the parser will then
    // call the EntityResolver.  An application must not call its
    // EntityResolver itself from this method.
    public Grammar retrieveGrammar(XMLGrammarDescription desc);

} // XMLGrammarPool

// This represents the basic physical description of the location of any
// XML resource (a Schema grammar, a DTD, a general entity etc.)
public interface XMLResourceDescription {

    /** Returns the public identifier. */
    public String getPublicId();

    /** Returns the system identifier. */
    public String getSystemId();

    /** Returns the base system identifier. */
    public String getBaseSystemId();
} // XMLResourceDescription

// This interface describes basic attributes of XML grammars--their
// physical location and their type.
public interface XMLGrammarDescription  extends XMLResourceDescription {
    // returns the type of the grammar (e.g., DTD or XSD).
    public String getGrammarType();
} // XMLGrammarDescription

// All information specific to dTD grammars.
public class XMLDTDDescription implements XMLGrammarDescription {
    // used to indicate whether it's an internal or external DTD
    public final static int INTERNAL_DTD = 0;
    public final static int EXTERNAL_DTD = 1;

    public int getDTDType();

    // this returns the name of the root element if this is a DOCTYPE
    // entity, or the name of the entity if it's a standard entity
    // declaration.
    public String getEntityName();
}

// All information specific to XML Schema grammars.
public class XSDDescription implements XMLGrammarDescription {
    // used to indicate what triggered the call
    // we don't include xsi:schemaLocation/noNamespaceSchemaLocation
    // because we'll defer the loading of schema documents until
    // a component from that namespace is referenced from the instance
    public final static int CONTEXT_INCLUDE   = 0;
    public final static int CONTEXT_REDEFINE  = 1;
    public final static int CONTEXT_IMPORT    = 2;
    public final static int CONTEXT_ELEMENT   = 3;
    public final static int CONTEXT_ATTRIBUTE = 4;
    public final static int CONTEXT_XSITYPE   = 5;

    public int getContextType();

    // for include and redefine, the namespace will be the target
    // namespace of the enclosing document. (or empty string?)
    public String getTargetNamespace();

    // for import and xsi:location attributes, it's possible to have
    // multiple hints for one namespace. so it's an array whose first
    // element will derive from the noNamespaceSchemaLocation or
    // schemaLocation property as the case of the targetNamespace may
    // be:
    public String[] getLocationHints();

    // If it's triggered by the document, the name of the
    // triggering component: element, attribute or xsi:type
    public QName getTriggeringComponent();

    // More information about "other location hint":
    // everything about the enclosing element
    public QName getEnclosingElementName();
    public XMLAttributes getAttributes();
}

/**
 * This interface is used to resolve external parsed entities. The
 * application can register an object that implements this interface
 * with the parser configuration in order to intercept entities and
 * resolve them explicitly. If the registered entity resolver cannot
 * resolve the entity, it should return <code>null</code> so that the
 * parser will try to resolve the entity using a default mechanism.
 *
 * @see XMLParserConfiguration
 *
 * @author Andy Clark, IBM
 *
 * @version $Id: XMLEntityResolver.java,v 1.2 2001/08/23 00:35:37 lehors Exp $
 */
public interface XMLEntityResolver {

    //
    // XMLEntityResolver methods
    //

    /**
     * Resolves an external parsed entity. If the entity cannot be
     * resolved, this method should return null.
     *
     * @param desc:  contains a description for the type of entity
     *      (grammar, abstract schema) being sought.
     * @throws XNIException Thrown on general error.
     * @throws IOException  Thrown if resolved entity stream cannot be
     *                      opened or some other i/o error occurs.
     */
    public XMLInputSource resolveEntity(XMLResourceDescription desc)
        throws XNIException, IOException;

} // interface XMLEntityResolver


/**
 * Location information.
 * <p>In addition to storing information as to the physical location of
 *  a resource, provides a means for pointing to individual
 *  characters in the resource.</p>
 *
 * @author Andy Clark, IBM
 *
 * @version $Id: XMLLocator.java,v 1.2 2001/08/23 00:35:36 lehors Exp $
 */
public interface XMLLocator extends XMLResourceDescription {

    //
    // XMLLocator methods
    //

    /** Returns the line number. */
    public int getLineNumber();

    /** Returns the column number. */
    public int getColumnNumber();

} // interface XMLLocator

Cheers,
Neil


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

Reply via email to