DOM guide: Resolving URIs: Difference between revisions

From COLLADA Public Wiki
Jump to navigation Jump to search
Alorino (talk | contribs)
No edit summary
SteveT (talk | contribs)
No edit summary
 
(27 intermediate revisions by 2 users not shown)
Line 1: Line 1:
The <code>daeURI</code> class represents URI data types in the [[COLLADA DOM]]. The <code>daeURI</code> class provides an interface for accessing/manipulating the URI string and for resolving the URI reference.
The <code>daeURI</code> class represents [[URI]] data types in the [[COLLADA DOM]]. This class provides an interface for accessing and manipulating the URI string and for resolving URI references.


==Working with daeURI==
==Working with URIs==
The COLLADA DOM uses normalized absolute URIs only. The daeURI class contains code that converts relative URIs into absolute URIs.


The base URI syntax is
Internally, the <code>daeURI</code> class resolves all relative URI references into full URIs before they're used by the COLLADA DOM for any operation, such as <code>load</code> or <code>resolveElement</code>.
scheme://authority/filepath?query#fragment


An absolute URI contains a scheme and an authority. If the authority is left empty than <code>localhost</code> is used, i.e.
Relative references require a base URI for resolution. The COLLADA DOM provides a base URI as follows:
file:///c:/path/document.dae#Geo_01
* If the URI is found within a COLLADA document, then:
is a URI that references a file named document.dae on the localhost found in c:/path.
** If the ''xml:base'' attribute is specified on the root <COLLADA> element, that value is used as the base URI.
** If no ''xml:base'' is specified, the document's URI is used as the base URI.
* If the URI is not part of a document then the current working directory is the base URI.


The fragment portion is used to identify elements by using their "id" attribute. The previous example references an element with an id "Geo_01".
''[[URI|Read main discussion on COLLADA URIs and relative reference resolution.]]''
 
A relative URI is any URI that does not contain a scheme and authority.
 
A relative URI can be a relative path, an absolute path, or just a fragment.
 
Examples of relative path URIs:
./path/document.dae
../../../path/document.dae#elementID
document.dae#Geo_01
 
An absolute path must be preceded by a forward slash character '/'. An example:
/c:/path/document.dae#Light01
 
A fragment identifier references an element that can be found within the same document as the URI. An example of this:
#redMaterial
 
The COLLADA DOM parses URI strings and normalizes them into absolute URIs before it can use the URI for any operation, i.e. load or resolveElement.
 
A base URI is needed to normalize relative URIs. Absolute URIs do not require a separate base URI. The COLLADA DOM will provide a base URI. If the URI is found within a COLLADA document then the base URI will be the document URI. If the URI is not part of a document then the current working directory is used as the base URI.
 
Assuming a base URI of
file:///c:/A/B/C/D/doc.dae
here are some examples of how the following URIs will be normalized:
./path/document.dae                  =>  file:///c:/A/B/C/D/path/document.dae
../../../path/document.dae#elementID  =>  file:///A/path/document.dae#elementID
/c:/path/document.dae#Light01        =>  file:///c:/path/document.dae#Light01
c:/path/document.dae                  =>  file:///c:/A/B/C/D/c:/path/document.dae
 
Note that '''Windows file paths ARE NOT proper absolute path relative URIs!'''
Note also that only the '/' character is used as a path delimeter. Windows uses the '\' character to delimit path segments. Using '\' character can result in incorrect URI processing! "A\B\C" is considered one path segment. If using "file:///A\B\C" as a base URI and trying to resolve "../doc.dae" the result will be "file:///doc.dae" and NOT "file:///A\B\doc.dae" as one might have expected.


===Accessing URI Data===
===Accessing URI Data===
The daeURI class provides accessors to all of the parts of a parsed URI. Please note that the COLLADA DOM refers to the "scheme" as "protocol" and the fragment as "id".
The <code>daeURI</code> class provides accessors to all parts of a parsed URI. Note that the COLLADA DOM refers to the ''scheme'' as ''protocol'' and the ''fragment'' as ''id''. Useful methods include:


