FileDocCategorySizeDatePackage
IdResolver.javaAPI DocJava SE 6 API7070Tue Jun 10 00:23:04 BST 2008com.sun.org.apache.xml.internal.security.utils

IdResolver

public class IdResolver extends Object
Purpose of this class is to enable the XML Parser to keep track of ID attributes. This is done by 'registering' attributes of type ID at the IdResolver. This is necessary if we create a document from scratch and we sign some resources with a URI using a fragent identifier...
The problem is that if you do not validate a document, you cannot use the getElementByID functionality. So this modules uses some implicit knowledge on selected Schemas and DTDs to pick the right Element for a given ID: We know that all @Id attributes in an Element from the XML Signature namespace are of type ID.
author
$Author: raul $
see
"Identity Crisis" on xml.com

Fields Summary
static Logger
log
{@link java.util.logging} logging facility
static WeakHashMap
docMap
static List
names
Constructors Summary
private IdResolver()
Constructor IdResolver

    
         
     

      // we don't allow instantiation
   
Methods Summary
public static org.w3c.dom.ElementgetElementById(org.w3c.dom.Document doc, java.lang.String id)
Method getElementById

param
doc
param
id
return
the element obtained by the Id, or null if it is not found.


      Element result = null;

      result = IdResolver.getElementByIdType(doc, id);

      if (result != null) {
         if (log.isLoggable(java.util.logging.Level.FINE))                                     log.log(java.util.logging.Level.FINE, 
            "I could find an Element using the simple getElementByIdType method: "
            + result.getTagName());

         return result;
      }

       result = IdResolver.getElementByIdUsingDOM(doc, id);

       if (result != null) {
          if (log.isLoggable(java.util.logging.Level.FINE))                                     log.log(java.util.logging.Level.FINE, 
             "I could find an Element using the simple getElementByIdUsingDOM method: "
            + result.getTagName());

         return result;
      }
       // this must be done so that Xalan can catch ALL namespaces
       //XMLUtils.circumventBug2650(doc);
      result = IdResolver.getElementBySearching(doc, id);

      if (result != null) {
		  IdResolver.registerElementById(result, id);

         return result;
      }

      return null;
   
private static org.w3c.dom.ElementgetElementByIdType(org.w3c.dom.Document doc, java.lang.String id)
Method getElementByIdType

param
doc
param
id
return
the element obtained by the Id, or null if it is not found.

   	  if (true)
   	  	if (log.isLoggable(java.util.logging.Level.FINE))                                     log.log(java.util.logging.Level.FINE, "getElementByIdType() Search for ID " + id);
       WeakHashMap elementMap = (WeakHashMap) docMap.get(doc);
       if (elementMap != null) {
           WeakReference weakReference = (WeakReference) elementMap.get(id);
           if (weakReference != null)
           {
                return (Element) weakReference.get();   
           }
       }
       return null;
   
private static org.w3c.dom.ElementgetElementByIdUsingDOM(org.w3c.dom.Document doc, java.lang.String id)
Method getElementByIdUsingDOM

param
doc
param
id
return
the element obtained by the Id, or null if it is not found.

        if (true)
        	if (log.isLoggable(java.util.logging.Level.FINE))                                     log.log(java.util.logging.Level.FINE, "getElementByIdUsingDOM() Search for ID " + id);
        return doc.getElementById(id);
    
private static org.w3c.dom.ElementgetElementBySearching(org.w3c.dom.Node root, java.lang.String id)

	   String namespaces[]={ Constants.SignatureSpecNS,
			   EncryptionConstants.EncryptionSpecNS,
			   "http://schemas.xmlsoap.org/soap/security/2000-12",
			   "http://www.w3.org/2002/03/xkms#"	   	   
		   };
	   names=Arrays.asList(namespaces);
   
	   Element []els=new Element[5];
	   getElementBySearching(root,id,els);
	   for (int i=0;i<els.length;i++) {
		   if (els[i]!=null) {
			   return els[i];
		   }
	   }
	   return null;
	   
   
private static intgetElementBySearching(org.w3c.dom.Node root, java.lang.String id, org.w3c.dom.Element[] els)

	   switch (root.getNodeType()) {
	   case Node.ELEMENT_NODE:
		   Element el=(Element)root;
		   if (el.hasAttributes()) {			  
			   int index=names.indexOf(el.getNamespaceURI());
			   if (index<0) {
				   index=4;
			   }		   
			   if (el.getAttribute("Id").equals(id)) {				   
				   els[index]=el;
				   if (index==0) {
					   return 1;
				   }
			   } else if ( el.getAttribute("id").equals(id) ) {
				   if (index!=2) {
					   index=4;
				   }			    				   
				   els[index]=el;
			   } else if ( el.getAttribute("ID").equals(id) ) {
				   if (index!=3) {
					   index=4;
				   }
				   els[index]=el;				   
			   } else if ((index==3)&&(
				   el.getAttribute("OriginalRequestID").equals(id) ||
				   el.getAttribute("RequestID").equals(id) ||
				   el.getAttribute("ResponseID" ).equals(id))) {
				   els[3]=el;				   
			   }
		   }
	   	case Node.DOCUMENT_NODE:
			Node sibling=root.getFirstChild();
			while (sibling!=null) {
				if (getElementBySearching(sibling,id,els)==1)
					return 1;
				sibling=sibling.getNextSibling();
			}
	   }
	   return 0;
   
public static voidregisterElementById(org.w3c.dom.Element element, java.lang.String idValue)
Method registerElementById

param
element
param
idValue

      Document doc = element.getOwnerDocument();
      WeakHashMap elementMap = (WeakHashMap) docMap.get(doc);
      if(elementMap == null) {
          elementMap = new WeakHashMap();
          docMap.put(doc, elementMap);
      }
      elementMap.put(idValue, new WeakReference(element));
   
public static voidregisterElementById(org.w3c.dom.Element element, org.w3c.dom.Attr id)
Method registerElementById

param
element
param
id

      IdResolver.registerElementById(element, id.getNodeValue());