XML API standardization
Big Picture
For JRE 1.5, Sun has included with the JRE new, standardized versions of the XML APIs supporting DOM Level 3 and JAXP 1.3. These APIs are available for JRE 1.4 via jars that can be downloaded and installed into JRE 1.4.
uPortal 2.5 will standardize upon and use the APIs.
What specific APIs are we talking about?
They are the APIs and implementation .jars included in JRE 1.5 (J2SE 5) and distributed at Java.net for use in JRE 1.3 and JRE 1.4. uPortal 2.5 requires JRE 1.4 or later and so we aren't particularly concerned with how to make these APIs available in JRE 1.3.
The JAXP 1.3 standalone release includes:
dom.jar
jaxp-api.jar
sax.jar
xalan.jar
xercesImpl.jar
What exactly do I have to do to make uPortal 2.5 work?
What about our legacy APIs?
IPortalDocument, PortalDcoumentImpl, and the uPortal DocumentFactory API become formally deprecated by this change. Instead, code using XML functionality in uPortal 2.5 is encouraged to move to use the new standard XML APIs.
Specific code examples
Getting DOM 3 support
Previously the core org.w3c.dom.Document implementation in uPortal was a DOM level 2 Document. DOM 3 support was added by means of an IPortalDocument interface and PortalDocumentImpl implementation.
IPortalDocument
package org.jasig.portal.utils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* An interface that allows a Document to cache elements by known keys.
* This is used to locally store and manager the ID element mappings
* regardless of the actual DOM implementation.
*
* @author Nick Bolton
* @version $Revision: 1.3 $
*/
public interface IPortalDocument extends Document {
/**
* Registers an identifier name with a specified element node.
*
* @param idName a key used to store an <code>Element</code> object.
* @param element an <code>Element</code> object to map.
* document.
*/
public void putIdentifier(String idName, Element element);
/**
* Copies the element cache from the source document. This will
* provide equivalent mappings from IDs to elements in this
* document provided the elements exist in the source document.
*
* @param sourceDoc The source doc to copy from.
*/
public void copyCache(IPortalDocument sourceDoc);
}
Now, the core org.w3c.dom.Document implementation in uPortal is a DOM level 3 Document natively supporting the methods that were added by IPortalDocument. It is therefore no longer necessary for any code to expect IPortalDocument instances – instead W3C DOM 3 Documents can be consumed directly.
The uPortal 2.5 IPortalDocument is therefore formally deprecated and adds no methods beyond what is available in a baseline org.w3c.dom.Document (DOM Level 3):
IPortalDocument in uPortal 2.5
/**
* IPortalDocument used to provide DOM 3 support on top of a DOM 2
* org.w3c.dom.Document implementation. Since uPortal 2.5, our Documents
* have been DOM 3 themselves and as such IPortalDocument is no longer needed.
* This interface is formally deprecated and will be removed in a future release.
* @deprecated use Document directly instead
public interface IPortalDocument extends Document {
}
Getting a new, empty Document
Pre-uPortal-2.5, deprecated approach
import org.jasig.portal.utils.DocumentFactory;
import org.w3c.dom.Document;
...
Document doc = DocumentFactory.getNewDocument();
uPortal 2.5 approach
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBulder;
import org.w3c.dom.Document;
...
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
While the 2.4 uPortal DocumentFactory implementation used PropertiesManager to determine the name of the class that it should Class.forName().instance() to get an instance of IPortalDocument to return, the uPortal 2.5 DocumentFactory implementation will simply return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(). For most existing clients of DocumentFactory, this will be sufficient since they were using only the DOM Level 2 Document API, of which DOM Level 3 is a superset. For those clients that were recasting the return value from Document to IPortalDocument, this will no longer be possible and they will need to change to recognize that the return value is no longer an IPortalDocument and is instead a Document which directly provides the methods desired.
Why Deprecate DocumentFactory?
Why deprecate DocumentFactory and ask clients to use the javax.xml DocumentBuilderFactory API directly? After all,
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
is longer than
Document doc = DocumentFactory.getNewDocument();
The reason to deprecate DocumentFactory is to encourage direct use of the javax.xml API and thereby reduce dependency within uPortal code upon other uPortal code. Code that does not depend upon uPortal DocumentFactory will be more reusable outside of uPortal. DocumentFactory in uPortal 2.5 no longer has a unique role to play – the work it was doing has been assumed by the core Java XML API in its provision of a DocumentBuilderFactory.
While
DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
is long, it becomes idiom – the way one gets a fresh Document instance in Java, not just in uPortal.
The long version
If you're thinking "Wait, wait! You've been too concise – I really want to read a longer account of what's going on here." – here it is. This is a re-presentation of content @Howard Gilbert presented to the Shibboleth community.