Calling daeURI::getURI will return the full URI string. This may be the non-normalized URI string if getURI is called before the URI is normalized. URIs are normalized when they are needed for an operation, i.e. resolveElement or loading a document.
* <code>daeURI::getURI</code>, which returns the full URI string. This may be an unresolved relative reference if <code>getURI</code> is called before the relative reference is resolved. Relative references are resolved when they are needed for an operation, for example, in <code>resolveElement</code> or when loading a document.


Calling daeURI::getOriginalURI will return the original URI string either read from the document or supplied by the user before the URI was normalized.
* <code>daeURI::getOriginalURI</code>, which returns the original URI string either read from the document or supplied by the user before the URI reference was resolved.


daeURI::getContainer will return a reference to the element that contains this URI data. This is helpful if you are given a daeURI object and need to find it's context or check which document it belongs to.
* <code>daeURI::getContainer</code>, which returns a reference to the element that contains this URI data. This is helpful if you are given a <code>daeURI</code> object and need to find its context or check which document it belongs to.


===Resolving URIs===
===Resolving URIs===
As part of the document loading process, the COLLADA DOM will attempt to resolve all of the URIs that are loaded.
To ''resolve'' a URI means to obtain a representation of the resource that the URI identifies. This should not be confused with resolving a relative URI reference, which means to convert a relative reference into a full URI. A lot of the URI literature uses the phrase ''resolve'' to refer to both processes, but the processes shouldn't be confused. Resolving relative URI references has already been discussed, and now we'll talk about resolving URIs.


The element that a URI resolves to, if successful, can be retrieved by calling daeURI::getElement.
In COLLADA, some URIs represent COLLADA elements, such as the ''url'' attribute on <instance_geometry> elements. The ''url'' is a URI that references a COLLADA <geometry> element. Some URIs represent resources that aren't COLLADA elements, such as the <image>/<init_from> element, which refers to an image file. As part of the document loading process, the COLLADA DOM attempts to resolve all URIs that represent COLLADA elements. The other URIs must be resolved manually by the client application.


If daeURI::getElement returns NULL then there could have been an error attempting to resolve the URI or there hasn't been an attempt at all. Calling daeURI::getState will tell you the status of the URI. If getState returns a value of uri_failed_* then there was an error resolving the URI. If getState returns uri_pending then there hasn't been an attempt to resolve the URI.
Useful methods related to resolving URIs include the following:
* <code>daeURI::getElement</code>, if successful, returns the element that a URI resolves to. If this returns NULL then there could have been an error attempting to resolve the URI or the URI doesn't refer to a COLLADA element.
* <code>daeURI::getState</code>  provides the status of the URI. Returned values include:
**  <code>uri_failed_*</code>: There was an error resolving the URI.  
**  <code>uri_pending</code>: There hasn't been an attempt to resolve the URI.


To resolve a URI call daeURI::resolveElement.  
* <code>daeURI::resolveElement</code> resolves a URI.


All URIs that are found in a document upon load will attempt to resolve, but if an application creates elements programattically you may encounter URIs that are in the uri_pending unresolved state. To be safe, you should always check daeURI::getElement for NULL and if NULL, check the state and if needed attempt to resolve the URI manually by calling daeURI::resolveElement.
The DOM automatically attempts to resolve all COLLADA element URIs that are found when loading a document, but if an application creates elements programmatically, you may encounter URIs that are in the <code>uri_pending</code> unresolved state. To be safe, always check <code>daeURI::getElement</code> for NULL. If NULL and <code>daeURI::getState</code> returns <code>uri_pending</code>, resolve the URI by calling <code>daeURI::resolveElement</code>.


