KickJava   Java API By Example, From Geeks To Geeks.

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


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 import java.math.BigInteger JavaDoc;
22 import java.util.HashMap JavaDoc;
23
24 import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
25 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
26 import org.w3c.dom.Attr JavaDoc;
27 import org.w3c.dom.Document JavaDoc;
28 import org.w3c.dom.Element JavaDoc;
29 import org.w3c.dom.Node JavaDoc;
30 import org.w3c.dom.NodeList JavaDoc;
31 import org.w3c.dom.Text JavaDoc;
32
33
34 /**
35  * This is the base class to all Objects which have a direct 1:1 mapping to an
36  * Element in a particular namespace.
37  *
38  * @author $Author: mullan $
39  */

40 public abstract class ElementProxy {
41
42    /** {@link java.util.logging} logging facility */
43     static java.util.logging.Logger JavaDoc log =
44         java.util.logging.Logger.getLogger(ElementProxy.class.getName());
45    //J-
46
/** The element has been created by the code **/
47    public static final int MODE_CREATE = 0;
48    /** The element has been readed from a DOM tree by the code **/
49    public static final int MODE_PROCESS = 1;
50    /** The element isn't known if it is readen or created **/
51    public static final int MODE_UNKNOWN = 2;
52
53    /** The element is going to be signed **/
54    public static final int MODE_SIGN = MODE_CREATE;
55    /** The element is going to be verified **/
56    public static final int MODE_VERIFY = MODE_PROCESS;
57
58    /** The element is going to be encrypted **/
59    public static final int MODE_ENCRYPT = MODE_CREATE;
60    /** The element is going to be decrypted **/
61    public static final int MODE_DECRYPT = MODE_PROCESS;
62
63    protected int _state = MODE_UNKNOWN;
64    //J+
65

66    /**
67     * Returns the namespace of the Elements of the sub-class.
68     *
69     * @return the namespace of the Elements of the sub-class.
70     */

71    public abstract String JavaDoc getBaseNamespace();
72
73    /**
74     * Returns the localname of the Elements of the sub-class.
75     *
76     * @return the localname of the Elements of the sub-class.
77     */

78    public abstract String JavaDoc getBaseLocalName();
79
80    /** Field _constructionElement */
81    protected Element JavaDoc _constructionElement = null;
82
83    /** Field _baseURI */
84    protected String JavaDoc _baseURI = null;
85
86    /** Field _doc */
87    protected Document JavaDoc _doc = null;
88
89    /**
90     * Constructor ElementProxy
91     *
92     */

93    public ElementProxy() {
94
95       this._doc = null;
96       this._state = ElementProxy.MODE_UNKNOWN;
97       this._baseURI = null;
98       this._constructionElement = null;
99    }
100
101    /**
102     * Constructor ElementProxy
103     *
104     * @param doc
105     */

106    public ElementProxy(Document JavaDoc doc) {
107
108       this();
109
110       if (doc == null) {
111          throw new RuntimeException JavaDoc("Document is null");
112       }
113
114       this._doc = doc;
115       this._state = ElementProxy.MODE_CREATE;
116       this._constructionElement = ElementProxy.createElementForFamily(this._doc,
117               this.getBaseNamespace(), this.getBaseLocalName());
118    }
119
120    /**
121     * This method creates an Element in a given namespace with a given localname.
122     * It uses the {@link ElementProxy#getDefaultPrefix} method to decide whether
123     * a particular prefix is bound to that namespace.
124     * <BR />
125     * This method was refactored out of the constructor.
126     *
127     * @param doc
128     * @param namespace
129     * @param localName
130     * @return The element created.
131     */

132    public static Element JavaDoc createElementForFamily(Document JavaDoc doc, String JavaDoc namespace,
133            String JavaDoc localName) {
134        //Element nscontext = XMLUtils.createDSctx(doc, "x", namespace);
135
Element JavaDoc result = null;
136       String JavaDoc prefix = ElementProxy.getDefaultPrefix(namespace);
137
138       if (namespace == null) {
139          result = doc.createElementNS(null, localName);
140       } else {
141          if ((prefix == null) || (prefix.length() == 0)) {
142             result = doc.createElementNS(namespace, localName);
143
144             result.setAttributeNS(Constants.NamespaceSpecNS, "xmlns",
145                                   namespace);
146          } else {
147             result = doc.createElementNS(namespace, prefix + ":" + localName);
148
149             result.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:" + prefix,
150                                   namespace);
151          }
152       }
153
154       return result;
155    }
156
157    /**
158     * Method setElement
159     *
160     * @param element
161     * @param BaseURI
162     * @throws XMLSecurityException
163     */

