Maps an optional namespace and optional schemaLocation to an Include or Import object.
As we include/import schemas, we append to one of these, and before we
include/import we check to see if it is already here.
About use of Delay[T]:
This is fairly deep function programming stuff, but it let's us have
our cake and eat it too for one thing. In processing of import
statements like this <xs:include schemaLocation="..."/>, the chicken/egg
problem arises about namespaces. We have to read the file just in order
to know the namespace in order to be able to decide if we have seen
this (NS, URL) pair before, and therefore don't need to load the
file....
So we maintain this growing map of (NS, URL) => file called an IIMap.
We use delay on this, because it lets us construct the DFDLSchemaFile,
construct the XMLSchemaDocument object, both of which require that
we pass in the IIMap. Then we can ask the XMLSchemaDocument for the
targetNamespace of the file, which will cause the file to be read.
But none of this needs the IIMap argument yet.
We then look at this new (tns, url) pair, and see if it is already
in the map. If not, we extend the IIMap,... and by the magic of
Delayed evaluation, that map is the one being passed to the
DFDLSchemaFile and XMLSchemaDocument above.
Seems cyclical, but it isn't. We can call the constructors, passing
them a promise (aka Delayed IIMap) to deliver the IIMap when it is
needed. Turns out it isn't needed for the constructed object to
answer the question "what is the targetNamespace". But that target
namespace information IS needed to determine the IIMap which will
be supplied when demanded.
From an ObjectOriented programing perspective, we don't pass an IIMap,
we pass an IIMap factory (a delayed IIMap is effectively that). That
factory isn't being called yet, and by the way it has pointers back
to data structures that will be filled in later, so it can't be called
yet. You wouldn't write an OO program this way usually.
Note that we must use a map that maintains insertion order, of which
ListMap is one of them.
Maps an optional namespace and optional schemaLocation to an Include or Import object.
As we include/import schemas, we append to one of these, and before we include/import we check to see if it is already here.
About use of Delay[T]:
This is fairly deep function programming stuff, but it let's us have our cake and eat it too for one thing. In processing of import statements like this <xs:include schemaLocation="..."/>, the chicken/egg problem arises about namespaces. We have to read the file just in order to know the namespace in order to be able to decide if we have seen this (NS, URL) pair before, and therefore don't need to load the file....
So we maintain this growing map of (NS, URL) => file called an IIMap.
We use delay on this, because it lets us construct the DFDLSchemaFile, construct the XMLSchemaDocument object, both of which require that we pass in the IIMap. Then we can ask the XMLSchemaDocument for the targetNamespace of the file, which will cause the file to be read. But none of this needs the IIMap argument yet.
We then look at this new (tns, url) pair, and see if it is already in the map. If not, we extend the IIMap,... and by the magic of Delayed evaluation, that map is the one being passed to the DFDLSchemaFile and XMLSchemaDocument above.
Seems cyclical, but it isn't. We can call the constructors, passing them a promise (aka Delayed IIMap) to deliver the IIMap when it is needed. Turns out it isn't needed for the constructed object to answer the question "what is the targetNamespace". But that target namespace information IS needed to determine the IIMap which will be supplied when demanded.
From an ObjectOriented programing perspective, we don't pass an IIMap, we pass an IIMap factory (a delayed IIMap is effectively that). That factory isn't being called yet, and by the way it has pointers back to data structures that will be filled in later, so it can't be called yet. You wouldn't write an OO program this way usually.
Note that we must use a map that maintains insertion order, of which ListMap is one of them.