If there have been many elements that have been created calling daeElement::resolveAll will resolve all URIs that are present in those newly created elements. An application that creates new elements and intends to pass COLLADA DOM data between different systems, like a conditioner in the [[COLLADA Refinery]], would benefit from calling daeElement::resolveAll before finishing. This could avoid common errors in which applications assume all URIs have attempted to be resolved.
Calling <code>daeElement::resolveAll</code> resolves all URIs in the COLLADA DOM that haven't been resolved yet. An application that creates new elements and intends to pass COLLADA DOM data between different systems, like a conditioner in the [[COLLADA Refinery]], would benefit from calling <code>daeElement::resolveAll</code> before finishing. This could avoid common errors in which applications assume that all URIs have attempted to be resolved.


===Creating URI Strings===
===Creating URI Strings===
The COLLADA DOM provides two ways to create URI strings; by setting the string directly with daeURI::setURI or by using the daeURI::resolveURI method.
The COLLADA DOM provides two ways to create URI strings; by setting the string directly with <code>daeURI::setURI</code> or by using the <code>daeURI::resolveURI</code> method.


Calling daeURI::setURI allows you to pass in a new URI string to be used for the daeURI. The daeURI class will parse this string right away but will not normalize the new URI until it is needed. You may set the URI to any valid URI string, absolute or relative. Most commonly URIs are set to reference other COLLADA elements.  
Calling <code>daeURI::setURI</code> allows you to pass in a new URI string to be used for the <code>daeURI</code>. You may set the URI to any valid URI reference, including absolute URIs and relative references. Relative URI references aren't resolved until necessary. Most commonly, this method is used to set URIs to reference other COLLADA elements. For example:
*Passing in a string "#''elementID''" will create a URI that references the ''elementID'' element from within the same document.
*Passing in a string <code>"#myGeometry"</code>  creates a URI that references the element  whose ''id'' is  <code>myGeometry</code> from within the same document.
*Passing in a string "''rel-path''/''document''#''elementID''" will create a URI that references an element in an external document.
*Passing in a string "<code>../subfolder/car.dae#wheel</code>" creates a URI that references the element whose ''id'' is  <code>wheel</code> in the external document <code>car.dae</code>.
Note. It is the clients responsibility to ensure that strings passed into daeURI::setURI are valid URI strings.
'''''Note:''' It is the client's responsibility to ensure that strings passed to <code>daeURI::setURI</code> are valid URI strings.''


Calling daeURI::resolveURI will create a URI string based on the element set with daeURI::setElement. The COLLADA DOM will create the URI based on the element's documentURI and the element's ID. This method of setting URI strings is very helpful if you have a reference to the element you wish to make the URI reference. Doing so will prevent the need of custom URI string generation. Here is an example of how this works:
Calling <code>daeURI::resolveURI</code> creates a URI string based on the element that was set using <code>daeURI::setElement</code>. The COLLADA DOM creates the URI based on the element's ''documentURI'' and the element's ''ID''. This method of setting URI strings is helpful if you have a reference to the element that you wish to make the URI reference. Doing so makes custom URI string generation unnecessary. Here is an example of how this works:
  //inst_geom is a pointer to an existing domInstance_geometry element
  //inst_geom is a pointer to an existing domInstance_geometry element
  //geom is a pointer to an existing domGeometry element.
  //geom is a pointer to an existing domGeometry element.
Line 80: Line 54:


==External URI References==
==External URI References==
By default, the COLLADA DOM will load additional COLLADA documents to resolve external URI references. I will be refering to these COLLADA documents as "external documents". Client applications may want or need finer control over which documents are loaded and when.
By default, the COLLADA DOM loads additional COLLADA documents to resolve external URI references. These COLLADA documents are referred to as ''external documents''. Client applications may want or need finer control over which documents are loaded and when.


The COLLADA DOM provides this functionality with daeURIResolver::setAutoLoadExternalDocuments and various methods of daeDocument class. To disable the DOM from implicitely loading documents when resolving URIs you must call
The COLLADA DOM provides this functionality with <code>daeURIResolver::setAutoLoadExternalDocuments</code> and various methods of the <code>daeDocument</code> class. To disable the DOM from implicitly loading documents when resolving URIs, you must call
  daeURIResolver::setAutoLoadExternalDocuments( false );
  daeURIResolver::setAutoLoadExternalDocuments( false );
