PageRenderTime 126ms CodeModel.GetById 52ms app.highlight 52ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/jre-1.6.0/src/com/sun/org/apache/xml/internal/utils/QName.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 707 lines | 343 code | 94 blank | 270 comment | 78 complexity | 117db5973abf1bbad4667054b2a5404e MD5 | raw file
  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 * $Id: QName.java,v 1.2.4.1 2005/09/15 08:15:52 suresh_emailid Exp $
 18 */
 19package com.sun.org.apache.xml.internal.utils;
 20
 21import java.util.Stack;
 22import java.util.StringTokenizer;
 23
 24import com.sun.org.apache.xml.internal.res.XMLErrorResources;
 25import com.sun.org.apache.xml.internal.res.XMLMessages;
 26
 27import org.w3c.dom.Element;
 28
 29/**
 30 * Class to represent a qualified name: "The name of an internal XSLT object,
 31 * specifically a named template (see [7 Named Templates]), a mode (see [6.7 Modes]),
 32 * an attribute set (see [8.1.4 Named Attribute Sets]), a key (see [14.2 Keys]),
 33 * a locale (see [14.3 Number Formatting]), a variable or a parameter (see
 34 * [12 Variables and Parameters]) is specified as a QName. If it has a prefix,
 35 * then the prefix is expanded into a URI reference using the namespace declarations
 36 * in effect on the attribute in which the name occurs. The expanded name
 37 * consisting of the local part of the name and the possibly null URI reference
 38 * is used as the name of the object. The default namespace is not used for
 39 * unprefixed names."
 40 * @xsl.usage general
 41 */
 42public class QName implements java.io.Serializable
 43{
 44    static final long serialVersionUID = 467434581652829920L;
 45
 46  /**
 47   * The local name.
 48   * @serial
 49   */
 50  protected String _localName;
 51
 52  /**
 53   * The namespace URI.
 54   * @serial
 55   */
 56  protected String _namespaceURI;
 57
 58  /**
 59   * The namespace prefix.
 60   * @serial
 61   */
 62  protected String _prefix;
 63
 64  /**
 65   * The XML namespace.
 66   */
 67  public static final String S_XMLNAMESPACEURI =
 68    "http://www.w3.org/XML/1998/namespace";
 69
 70  /**
 71   * The cached hashcode, which is calculated at construction time.
 72   * @serial
 73   */
 74  private int m_hashCode;
 75
 76  /**
 77   * Constructs an empty QName.
 78   * 20001019: Try making this public, to support Serializable? -- JKESS
 79   */
 80  public QName(){}
 81
 82  /**
 83   * Constructs a new QName with the specified namespace URI and
 84   * local name.
 85   *
 86   * @param namespaceURI The namespace URI if known, or null
 87   * @param localName The local name
 88   */
 89  public QName(String namespaceURI, String localName)
 90  {
 91    this(namespaceURI, localName, false); 
 92  }
 93
 94  /**
 95   * Constructs a new QName with the specified namespace URI and
 96   * local name.
 97   *
 98   * @param namespaceURI The namespace URI if known, or null
 99   * @param localName The local name
100   * @param validate If true the new QName will be validated and an IllegalArgumentException will
101   *                 be thrown if it is invalid.
102   */
103  public QName(String namespaceURI, String localName, boolean validate) 
104  {
105
106    // This check was already here.  So, for now, I will not add it to the validation
107    // that is done when the validate parameter is true.
108    if (localName == null)
109      throw new IllegalArgumentException(XMLMessages.createXMLMessage(
110            XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");
111
112    if (validate) 
113    {
114        if (!XML11Char.isXML11ValidNCName(localName))
115        {
116            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
117            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
118        }
119    }
120    
121    _namespaceURI = namespaceURI;
122    _localName = localName;
123    m_hashCode = toString().hashCode();
124  }
125  
126  /**
127   * Constructs a new QName with the specified namespace URI, prefix
128   * and local name.
129   *
130   * @param namespaceURI The namespace URI if known, or null
131   * @param prefix The namespace prefix is known, or null
132   * @param localName The local name
133   * 
134   */
135  public QName(String namespaceURI, String prefix, String localName)
136  {
137     this(namespaceURI, prefix, localName, false);
138  }
139  
140 /**
141   * Constructs a new QName with the specified namespace URI, prefix
142   * and local name.
143   *
144   * @param namespaceURI The namespace URI if known, or null
145   * @param prefix The namespace prefix is known, or null
146   * @param localName The local name
147   * @param validate If true the new QName will be validated and an IllegalArgumentException will
148   *                 be thrown if it is invalid.
149   */
150  public QName(String namespaceURI, String prefix, String localName, boolean validate)
151  {
152
153    // This check was already here.  So, for now, I will not add it to the validation
154    // that is done when the validate parameter is true.
155    if (localName == null)
156      throw new IllegalArgumentException(XMLMessages.createXMLMessage(
157            XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");
158
159    if (validate)
160    {    
161        if (!XML11Char.isXML11ValidNCName(localName))
162        {
163            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
164            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
165        }
166
167        if ((null != prefix) && (!XML11Char.isXML11ValidNCName(prefix)))
168        {
169            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
170            XMLErrorResources.ER_ARG_PREFIX_INVALID,null )); //"Argument 'prefix' not a valid NCName");
171        }
172
173    }
174    _namespaceURI = namespaceURI;
175    _prefix = prefix;
176    _localName = localName;
177    m_hashCode = toString().hashCode();
178  }  
179
180  /**
181   * Construct a QName from a string, without namespace resolution.  Good
182   * for a few odd cases.
183   *
184   * @param localName Local part of qualified name
185   * 
186   */
187  public QName(String localName)
188  {
189    this(localName, false);
190  }
191  
192  /**
193   * Construct a QName from a string, without namespace resolution.  Good
194   * for a few odd cases.
195   *
196   * @param localName Local part of qualified name
197   * @param validate If true the new QName will be validated and an IllegalArgumentException will
198   *                 be thrown if it is invalid.
199   */
200  public QName(String localName, boolean validate)
201  {
202
203    // This check was already here.  So, for now, I will not add it to the validation
204    // that is done when the validate parameter is true.
205    if (localName == null)
206      throw new IllegalArgumentException(XMLMessages.createXMLMessage(
207            XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");
208
209    if (validate)
210    {    
211        if (!XML11Char.isXML11ValidNCName(localName))
212        {
213            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
214            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
215        }
216    }
217    _namespaceURI = null;
218    _localName = localName;
219    m_hashCode = toString().hashCode();
220  }  
221
222  /**
223   * Construct a QName from a string, resolving the prefix
224   * using the given namespace stack. The default namespace is
225   * not resolved.
226   *
227   * @param qname Qualified name to resolve
228   * @param namespaces Namespace stack to use to resolve namespace
229   */
230  public QName(String qname, Stack namespaces)
231  {
232    this(qname, namespaces, false);
233  }
234
235  /**
236   * Construct a QName from a string, resolving the prefix
237   * using the given namespace stack. The default namespace is
238   * not resolved.
239   *
240   * @param qname Qualified name to resolve
241   * @param namespaces Namespace stack to use to resolve namespace
242   * @param validate If true the new QName will be validated and an IllegalArgumentException will
243   *                 be thrown if it is invalid.
244   */
245  public QName(String qname, Stack namespaces, boolean validate)
246  {
247
248    String namespace = null;
249    String prefix = null;
250    int indexOfNSSep = qname.indexOf(':');
251
252    if (indexOfNSSep > 0)
253    {
254      prefix = qname.substring(0, indexOfNSSep);
255
256      if (prefix.equals("xml"))
257      {
258        namespace = S_XMLNAMESPACEURI;
259      }
260      // Do we want this?
261      else if (prefix.equals("xmlns"))
262      {
263        return;
264      }
265      else
266      {
267        int depth = namespaces.size();
268
269        for (int i = depth - 1; i >= 0; i--)
270        {
271          NameSpace ns = (NameSpace) namespaces.elementAt(i);
272
273          while (null != ns)
274          {
275            if ((null != ns.m_prefix) && prefix.equals(ns.m_prefix))
276            {
277              namespace = ns.m_uri;
278              i = -1;
279
280              break;
281            }
282
283            ns = ns.m_next;
284          }
285        }
286      }
287
288      if (null == namespace)
289      {
290        throw new RuntimeException(
291          XMLMessages.createXMLMessage(
292            XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
293            new Object[]{ prefix }));  //"Prefix must resolve to a namespace: "+prefix);
294      }
295    }
296
297    _localName = (indexOfNSSep < 0)
298                 ? qname : qname.substring(indexOfNSSep + 1);
299                 
300    if (validate)
301    {
302        if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName))) 
303        {
304           throw new IllegalArgumentException(XMLMessages.createXMLMessage(
305            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
306        }
307    }                 
308    _namespaceURI = namespace;
309    _prefix = prefix;
310    m_hashCode = toString().hashCode();
311  }
312
313  /**
314   * Construct a QName from a string, resolving the prefix
315   * using the given namespace context and prefix resolver. 
316   * The default namespace is not resolved.
317   * 
318   * @param qname Qualified name to resolve
319   * @param namespaceContext Namespace Context to use
320   * @param resolver Prefix resolver for this context
321   */
322  public QName(String qname, Element namespaceContext,
323               PrefixResolver resolver)
324  {
325      this(qname, namespaceContext, resolver, false);
326  }
327
328  /**
329   * Construct a QName from a string, resolving the prefix
330   * using the given namespace context and prefix resolver. 
331   * The default namespace is not resolved.
332   * 
333   * @param qname Qualified name to resolve
334   * @param namespaceContext Namespace Context to use
335   * @param resolver Prefix resolver for this context
336   * @param validate If true the new QName will be validated and an IllegalArgumentException will
337   *                 be thrown if it is invalid.
338   */
339  public QName(String qname, Element namespaceContext,
340               PrefixResolver resolver, boolean validate)
341  {
342
343    _namespaceURI = null;
344
345    int indexOfNSSep = qname.indexOf(':');
346
347    if (indexOfNSSep > 0)
348    {
349      if (null != namespaceContext)
350      {
351        String prefix = qname.substring(0, indexOfNSSep);
352
353        _prefix = prefix;
354
355        if (prefix.equals("xml"))
356        {
357          _namespaceURI = S_XMLNAMESPACEURI;
358        }
359        
360        // Do we want this?
361        else if (prefix.equals("xmlns"))
362        {
363          return;
364        }
365        else
366        {
367          _namespaceURI = resolver.getNamespaceForPrefix(prefix,
368                  namespaceContext);
369        }
370
371        if (null == _namespaceURI)
372        {
373          throw new RuntimeException(
374            XMLMessages.createXMLMessage(
375              XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
376              new Object[]{ prefix }));  //"Prefix must resolve to a namespace: "+prefix);
377        }
378      }
379      else
380      {
381
382        // TODO: error or warning...
383      }
384    }
385
386    _localName = (indexOfNSSep < 0)
387                 ? qname : qname.substring(indexOfNSSep + 1);
388
389    if (validate)
390    {
391        if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName))) 
392        {
393           throw new IllegalArgumentException(XMLMessages.createXMLMessage(
394            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
395        }
396    }                 
397                 
398    m_hashCode = toString().hashCode();
399  }
400
401
402  /**
403   * Construct a QName from a string, resolving the prefix
404   * using the given namespace stack. The default namespace is
405   * not resolved.
406   *
407   * @param qname Qualified name to resolve
408   * @param resolver Prefix resolver for this context
409   */
410  public QName(String qname, PrefixResolver resolver)
411  {
412    this(qname, resolver, false);
413  }
414
415  /**
416   * Construct a QName from a string, resolving the prefix
417   * using the given namespace stack. The default namespace is
418   * not resolved.
419   *
420   * @param qname Qualified name to resolve
421   * @param resolver Prefix resolver for this context
422   * @param validate If true the new QName will be validated and an IllegalArgumentException will
423   *                 be thrown if it is invalid.
424   */
425  public QName(String qname, PrefixResolver resolver, boolean validate)
426  {
427
428	String prefix = null;
429    _namespaceURI = null;
430
431    int indexOfNSSep = qname.indexOf(':');
432
433    if (indexOfNSSep > 0)
434    {
435      prefix = qname.substring(0, indexOfNSSep);
436
437      if (prefix.equals("xml"))
438      {
439        _namespaceURI = S_XMLNAMESPACEURI;
440      }
441      else
442      {
443        _namespaceURI = resolver.getNamespaceForPrefix(prefix);
444      }
445
446      if (null == _namespaceURI)
447      {
448        throw new RuntimeException(
449          XMLMessages.createXMLMessage(
450            XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
451            new Object[]{ prefix }));  //"Prefix must resolve to a namespace: "+prefix);
452      }
453      _localName = qname.substring(indexOfNSSep + 1);
454    }
455    else if (indexOfNSSep == 0) 
456    {
457      throw new RuntimeException(
458         XMLMessages.createXMLMessage(
459           XMLErrorResources.ER_NAME_CANT_START_WITH_COLON,
460           null));
461    }
462    else
463    {
464      _localName = qname;
465    }   
466                 
467    if (validate)
468    {
469        if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName))) 
470        {
471           throw new IllegalArgumentException(XMLMessages.createXMLMessage(
472            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
473        }
474    }                 
475
476              
477    m_hashCode = toString().hashCode();
478    _prefix = prefix;
479  }
480
481  /**
482   * Returns the namespace URI. Returns null if the namespace URI
483   * is not known.
484   *
485   * @return The namespace URI, or null
486   */
487  public String getNamespaceURI()
488  {
489    return _namespaceURI;
490  }
491
492  /**
493   * Returns the namespace prefix. Returns null if the namespace
494   * prefix is not known.
495   *
496   * @return The namespace prefix, or null
497   */
498  public String getPrefix()
499  {
500    return _prefix;
501  }
502
503  /**
504   * Returns the local part of the qualified name.
505   *
506   * @return The local part of the qualified name
507   */
508  public String getLocalName()
509  {
510    return _localName;
511  }
512
513  /**
514   * Return the string representation of the qualified name, using the 
515   * prefix if available, or the '{ns}foo' notation if not. Performs
516   * string concatenation, so beware of performance issues.
517   *
518   * @return the string representation of the namespace
519   */
520  public String toString()
521  {
522
523    return _prefix != null
524           ? (_prefix + ":" + _localName)
525           : (_namespaceURI != null
526              ? ("{"+_namespaceURI + "}" + _localName) : _localName);
527  }
528  
529  /**
530   * Return the string representation of the qualified name using the 
531   * the '{ns}foo' notation. Performs
532   * string concatenation, so beware of performance issues.
533   *
534   * @return the string representation of the namespace
535   */
536  public String toNamespacedString()
537  {
538
539    return (_namespaceURI != null
540              ? ("{"+_namespaceURI + "}" + _localName) : _localName);
541  }
542
543
544  /**
545   * Get the namespace of the qualified name.
546   *
547   * @return the namespace URI of the qualified name
548   */
549  public String getNamespace()
550  {
551    return getNamespaceURI();
552  }
553
554  /**
555   * Get the local part of the qualified name.
556   *
557   * @return the local part of the qualified name
558   */
559  public String getLocalPart()
560  {
561    return getLocalName();
562  }
563
564  /**
565   * Return the cached hashcode of the qualified name.
566   *
567   * @return the cached hashcode of the qualified name
568   */
569  public int hashCode()
570  {
571    return m_hashCode;
572  }
573
574  /**
575   * Override equals and agree that we're equal if
576   * the passed object is a string and it matches
577   * the name of the arg.
578   *
579   * @param ns Namespace URI to compare to
580   * @param localPart Local part of qualified name to compare to 
581   *
582   * @return True if the local name and uri match 
583   */
584  public boolean equals(String ns, String localPart)
585  {
586
587    String thisnamespace = getNamespaceURI();
588
589    return getLocalName().equals(localPart)
590           && (((null != thisnamespace) && (null != ns))
591               ? thisnamespace.equals(ns)
592               : ((null == thisnamespace) && (null == ns)));
593  }
594
595  /**
596   * Override equals and agree that we're equal if
597   * the passed object is a QName and it matches
598   * the name of the arg.
599   *
600   * @return True if the qualified names are equal
601   */
602  public boolean equals(Object object)
603  {
604
605    if (object == this)
606      return true;
607
608    if (object instanceof QName) {
609      QName qname = (QName) object;
610      String thisnamespace = getNamespaceURI();
611      String thatnamespace = qname.getNamespaceURI();
612
613      return getLocalName().equals(qname.getLocalName())
614             && (((null != thisnamespace) && (null != thatnamespace))
615                 ? thisnamespace.equals(thatnamespace)
616                 : ((null == thisnamespace) && (null == thatnamespace)));
617    }
618    else
619      return false;
620  }
621
622  /**
623   * Given a string, create and return a QName object  
624   *
625   *
626   * @param name String to use to create QName
627   *
628   * @return a QName object
629   */
630  public static QName getQNameFromString(String name)
631  {
632
633    StringTokenizer tokenizer = new StringTokenizer(name, "{}", false);
634    QName qname;
635    String s1 = tokenizer.nextToken();
636    String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
637
638    if (null == s2)
639      qname = new QName(null, s1);
640    else
641      qname = new QName(s1, s2);
642
643    return qname;
644  }
645
646  /**
647   * This function tells if a raw attribute name is a
648   * xmlns attribute.
649   *
650   * @param attRawName Raw name of attribute
651   *
652   * @return True if the attribute starts with or is equal to xmlns 
653   */
654  public static boolean isXMLNSDecl(String attRawName)
655  {
656
657    return (attRawName.startsWith("xmlns")
658            && (attRawName.equals("xmlns")
659                || attRawName.startsWith("xmlns:")));
660  }
661
662  /**
663   * This function tells if a raw attribute name is a
664   * xmlns attribute.
665   *
666   * @param attRawName Raw name of attribute
667   *
668   * @return Prefix of attribute
669   */
670  public static String getPrefixFromXMLNSDecl(String attRawName)
671  {
672
673    int index = attRawName.indexOf(':');
674
675    return (index >= 0) ? attRawName.substring(index + 1) : "";
676  }
677
678  /**
679   * Returns the local name of the given node.
680   *
681   * @param qname Input name
682   *
683   * @return Local part of the name if prefixed, or the given name if not
684   */
685  public static String getLocalPart(String qname)
686  {
687
688    int index = qname.indexOf(':');
689
690    return (index < 0) ? qname : qname.substring(index + 1);
691  }
692
693  /**
694   * Returns the local name of the given node.
695   *
696   * @param qname Input name 
697   *
698   * @return Prefix of name or empty string if none there   
699   */
700  public static String getPrefixPart(String qname)
701  {
702
703    int index = qname.indexOf(':');
704
705    return (index >= 0) ? qname.substring(0, index) : "";
706  }
707}