164    public void setElement(Element JavaDoc element, String JavaDoc BaseURI)
165            throws XMLSecurityException {
166
167       if (element == null) {
168          throw new XMLSecurityException("ElementProxy.nullElement");
169       }
170       if (true) {
171       }
172       
173       if (true) {
174         if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "setElement(" + element.getTagName() + ", \"" + BaseURI + "\"");
175       }
176         
177       this._doc = element.getOwnerDocument();
178       this._state = ElementProxy.MODE_PROCESS;
179       this._constructionElement = element;
180       this._baseURI = BaseURI;
181    }
182
183    /**
184     * Constructor ElementProxy
185     *
186     * @param element
187     * @param BaseURI
188     * @throws XMLSecurityException
189     */

190    public ElementProxy(Element JavaDoc element, String JavaDoc BaseURI)
191            throws XMLSecurityException {
192
193       this();
194
195       if (element == null) {
196          throw new XMLSecurityException("ElementProxy.nullElement");
197       }
198       
199       if (true) {
200         if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "setElement(\"" + element.getTagName() + "\", \"" + BaseURI
201                 + "\")");
202       }
203
204       this._doc = element.getOwnerDocument();
205       this._state = ElementProxy.MODE_PROCESS;
206       this._constructionElement = element;
207       this._baseURI = BaseURI;
208
209       this.guaranteeThatElementInCorrectSpace();
210    }
211
212    /**
213     * Returns the Element which was constructed by the Object.
214     *
215     * @return the Element which was constructed by the Object.
216     */

217    public final Element JavaDoc getElement() {
218       return this._constructionElement;
219    }
220
221    /**
222     * Returns the Element plus a leading and a trailing CarriageReturn Text node.
223     *
224     * @return the Element which was constructed by the Object.
225     */

226    public final NodeList JavaDoc getElementPlusReturns() {
227
228       HelperNodeList nl = new HelperNodeList();
229
230       nl.appendChild(this._doc.createTextNode("\n"));
231       nl.appendChild(this.getElement());
232       nl.appendChild(this._doc.createTextNode("\n"));
233
234       return nl;
235    }
236
237    /**
238     * Method getDocument
239     *
240     * @return the Document where this element is contained.
241     */

242    public Document JavaDoc getDocument() {
243       return this._doc;
244    }
245
246    /**
247     * Method getBaseURI
248     *
249     * @return the base uri of the namespace of this element
250     */

251    public String JavaDoc getBaseURI() {
252       return this._baseURI;
253    }
254
255    /**
256     * Method guaranteeThatElementInCorrectSpace
257     *
258     * @throws XMLSecurityException
259     */

260    public void guaranteeThatElementInCorrectSpace()
261            throws XMLSecurityException {
262
263       String JavaDoc localnameSHOULDBE = this.getBaseLocalName();
264       String JavaDoc namespaceSHOULDBE = this.getBaseNamespace();
265       
266       String JavaDoc localnameIS = this._constructionElement.getLocalName();
267       String JavaDoc namespaceIS = this._constructionElement.getNamespaceURI();
268       if ( !localnameSHOULDBE.equals(localnameIS) ||
269         !namespaceSHOULDBE.equals(namespaceIS)) {
270          Object JavaDoc exArgs[] = { namespaceIS +":"+ localnameIS,
271            namespaceSHOULDBE +":"+ localnameSHOULDBE};
272          throw new XMLSecurityException("xml.WrongElement", exArgs);
273       }
274    }
275
276    /**
277     * Method setVal
278     *
279     * @param bi
280     * @param localname
281     */