sometime before you attempt to load a document.
sometime before you attempt to load a document. Then the DOM won't resolve any URIs that reference elements in external documents. Calling <code>daeURI::getState</code> to query the status of the URI returns the value <code>uri_failed_external_document</code>.


All URIs that reference elements in external documents will not be resolved. You will be returned the value uri_failed_external_document when querying the status of the URI by calling daeURI::getState.
To retrieve a list of all documents to which the current document has external URI references, use <code>daeDocument::getReferencedDocuments</code>.


Use daeDocument::getReferencedDocuments to retrieve a list of all documents that the current document has external URI references to.
To retrieve a list of pointers to the <code>daeURI</code> objects that reference a specific document, use <code>daeDocument::getExternalURIs</code>.


Use daeDocument::getExternalURIs to retrieve a list of pointers to the daeURI objects that reference a specific document.
When a new document is loaded into the COLLADA DOM using <code>DAE::load</code>, the COLLADA DOM checks whether any currently loaded documents contain any external references to the newly loaded document. If a document does contain an external reference to the newly loaded document, the reference is resolved.


When a new document is loaded into the COLLADA DOM, via DAE::load, the COLLADA DOM checks if any currently loaded documents contain any external references to the newly loaded document. If a document does contain an external reference to the newly loaded document the reference is resolved.
{{DOM navigation}}


[[Category:DOM project|Resolving URIs]]
[[Category:COLLADA DOM|Resolving URIs]]

Latest revision as of 23:46, 6 February 2008

The daeURI class represents URI data types in the COLLADA DOM. This class provides an interface for accessing and manipulating the URI string and for resolving URI references.

Working with URIs

Internally, the daeURI class resolves all relative URI references into full URIs before they're used by the COLLADA DOM for any operation, such as load or resolveElement.

Relative references require a base URI for resolution. The COLLADA DOM provides a base URI as follows:

  • If the URI is found within a COLLADA document, then:
    • If the xml:base attribute is specified on the root <COLLADA> element, that value is used as the base URI.
    • If no xml:base is specified, the document's URI is used as the base URI.
  • If the URI is not part of a document then the current working directory is the base URI.

Read main discussion on COLLADA URIs and relative reference resolution.

Accessing URI Data

The daeURI class provides accessors to all parts of a parsed URI. Note that the COLLADA DOM refers to the scheme as protocol and the fragment as id. Useful methods include:

  • daeURI::getURI, which returns the full URI string. This may be an unresolved relative reference if getURI is called before the relative reference is resolved. Relative references are resolved when they are needed for an operation, for example, in resolveElement or when loading a document.
  • daeURI::getOriginalURI, which returns the original URI string either read from the document or supplied by the user before the URI reference was resolved.
  • daeURI::getContainer, which returns a reference to the element that contains this URI data. This is helpful if you are given a daeURI object and need to find its context or check which document it belongs to.

Resolving URIs

To resolve a URI means to obtain a representation of the resource that the URI identifies. This should not be confused with resolving a relative URI reference, which means to convert a relative reference into a full URI. A lot of the URI literature uses the phrase resolve to refer to both processes, but the processes shouldn't be confused. Resolving relative URI references has already been discussed, and now we'll talk about resolving URIs.

In COLLADA, some URIs represent COLLADA elements, such as the url attribute on <instance_geometry> elements. The url is a URI that references a COLLADA <geometry> element. Some URIs represent resources that aren't COLLADA elements, such as the <image>/<init_from> element, which refers to an image file. As part of the document loading process, the COLLADA DOM attempts to resolve all URIs that represent COLLADA elements. The other URIs must be resolved manually by the client application.

