1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999-2004 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xerces" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, International
  53. * Business Machines, Inc., http://www.apache.org. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package com.sun.org.apache.xerces.internal.dom;
  58. import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl;
  59. import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
  60. import org.w3c.dom.DOMException;
  61. /**
  62. * AttrNSImpl inherits from AttrImpl and adds namespace support.
  63. * <P>
  64. * The qualified name is the node name, and we store localName which is also
  65. * used in all queries. On the other hand we recompute the prefix when
  66. * necessary.
  67. * @author Arnaud Le Hors, IBM
  68. * @author Andy Clark, IBM
  69. * @author Ralf Pfeiffer, IBM
  70. * @version $Id: AttrNSImpl.java,v 1.43 2004/02/16 05:34:38 mrglavas Exp $
  71. */
  72. public class AttrNSImpl
  73. extends AttrImpl {
  74. //
  75. // Constants
  76. //
  77. /** Serialization version. */
  78. static final long serialVersionUID = -781906615369795414L;
  79. static final String xmlnsURI = "http://www.w3.org/2000/xmlns/";
  80. static final String xmlURI = "http://www.w3.org/XML/1998/namespace";
  81. //
  82. // Data
  83. //
  84. /** DOM2: Namespace URI. */
  85. protected String namespaceURI;
  86. /** DOM2: localName. */
  87. protected String localName;
  88. /*
  89. * Default constructor
  90. */
  91. public AttrNSImpl(){}
  92. /**
  93. * DOM2: Constructor for Namespace implementation.
  94. */
  95. protected AttrNSImpl(CoreDocumentImpl ownerDocument,
  96. String namespaceURI,
  97. String qualifiedName) {
  98. super(ownerDocument, qualifiedName);
  99. setName(namespaceURI, qualifiedName);
  100. }
  101. private void setName(String namespaceURI, String qname){
  102. String prefix;
  103. // DOM Level 3: namespace URI is never empty string.
  104. this.namespaceURI = namespaceURI;
  105. if (namespaceURI !=null) {
  106. this.namespaceURI = (namespaceURI.length() == 0)? null
  107. : namespaceURI;
  108. }
  109. int colon1 = qname.indexOf(':');
  110. int colon2 = qname.lastIndexOf(':');
  111. ownerDocument().checkNamespaceWF(qname, colon1, colon2);
  112. if (colon1 < 0) {
  113. // there is no prefix
  114. localName = qname;
  115. ownerDocument().checkQName(null, localName);
  116. if (ownerDocument().errorChecking) {
  117. if (qname.equals("xmlns")
  118. && (namespaceURI == null
  119. || !namespaceURI.equals(NamespaceContext.XMLNS_URI))
  120. || (namespaceURI!=null && namespaceURI.equals(NamespaceContext.XMLNS_URI)
  121. && !qname.equals("xmlns"))) {
  122. String msg =
  123. DOMMessageFormatter.formatMessage(
  124. DOMMessageFormatter.DOM_DOMAIN,
  125. "NAMESPACE_ERR",
  126. null);
  127. throw new DOMException(DOMException.NAMESPACE_ERR, msg);
  128. }
  129. }
  130. }
  131. else {
  132. prefix = qname.substring(0, colon1);
  133. localName = qname.substring(colon2+1);
  134. ownerDocument().checkQName(prefix, localName);
  135. ownerDocument().checkDOMNSErr(prefix, namespaceURI);
  136. }
  137. }
  138. // when local name is known
  139. public AttrNSImpl(CoreDocumentImpl ownerDocument,
  140. String namespaceURI,
  141. String qualifiedName,
  142. String localName) {
  143. super(ownerDocument, qualifiedName);
  144. this.localName = localName;
  145. this.namespaceURI = namespaceURI;
  146. }
  147. // for DeferredAttrImpl
  148. protected AttrNSImpl(CoreDocumentImpl ownerDocument,
  149. String value) {
  150. super(ownerDocument, value);
  151. }
  152. // Support for DOM Level 3 renameNode method.
  153. // Note: This only deals with part of the pb. It is expected to be
  154. // called after the Attr has been detached for one thing.
  155. // CoreDocumentImpl does all the work.
  156. void rename(String namespaceURI, String qualifiedName) {
  157. if (needsSyncData()) {
  158. synchronizeData();
  159. }
  160. this.name = qualifiedName;
  161. setName(namespaceURI, qualifiedName);
  162. }
  163. /**
  164. * NON-DOM: resets this node and sets specified values for the node
  165. *
  166. * @param ownerDocument
  167. * @param namespaceURI
  168. * @param qualifiedName
  169. * @param localName
  170. */
  171. public void setValues (CoreDocumentImpl ownerDocument,
  172. String namespaceURI,
  173. String qualifiedName,
  174. String localName){
  175. super.textNode = null;
  176. super.flags = 0;
  177. isSpecified(true);
  178. hasStringValue(true);
  179. super.setOwnerDocument(ownerDocument);
  180. this.localName = localName;
  181. this.namespaceURI = namespaceURI;
  182. super.name = qualifiedName;
  183. super.value = null;
  184. }
  185. //
  186. // DOM2: Namespace methods
  187. //
  188. /**
  189. * Introduced in DOM Level 2. <p>
  190. *
  191. * The namespace URI of this node, or null if it is unspecified.<p>
  192. *
  193. * This is not a computed value that is the result of a namespace lookup
  194. * based on an examination of the namespace declarations in scope. It is
  195. * merely the namespace URI given at creation time.<p>
  196. *
  197. * For nodes created with a DOM Level 1 method, such as createElement
  198. * from the Document interface, this is null.
  199. * @since WD-DOM-Level-2-19990923
  200. */
  201. public String getNamespaceURI()
  202. {
  203. if (needsSyncData()) {
  204. synchronizeData();
  205. }
  206. // REVIST: This code could/should be done at a lower-level, such that
  207. // the namespaceURI is set properly upon creation. However, there still
  208. // seems to be some DOM spec interpretation grey-area.
  209. return namespaceURI;
  210. }
  211. /**
  212. * Introduced in DOM Level 2. <p>
  213. *
  214. * The namespace prefix of this node, or null if it is unspecified. <p>
  215. *
  216. * For nodes created with a DOM Level 1 method, such as createElement
  217. * from the Document interface, this is null. <p>
  218. *
  219. * @since WD-DOM-Level-2-19990923
  220. */
  221. public String getPrefix()
  222. {
  223. if (needsSyncData()) {
  224. synchronizeData();
  225. }
  226. int index = name.indexOf(':');
  227. return index < 0 ? null : name.substring(0, index);
  228. }
  229. /**
  230. * Introduced in DOM Level 2. <p>
  231. *
  232. * Note that setting this attribute changes the nodeName attribute, which
  233. * holds the qualified name, as well as the tagName and name attributes of
  234. * the Element and Attr interfaces, when applicable.<p>
  235. *
  236. * @param prefix The namespace prefix of this node, or null(empty string) if it is unspecified.
  237. *
  238. * @exception INVALID_CHARACTER_ERR
  239. * Raised if the specified
  240. * prefix contains an invalid character.
  241. * @exception DOMException
  242. * @since WD-DOM-Level-2-19990923
  243. */
  244. public void setPrefix(String prefix)
  245. throws DOMException
  246. {
  247. if (needsSyncData()) {
  248. synchronizeData();
  249. }
  250. if (ownerDocument().errorChecking) {
  251. if (isReadOnly()) {
  252. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
  253. throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
  254. }
  255. if (prefix != null && prefix.length() != 0) {
  256. if (!CoreDocumentImpl.isXMLName(prefix,ownerDocument().isXML11Version())) {
  257. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_CHARACTER_ERR", null);
  258. throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
  259. }
  260. if (namespaceURI == null || prefix.indexOf(':') >=0) {
  261. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR", null);
  262. throw new DOMException(DOMException.NAMESPACE_ERR, msg);
  263. }
  264. if (prefix.equals("xmlns")) {
  265. if (!namespaceURI.equals(xmlnsURI)){
  266. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR", null);
  267. throw new DOMException(DOMException.NAMESPACE_ERR, msg);
  268. }
  269. } else if (prefix.equals("xml")) {
  270. if (!namespaceURI.equals(xmlURI)) {
  271. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR", null);
  272. throw new DOMException(DOMException.NAMESPACE_ERR, msg);
  273. }
  274. }else if (name.equals("xmlns")) {
  275. String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR", null);
  276. throw new DOMException(DOMException.NAMESPACE_ERR, msg);
  277. }
  278. }
  279. }
  280. // update node name with new qualifiedName
  281. if (prefix !=null && prefix.length() != 0) {
  282. name = prefix + ":" + localName;
  283. }
  284. else {
  285. name = localName;
  286. }
  287. }
  288. /**
  289. * Introduced in DOM Level 2. <p>
  290. *
  291. * Returns the local part of the qualified name of this node.
  292. * @since WD-DOM-Level-2-19990923
  293. */
  294. public String getLocalName()
  295. {
  296. if (needsSyncData()) {
  297. synchronizeData();
  298. }
  299. return localName;
  300. }
  301. /**
  302. * DOM Level 3 Experimental
  303. *
  304. * @see org.w3c.dom.TypeInfo#isDerivedFrom()
  305. */
  306. public boolean isDerivedFrom(String typeNamespaceArg,
  307. String typeNameArg,
  308. int derivationMethod) {
  309. //REVISIT: XSSimpleTypeDecl.derivedFrom and
  310. //derivationMethod constants in DOM vs Xerces
  311. if (type !=null){
  312. if (type instanceof XSSimpleTypeDecl){
  313. return ((XSSimpleTypeDecl)type).derivedFrom(typeNamespaceArg,typeNameArg,(short)derivationMethod);
  314. }
  315. }
  316. return false;
  317. }
  318. /**
  319. * @see org.w3c.dom.TypeInfo#getTypeNamespace()
  320. */
  321. public String getTypeNamespace() {
  322. if (type !=null) {
  323. if (type instanceof XSSimpleTypeDecl){
  324. return ((XSSimpleTypeDecl)type).getNamespace();
  325. }
  326. return DTD_URI;
  327. }
  328. return null;
  329. }
  330. }