282    public void addBigIntegerElement(BigInteger JavaDoc bi, String JavaDoc localname) {
283
284       if (bi != null) {
285          Element JavaDoc e = XMLUtils.createElementInSignatureSpace(this._doc,
286                         localname);
287
288          Base64.fillElementWithBigInteger(e, bi);
289          this._constructionElement.appendChild(e);
290          XMLUtils.addReturnToElement(this._constructionElement);
291       }
292    }
293
294    /**
295     * Method addBase64Element
296     *
297     * @param bytes
298     * @param localname
299     */

300    public void addBase64Element(byte[] bytes, String JavaDoc localname) {
301
302       if (bytes != null) {
303
304          Element JavaDoc e = Base64.encodeToElement(this._doc, localname, bytes);
305
306          this._constructionElement.appendChild(e);
307          this._constructionElement.appendChild(this._doc.createTextNode("\n"));
308       }
309    }
310
311    /**
312     * Method addTextElement
313     *
314     * @param text
315     * @param localname
316     */

317    public void addTextElement(String JavaDoc text, String JavaDoc localname) {
318
319       Element JavaDoc e = XMLUtils.createElementInSignatureSpace(this._doc, localname);
320       Text JavaDoc t = this._doc.createTextNode(text);
321
322       e.appendChild(t);
323       this._constructionElement.appendChild(e);
324       XMLUtils.addReturnToElement(this._constructionElement);
325    }
326
327    /**
328     * Method addBase64Text
329     *
330     * @param bytes
331     */

332    public void addBase64Text(byte[] bytes) {
333
334       if (bytes != null) {
335          Text JavaDoc t = this._doc.createTextNode("\n" + Base64.encode(bytes) + "\n");
336
337          this._constructionElement.appendChild(t);
338       }
339    }
340
341    /**
342     * Method addText
343     *
344     * @param text
345     */

346    public void addText(String JavaDoc text) {
347
348       if (text != null) {
349          Text JavaDoc t = this._doc.createTextNode(text);
350
351          this._constructionElement.appendChild(t);
352       }
353    }
354
355    /**
356     * Method getVal
357     *
358     * @param localname
359     * @param namespace
360     * @return The biginter contained in the given element
361  * @throws Base64DecodingException
362     */

363    public BigInteger JavaDoc getBigIntegerFromChildElement(
364            String JavaDoc localname, String JavaDoc namespace) throws Base64DecodingException {
365         
366         return Base64.decodeBigIntegerFromText(
367                 XMLUtils.selectNodeText(this._constructionElement.getFirstChild(),
368                         namespace,localname,0));
369
370    }
371
372    /**
373     * Method getBytesFromChildElement
374     *
375     * @param localname
376     * @param namespace
377     * @return the bytes
378     * @throws XMLSecurityException
379     */

380    public byte[] getBytesFromChildElement(String JavaDoc localname, String JavaDoc namespace)
381            throws XMLSecurityException {
382                
383          Element JavaDoc e =
384              XMLUtils.selectNode(
385                  this._constructionElement.getFirstChild(),
386                  namespace,
387                  localname,
388                  0);
389             
390          return Base64.decode(e);
391    }
392
393    /**
394     * Method getTextFromChildElement
395     *
396     * @param localname
397     * @param namespace
398     * @return the Text of the textNode
399     */

400    public String JavaDoc getTextFromChildElement(String JavaDoc localname, String JavaDoc namespace) {
401               
402          Text JavaDoc t =
403              (Text JavaDoc) XMLUtils.selectNode(
404                         this._constructionElement.getFirstChild(),
405                         namespace,
406                         localname,
407                         0).getFirstChild();
408
409          return t.getData();
410    }
411
412    /**
413     * Method getBytesFromTextChild
414     *
415     * @return The base64 bytes from the first text child of this element
416     * @throws XMLSecurityException
417     */

418    public byte[] getBytesFromTextChild() throws XMLSecurityException {
419       
420          Text JavaDoc t = (Text JavaDoc)this._constructionElement.getFirstChild();
421                                                    
422
423          return Base64.decode(t.getData());
424    }
425
426    /**
427     * Method getTextFromTextChild
428     *
429     * @return the Text obtained concatening all the the text nodes of this element
430     */