Useful methods related to resolving URIs include the following:

  • daeURI::getElement, if successful, returns the element that a URI resolves to. If this returns NULL then there could have been an error attempting to resolve the URI or the URI doesn't refer to a COLLADA element.
  • daeURI::getState provides the status of the URI. Returned values include:
    • uri_failed_*: There was an error resolving the URI.
    • uri_pending: There hasn't been an attempt to resolve the URI.
  • daeURI::resolveElement resolves a URI.

The DOM automatically attempts to resolve all COLLADA element URIs that are found when loading a document, but if an application creates elements programmatically, you may encounter URIs that are in the uri_pending unresolved state. To be safe, always check daeURI::getElement for NULL. If NULL and daeURI::getState returns uri_pending, resolve the URI by calling daeURI::resolveElement.

Calling daeElement::resolveAll resolves all URIs in the COLLADA DOM that haven't been resolved yet. An application that creates new elements and intends to pass COLLADA DOM data between different systems, like a conditioner in the COLLADA Refinery, would benefit from calling daeElement::resolveAll before finishing. This could avoid common errors in which applications assume that all URIs have attempted to be resolved.

Creating URI Strings

The COLLADA DOM provides two ways to create URI strings; by setting the string directly with daeURI::setURI or by using the daeURI::resolveURI method.

Calling daeURI::setURI allows you to pass in a new URI string to be used for the daeURI. You may set the URI to any valid URI reference, including absolute URIs and relative references. Relative URI references aren't resolved until necessary. Most commonly, this method is used to set URIs to reference other COLLADA elements. For example:

  • Passing in a string "#myGeometry" creates a URI that references the element whose id is myGeometry from within the same document.
  • Passing in a string "../subfolder/car.dae#wheel" creates a URI that references the element whose id is wheel in the external document car.dae.

Note: It is the client's responsibility to ensure that strings passed to daeURI::setURI are valid URI strings.

Calling daeURI::resolveURI creates a URI string based on the element that was set using daeURI::setElement. The COLLADA DOM creates the URI based on the element's documentURI and the element's ID. This method of setting URI strings is helpful if you have a reference to the element that you wish to make the URI reference. Doing so makes custom URI string generation unnecessary. Here is an example of how this works:

//inst_geom is a pointer to an existing domInstance_geometry element
//geom is a pointer to an existing domGeometry element.
inst_geom->getUrl().setElement( geom );
inst_geom->getUrl().resolveURI();

External URI References

By default, the COLLADA DOM loads additional COLLADA documents to resolve external URI references. These COLLADA documents are referred to as external documents. Client applications may want or need finer control over which documents are loaded and when.

The COLLADA DOM provides this functionality with daeURIResolver::setAutoLoadExternalDocuments and various methods of the daeDocument class. To disable the DOM from implicitly loading documents when resolving URIs, you must call

daeURIResolver::setAutoLoadExternalDocuments( false );

sometime before you attempt to load a document. Then the DOM won't resolve any URIs that reference elements in external documents. Calling daeURI::getState to query the status of the URI returns the value uri_failed_external_document.

To retrieve a list of all documents to which the current document has external URI references, use daeDocument::getReferencedDocuments.

To retrieve a list of pointers to the daeURI objects that reference a specific document, use daeDocument::getExternalURIs.

When a new document is loaded into the COLLADA DOM using DAE::load, the COLLADA DOM checks whether any currently loaded documents contain any external references to the newly loaded document. If a document does contain an external reference to the newly loaded document, the reference is resolved.


COLLADA DOM - Version 2.4 Historical Reference
List of main articles under the DOM portal.
User Guide chapters:  • Intro  • Architecture  • Setting up  • Working with documents  • Creating docs  • Importing docs  • Representing elements  • Working with elements  • Resolving URIs  • Resolving SIDs  • Using custom COLLADA data  • Integration templates  • Error handling

Systems:  • URI resolver  • Meta  • Load/save flow  • Runtime database  • Memory • StringRef  • Code generator
Additional information:  • What's new  • Backward compatibility  • Future work
Terminology categories:  • COLLADA  • DOM  • XML