KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > security > utils > IdResolver


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package com.sun.org.apache.xml.internal.security.utils;
18
19
20
21
22 import org.w3c.dom.Attr JavaDoc;
23 import org.w3c.dom.Document JavaDoc;
24 import org.w3c.dom.Element JavaDoc;
25 import org.w3c.dom.Node JavaDoc;
26
27 import java.util.Arrays JavaDoc;
28 import java.util.WeakHashMap JavaDoc;
29 import java.lang.ref.WeakReference JavaDoc;
30
31
32 /**
33  * Purpose of this class is to enable the XML Parser to keep track of ID
34  * attributes. This is done by 'registering' attributes of type ID at the
35  * IdResolver. This is necessary if we create a document from scratch and we
36  * sign some resources with a URI using a fragent identifier...
37  * <BR />
38  * The problem is that if you do not validate a document, you cannot use the
39  * <CODE>getElementByID</CODE> functionality. So this modules uses some implicit
40  * knowledge on selected Schemas and DTDs to pick the right Element for a given
41  * ID: We know that all <CODE>@Id</CODE> attributes in an Element from the XML
42  * Signature namespace are of type <CODE>ID</CODE>.
43  *
44  * @author $Author: raul $
45  * @see <A HREF="http://www.xml.com/lpt/a/2001/11/07/id.html">"Identity Crisis" on xml.com</A>
46  */

47 public class IdResolver {
48
49    /** {@link java.util.logging} logging facility */
50     static java.util.logging.Logger JavaDoc log =
51         java.util.logging.Logger.getLogger(IdResolver.class.getName());
52
53    static WeakHashMap JavaDoc docMap = new WeakHashMap JavaDoc();
54     
55    /**
56     * Constructor IdResolver
57     *
58     */

59    private IdResolver() {
60
61       // we don't allow instantiation
62
}
63
64    /**
65     * Method registerElementById
66     *
67     * @param element
68     * @param idValue
69     */

70    public static void registerElementById(Element JavaDoc element, String JavaDoc idValue) {
71       Document JavaDoc doc = element.getOwnerDocument();
72       WeakHashMap JavaDoc elementMap = (WeakHashMap JavaDoc) docMap.get(doc);
73       if(elementMap == null) {
74           elementMap = new WeakHashMap JavaDoc();
75           docMap.put(doc, elementMap);
76       }
77       elementMap.put(idValue, new WeakReference JavaDoc(element));
78    }
79
80    /**
81     * Method registerElementById
82     *
83     * @param element
84     * @param id
85     */

86    public static void registerElementById(Element JavaDoc element, Attr JavaDoc id) {
87       IdResolver.registerElementById(element, id.getNodeValue());
88    }
89
90    /**
91     * Method getElementById
92     *
93     * @param doc
94     * @param id
95     * @return the element obtained by the Id, or null if it is not found.
96     */

97    public static Element JavaDoc getElementById(Document JavaDoc doc, String JavaDoc id) {
98
99       Element JavaDoc result = null;
100
101       result = IdResolver.getElementByIdType(doc, id);
102
103       if (result != null) {
104          if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE,
105             "I could find an Element using the simple getElementByIdType method: "
106             + result.getTagName());
107
108          return result;
109       }
110
111        result = IdResolver.getElementByIdUsingDOM(doc, id);
112
113        if (result != null) {
114           if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE,
115              "I could find an Element using the simple getElementByIdUsingDOM method: "
116             + result.getTagName());
117
118          return result;
119       }
120        // this must be done so that Xalan can catch ALL namespaces
121
//XMLUtils.circumventBug2650(doc);
122
result = IdResolver.getElementBySearching(doc, id);
123
124       if (result != null) {
125           IdResolver.registerElementById(result, id);
126
127          return result;
128       }
129
130       return null;
131    }
132    
133
134     /**
135      * Method getElementByIdUsingDOM
136      *
137      * @param doc
138      * @param id
139      * @return the element obtained by the Id, or null if it is not found.
140      */

141     private static Element JavaDoc getElementByIdUsingDOM(Document JavaDoc doc, String JavaDoc id) {
142         if (true)
143             if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "getElementByIdUsingDOM() Search for ID " + id);
144         return doc.getElementById(id);
145     }
146
147    /**
148     * Method getElementByIdType
149     *
150     * @param doc
151     * @param id
152     * @return the element obtained by the Id, or null if it is not found.
153     */

154    private static Element JavaDoc getElementByIdType(Document JavaDoc doc, String JavaDoc id) {
155       if (true)
156         if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "getElementByIdType() Search for ID " + id);
157        WeakHashMap JavaDoc elementMap = (WeakHashMap JavaDoc) docMap.get(doc);
158        if (elementMap != null) {
159            WeakReference JavaDoc weakReference = (WeakReference JavaDoc) elementMap.get(id);
160            if (weakReference != null)
161            {
162                 return (Element JavaDoc) weakReference.get();
163            }
164        }
165        return null;
166    }
167
168    
169    static java.util.List JavaDoc names;
170    static {
171        String JavaDoc namespaces[]={ Constants.SignatureSpecNS,
172                EncryptionConstants.EncryptionSpecNS,
173                "http://schemas.xmlsoap.org/soap/security/2000-12",
174                "http://www.w3.org/2002/03/xkms#"
175            };
176        names=Arrays.asList(namespaces);
177    }
178    
179
180    private static Element JavaDoc getElementBySearching(Node JavaDoc root,String JavaDoc id) {
181        Element JavaDoc []els=new Element JavaDoc[5];
182        getElementBySearching(root,id,els);
183        for (int i=0;i<els.length;i++) {
184            if (els[i]!=null) {
185                return els[i];
186            }
187        }
188        return null;
189        
190    }
191    private static int getElementBySearching(Node JavaDoc root,String JavaDoc id,Element JavaDoc []els) {
192        switch (root.getNodeType()) {
193        case Node.ELEMENT_NODE:
194            Element JavaDoc el=(Element JavaDoc)root;
195            if (el.hasAttributes()) {
196                int index=names.indexOf(el.getNamespaceURI());
197                if (index<0) {
198                    index=4;
199                }
200                if (el.getAttribute("Id").equals(id)) {
201                    els[index]=el;
202                    if (index==0) {
203                        return 1;
204                    }
205                } else if ( el.getAttribute("id").equals(id) ) {
206                    if (index!=2) {
207                        index=4;
208                    }
209                    els[index]=el;
210                } else if ( el.getAttribute("ID").equals(id) ) {
211                    if (index!=3) {
212                        index=4;
213                    }
214                    els[index]=el;
215                } else if ((index==3)&&(
216                    el.getAttribute("OriginalRequestID").equals(id) ||
217                    el.getAttribute("RequestID").equals(id) ||
218                    el.getAttribute("ResponseID" ).equals(id))) {
219                    els[3]=el;
220                }
221            }
222         case Node.DOCUMENT_NODE:
223             Node JavaDoc sibling=root.getFirstChild();
224             while (sibling!=null) {
225                 if (getElementBySearching(sibling,id,els)==1)
226                     return 1;
227                 sibling=sibling.getNextSibling();
228             }
229        }
230        return 0;
231    }
232
233 }
234
Popular Tags