431    public String JavaDoc getTextFromTextChild() {
432       return XMLUtils.getFullTextChildrenFromElement(this._constructionElement);
433    }
434
435   
436
437    /**
438     * Method length
439     *
440     * @param namespace
441     * @param localname
442     * @return the number of elements {namespace}:localname under this element
443     */

444    public int length(String JavaDoc namespace, String JavaDoc localname) {
445         int number=0;
446         Node JavaDoc sibling=this._constructionElement.getFirstChild();
447         while (sibling!=null) {
448             if (localname.equals(sibling.getLocalName())
449                     &&
450                     namespace.equals(sibling.getNamespaceURI())) {
451                 number++;
452             }
453             sibling=sibling.getNextSibling();
454         }
455         return number;
456      }
457
458    /**
459     * Adds an xmlns: definition to the Element. This can be called as follows:
460     *
461     * <PRE>
462     * // set namespace with ds prefix
463     * xpathContainer.setXPathNamespaceContext("ds", "http://www.w3.org/2000/09/xmldsig#");
464     * xpathContainer.setXPathNamespaceContext("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#");
465     * </PRE>
466     *
467     * @param prefix
468     * @param uri
469     * @throws XMLSecurityException
470     */

471    public void setXPathNamespaceContext(String JavaDoc prefix, String JavaDoc uri)
472            throws XMLSecurityException {
473
474       String JavaDoc ns;
475
476       if ((prefix == null) || (prefix.length() == 0)) {
477        throw new XMLSecurityException("defaultNamespaceCannotBeSetHere");
478       } else if (prefix.equals("xmlns")) {
479         throw new XMLSecurityException("defaultNamespaceCannotBeSetHere");
480       } else if (prefix.startsWith("xmlns:")) {
481          ns = prefix;//"xmlns:" + prefix.substring("xmlns:".length());
482
} else {
483          ns = "xmlns:" + prefix;
484       }
485
486       
487
488       Attr JavaDoc a = this._constructionElement.getAttributeNodeNS(Constants.NamespaceSpecNS, ns);
489
490       if (a != null) {
491        if (!a.getNodeValue().equals(uri)) {
492          Object JavaDoc exArgs[] = { ns,
493                              this._constructionElement.getAttributeNS(null,
494                                                                       ns) };
495
496          throw new XMLSecurityException("namespacePrefixAlreadyUsedByOtherURI",
497                                         exArgs);
498        }
499        return;
500       }
501
502       this._constructionElement.setAttributeNS(Constants.NamespaceSpecNS, ns,
503                                                uri);
504    }
505
506    /** Field _prefixMappings */
507    static HashMap JavaDoc _prefixMappings = new HashMap JavaDoc();
508
509    /**
510     * Method setDefaultPrefix
511     *
512     * @param namespace
513     * @param prefix
514     * @throws XMLSecurityException
515     */

516    public static void setDefaultPrefix(String JavaDoc namespace, String JavaDoc prefix)
517            throws XMLSecurityException {
518     
519     if (ElementProxy._prefixMappings.containsValue(prefix)) {
520         
521         Object JavaDoc storedNamespace=ElementProxy._prefixMappings.get(namespace);
522          if (!storedNamespace.equals(prefix)) {
523             Object JavaDoc exArgs[] = { prefix, namespace, storedNamespace };
524
525             throw new XMLSecurityException("prefix.AlreadyAssigned", exArgs);
526          }
527     }
528       ElementProxy._prefixMappings.put(namespace, prefix);
529    }
530
531    /**
532     * Method getDefaultPrefix
533     *
534     * @param namespace
535     * @return the default prefix bind to this element.
536     */

537    public static String JavaDoc getDefaultPrefix(String JavaDoc namespace) {
538
539       String JavaDoc prefix = (String JavaDoc) ElementProxy._prefixMappings.get(namespace);
540
541       return prefix;
542    }
543 }
544
Popular Tags