public class HdxFactory extends Object
To create a new HdxContainer
from a URI, use the
following paradigm:
URI myData = new URI("..."); HdxFactory factory = HdxFactory.getInstance(); HdxContainer myHdx = factory.newHdxContainer(myData); // process myHdx...If you already have a DOM obtained from an XML file, then you can extract the HdxContainer from it using the
newHdxContainer(Element)
method.
This class, or rather the group of newHdxContainer
methods, is also the gatekeeper for the Hdx system, in the sense
that it is this class which ensures that the
HdxContainer
which it produces is in a normalised
form, and is valid. The Hdx validation is that defined by the
static method HdxResourceType.isValidHdx(Document)
and the
validators for the individual types, HdxResourceType.isValid(Element)
.
Instances of this class also provide the facilities to resolve
URIs into URLs, supplying whatever context is required in the form
of base URIs. They do this using the fullyResolveURI(java.net.URI, org.w3c.dom.Node)
method. Since the context required will typically depend on the
DOM context, you should find an appropriate factory using findFactory(org.w3c.dom.Node)
.
To add an extension class, which handles a new file type, you must do two things:
HdxDocumentFactory
, and
which registers itself as such a factory, through a call to registerHdxDocumentFactory(uk.ac.starlink.hdx.HdxDocumentFactory)
, in a static initialiser.
my.new.type
, and if
there is an `Hdx property'
HdxDocumentFactory.load.my.new.type
with the value
true
(or anything which the Boolean
class
evaluates to true), then the specified class is loaded during
initialization of this HdxFactory
class. This is an
`Hdx property', which means that it may be specified as either a
System property, or in an Hdx property file as described in HdxProperties
.
Modifier and Type | Method and Description |
---|---|
static HdxFactory |
findFactory(Node el)
Obtains the factory instance which should handle a particular
element.
|
URL |
fullyResolveURI(String uri,
Node context)
Completely resolves a URI, expressed as a string, into a URL.
|
URL |
fullyResolveURI(URI uri,
Node context)
Completely resolves a URI into a URL.
|
static HdxFactory |
getInstance()
Obtains an instance of the
HdxFactory . |
Object |
getObject(Element el)
Recovers the Java object which corresponds to the given
element.
|
HdxContainer |
newHdxContainer(Element el)
Constructs a new
HdxContainer from the supplied DOM. |
HdxContainer |
newHdxContainer(Element el,
URI systemId)
Constructs a new
HdxContainer from the supplied DOM. |
HdxContainer |
newHdxContainer(HdxFacade facade)
Constructs a new
HdxContainer which wraps an
HdxFacade . |
HdxContainer |
newHdxContainer(URI uri)
Constructs a new
HdxContainer from the supplied URI. |
HdxContainer |
newHdxContainer(URL url)
Constructs a new
HdxContainer from the supplied URL. |
static void |
registerHdxDocumentFactory(HdxDocumentFactory factory)
Adds a
HdxDocumentFactory to the list of factories
tried by newHdxContainer(java.net.URI) . |
public static HdxFactory getInstance()
HdxFactory
.public static HdxFactory findFactory(Node el)
el
- indicates the DOM context which the returned factory
is to servicepublic static void registerHdxDocumentFactory(HdxDocumentFactory factory)
HdxDocumentFactory
to the list of factories
tried by newHdxContainer(java.net.URI)
. The factory is
added at the beginning of the list of factories tried.factory
- an object implementing the HdxDocumentFactory
interface.public HdxContainer newHdxContainer(URI uri) throws HdxException
HdxContainer
from the supplied URI.
The resulting HdxContainer
is normalised as
described in newHdxContainer(Element,URI)
.uri
- a URI
pointing to the resourceHdxContainer
, or null if there
is no handler available to parse the given URIHdxException
- if there is an unexpected problem creating
the HdxContainer
(that is, if we
ought to be able to handle this URI, but fail
for some reason)public HdxContainer newHdxContainer(URL url) throws HdxException
HdxContainer
from the supplied URL.
The resulting HdxContainer
is normalised as
described in newHdxContainer(Element,URI)
.url
- a URL
pointing to the resourceHdxContainer
, or null if there
is no handler available to parse the given URIHdxException
- if there is an unexpected problem creating
the HdxContainer
(that is, if we
ought to be able to handle this URL, but fail
for some reason)public HdxContainer newHdxContainer(Element el) throws HdxException
HdxContainer
from the supplied DOM.
Equivalent to newHdxContainer(el, null)
el
- an element in or beneath which there is the XML which
represents a single HDX objectHdxContainer
, or null if there is not exactly one
HDX element in the DOMHdxException
newHdxContainer(Element,URI)
public HdxContainer newHdxContainer(Element el, URI systemId) throws HdxException
HdxContainer
from the supplied DOM.
Searches through the tree beneath the given element to find an
element which is in the HDX namespace (for permissible syntax,
see HdxResourceType
). This method expects to find only
a single HDX element in the DOM tree it receives: if there is
more than one, it returns null.
The DOM which this builds is normalised, in the sense that:
The new DOM is backed by the old one, so that changes in the new one also appear in the old one.
The Element argument should contain one or more HDX objects
(that is, elements representing an <hdx>
element in the HDX namespace). However, as a special case, if
it contains only elements which are the content of HDX
objects, then they are put inside a new HDX object if that can
be done unambiguously. This is a heuristic fix, and its
behaviour may change in future.
If the element argument is both an HDX-type element (that
is, <hdx>
or <ndx>
or the
like) and is in no namespace, then this method will not look
for the HDX namespace in the elements below, and indeed will
ignore elements in the HDX namespace. Otherwise, the method
will examine only elements and attributes in the HDX
namespace. As a special case, if the element is in the HDX namespace,
then any unprefixed attributes on the element are taken to be
in that namespace also. This is a contradiction to the XML
standard, which states that unprefixed attributes are in
no namespace, not even the default one. However,
there are no reasonable cases where this behaviour is useful,
and it is massively confusing, so this constitutes best
practice.
el
- an element in or beneath which there is the XML which
represents a single HDX objectsystemId
- the system identifier for this element, or null
if none is definedHdxContainer
, or null if there is not exactly one
HDX element in the DOMHdxException
- if there is an unexpected problem
normalizing the DOMpublic HdxContainer newHdxContainer(HdxFacade facade) throws HdxException
HdxContainer
which wraps an
HdxFacade
.
Unlike the other newHdxContainer
methods, this
does not guarantee to normalise the (implied) input DOM
immediately, and this may be postponed until the (implied)
resulting Hdx DOM is produced at a later stage. It is only
whenever this normalisation is finally done that any errors in
the input DOM will materialise. However, since the
HdxFacade
is a synthetic view of an underlying
structure, under control of the same code which is ultimately
responsible for validating the input DOM, one can presume that
any normalisation errors are bugs in that code. Thus this
method either succeeds or thows an exception, and does not
return null on any error.
This method is part of the preferred route for generating
XML from a Java object which is part of the HDX world. Given
that the object, obj
has a
getHdxFacade
method, or equivalent, the route is:
Element el = HdxFactory .getInstance() // or some suitable .findFactory(...) .newHdxContainer(obj.getHdxFacade()) .getDOM(null) ; // or a suitable base URIAlthough this seems roundabout, (a) this method is written to be efficient with this route in mind, and (b) this ensures that the DOM or Source produced by the
HdxFacade
is
processed for output in a way consistent with other XML
generated by this package.facade
- an HdxFacade
which represents an
underlying objectHdxContainer
HdxException
- if there is some problem constructing the DOMpublic Object getObject(Element el) throws HdxException
The DOM element should be regarded as the master
representation of the data object, thus it is the Element which
client code should generally hold on to, rather than the Java object,
which can be extracted from the element using this method at
any time. That is why this is a get...
method
rather than being referred to as a constructor.
The returned object is checked to correspond to the type registered
using HdxResourceType.setConstructedClass(java.lang.Class)
.
el
- an element in the Hdx DOMHdxException
- if the given element is somehow inconsistentPluginException
- (unchecked exception) if the
underlying code returned an object which did not match the
registered target class obtained from HdxResourceType.getConstructedClass()
, if that is non-nullpublic URL fullyResolveURI(URI uri, Node context) throws HdxException
The relative-to-absolute resolution is performed using the base URI corresponding to the given context node, as specified by XML Base Recommendation, section 4.
If no base URI can be determined, then the method uses a
last-ditch base URI consisting of the file:
URI
corresponding to the current directory (as obtained from the
System property user.dir
).
Note that the natural-looking URI
file:filename.xml
is an absolute URI,
according to RFC
2396, Uniform Resource Identifiers (URI): Generic
Syntax (since it has a non-null scheme
part).
Such URIs should be avoided, but since they are common, and
intended to be relative URIs, we special-case this, in a
deviation from RFC 2396 by removing the
scheme
part (this conforms with the remarks on
backward compatibility in RFC 2396, section 5.2, step 3,
although, as blessed in that section) we do not extend this
latitude to other schemes). We allow the file
scheme-specifier to be mixed-case.
uri
- the URI which is to be resolved. If this is
absolute already, it is merely converted to a URL.context
- a DOM Node providing the context for any
resolution required; this may be nullHdxException
- if any of the URI or URL exceptions are
thrown, which should happen only if there is some syntactic
problem with the input URI. Also thrown if the input URI was
relative, and it is impossible to determine a base URI to
resolve it against.public URL fullyResolveURI(String uri, Node context) throws HdxException
uri
- a String holding the URIcontext
- a DOM Node providing the context for any
resolution required; this may be nullHdxException
- if any of the URI or URL exceptions are
thrown, which should happen only if there is some syntactic
problem with the input URI.fullyResolveURI(URI,Node)
Copyright © 2025 Central Laboratory of the Research Councils. All Rights Reserved.