aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLName.java
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLName.java')
-rw-r--r--trunk/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLName.java469
1 files changed, 469 insertions, 0 deletions
diff --git a/trunk/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLName.java b/trunk/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLName.java
new file mode 100644
index 0000000..edd7525
--- /dev/null
+++ b/trunk/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLName.java
@@ -0,0 +1,469 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Milen Nankov
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import org.mozilla.javascript.*;
+
+class XMLName extends Ref {
+ static final long serialVersionUID = 3832176310755686977L;
+
+ private static boolean isNCNameStartChar(int c) {
+ if ((c & ~0x7F) == 0) {
+ // Optimize for ASCII and use A..Z < _ < a..z
+ if (c >= 'a') {
+ return c <= 'z';
+ } else if (c >= 'A') {
+ if (c <= 'Z') {
+ return true;
+ }
+ return c == '_';
+ }
+ } else if ((c & ~0x1FFF) == 0) {
+ return (0xC0 <= c && c <= 0xD6)
+ || (0xD8 <= c && c <= 0xF6)
+ || (0xF8 <= c && c <= 0x2FF)
+ || (0x370 <= c && c <= 0x37D)
+ || 0x37F <= c;
+ }
+ return (0x200C <= c && c <= 0x200D)
+ || (0x2070 <= c && c <= 0x218F)
+ || (0x2C00 <= c && c <= 0x2FEF)
+ || (0x3001 <= c && c <= 0xD7FF)
+ || (0xF900 <= c && c <= 0xFDCF)
+ || (0xFDF0 <= c && c <= 0xFFFD)
+ || (0x10000 <= c && c <= 0xEFFFF);
+ }
+
+ private static boolean isNCNameChar(int c) {
+ if ((c & ~0x7F) == 0) {
+ // Optimize for ASCII and use - < . < 0..9 < A..Z < _ < a..z
+ if (c >= 'a') {
+ return c <= 'z';
+ } else if (c >= 'A') {
+ if (c <= 'Z') {
+ return true;
+ }
+ return c == '_';
+ } else if (c >= '0') {
+ return c <= '9';
+ } else {
+ return c == '-' || c == '.';
+ }
+ } else if ((c & ~0x1FFF) == 0) {
+ return isNCNameStartChar(c) || c == 0xB7
+ || (0x300 <= c && c <= 0x36F);
+ }
+ return isNCNameStartChar(c) || (0x203F <= c && c <= 0x2040);
+ }
+
+ // This means "accept" in the parsing sense
+ // See ECMA357 13.1.2.1
+ static boolean accept(Object nameObj) {
+ String name;
+ try {
+ name = ScriptRuntime.toString(nameObj);
+ } catch (EcmaError ee) {
+ if ("TypeError".equals(ee.getName())) {
+ return false;
+ }
+ throw ee;
+ }
+
+ // See http://w3.org/TR/xml-names11/#NT-NCName
+ int length = name.length();
+ if (length != 0) {
+ if (isNCNameStartChar(name.charAt(0))) {
+ for (int i = 1; i != length; ++i) {
+ if (!isNCNameChar(name.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private XmlNode.QName qname;
+ private boolean isAttributeName;
+ private boolean isDescendants;
+ private XMLObjectImpl xmlObject;
+
+ private XMLName() {
+ }
+
+ static XMLName formStar() {
+ XMLName rv = new XMLName();
+ rv.qname = XmlNode.QName.create(null, null);
+ return rv;
+ }
+
+ /** @deprecated */
+ static XMLName formProperty(XmlNode.Namespace namespace, String localName) {
+ if (localName != null && localName.equals("*")) localName = null;
+ XMLName rv = new XMLName();
+ rv.qname = XmlNode.QName.create(namespace, localName);
+ return rv;
+ }
+
+ /** @deprecated */
+ static XMLName formProperty(String uri, String localName) {
+ return formProperty(XmlNode.Namespace.create(uri), localName);
+ }
+
+ /** @deprecated */
+ static XMLName create(String defaultNamespaceUri, String name) {
+ if (name == null)
+ throw new IllegalArgumentException();
+
+ int l = name.length();
+ if (l != 0) {
+ char firstChar = name.charAt(0);
+ if (firstChar == '*') {
+ if (l == 1) {
+ return XMLName.formStar();
+ }
+ } else if (firstChar == '@') {
+ XMLName xmlName = XMLName.formProperty("", name.substring(1));
+ xmlName.setAttributeName();
+ return xmlName;
+ }
+ }
+
+ return XMLName.formProperty(defaultNamespaceUri, name);
+ }
+
+ static XMLName create(XmlNode.QName qname, boolean attribute, boolean descendants) {
+ XMLName rv = new XMLName();
+ rv.qname = qname;
+ rv.isAttributeName = attribute;
+ rv.isDescendants = descendants;
+ return rv;
+ }
+
+ /** @deprecated */
+ static XMLName create(XmlNode.QName qname) {
+ return create(qname, false, false);
+ }
+
+ void initXMLObject(XMLObjectImpl xmlObject) {
+ if (xmlObject == null) throw new IllegalArgumentException();
+ if (this.xmlObject != null) throw new IllegalStateException();
+ this.xmlObject = xmlObject;
+ }
+
+ String uri() {
+ if (qname.getNamespace() == null) return null;
+ return qname.getNamespace().getUri();
+ }
+
+ String localName() {
+ if (qname.getLocalName() == null) return "*";
+ return qname.getLocalName();
+ }
+
+ private void addDescendantChildren(XMLList list, XML target) {
+ XMLName xmlName = this;
+ if (target.isElement()) {
+ XML[] children = target.getChildren();
+ for (int i=0; i<children.length; i++) {
+ if (xmlName.matches( children[i] )) {
+ list.addToList( children[i] );
+ }
+ addDescendantChildren(list, children[i]);
+ }
+ }
+ }
+
+ void addMatchingAttributes(XMLList list, XML target) {
+ XMLName name = this;
+ if (target.isElement()) {
+ XML[] attributes = target.getAttributes();
+ for (int i=0; i<attributes.length; i++) {
+ if (name.matches( attributes[i]) ) {
+ list.addToList( attributes[i] );
+ }
+ }
+ }
+ }
+
+ private void addDescendantAttributes(XMLList list, XML target) {
+ if (target.isElement()) {
+ addMatchingAttributes(list, target);
+ XML[] children = target.getChildren();
+ for (int i=0; i<children.length; i++) {
+ addDescendantAttributes(list, children[i]);
+ }
+ }
+ }
+
+ XMLList matchDescendantAttributes(XMLList rv, XML target) {
+ rv.setTargets(target, null);
+ addDescendantAttributes(rv, target);
+ return rv;
+ }
+
+ XMLList matchDescendantChildren(XMLList rv, XML target) {
+ rv.setTargets(target, null);
+ addDescendantChildren(rv, target);
+ return rv;
+ }
+
+ void addDescendants(XMLList rv, XML target) {
+ XMLName xmlName = this;
+ if (xmlName.isAttributeName()) {
+ matchDescendantAttributes(rv, target);
+ } else {
+ matchDescendantChildren(rv, target);
+ }
+ }
+
+ private void addAttributes(XMLList rv, XML target) {
+ addMatchingAttributes(rv, target);
+ }
+
+ void addMatches(XMLList rv, XML target) {
+ if (isDescendants()) {
+ addDescendants(rv, target);
+ } else if (isAttributeName()) {
+ addAttributes(rv, target);
+ } else {
+ XML[] children = target.getChildren();
+ if (children != null) {
+ for (int i=0; i<children.length; i++) {
+ if (this.matches(children[i])) {
+ rv.addToList( children[i] );
+ }
+ }
+ }
+ rv.setTargets(target, this.toQname());
+ }
+ }
+
+ XMLList getMyValueOn(XML target) {
+ XMLList rv = target.newXMLList();
+ addMatches(rv, target);
+ return rv;
+ }
+
+ void setMyValueOn(XML target, Object value) {
+ // Special-case checks for undefined and null
+ if (value == null) {
+ value = "null";
+ } else if (value instanceof Undefined) {
+ value = "undefined";
+ }
+
+ XMLName xmlName = this;
+ // Get the named property
+ if (xmlName.isAttributeName()) {
+ target.setAttribute(xmlName, value);
+ } else if (xmlName.uri() == null && xmlName.localName().equals("*")) {
+ target.setChildren(value);
+ } else {
+ // Convert text into XML if needed.
+ XMLObjectImpl xmlValue = null;
+
+ if (value instanceof XMLObjectImpl) {
+ xmlValue = (XMLObjectImpl)value;
+
+ // Check for attribute type and convert to textNode
+ if (xmlValue instanceof XML) {
+ if (((XML)xmlValue).isAttribute()) {
+ xmlValue = target.makeXmlFromString(xmlName, xmlValue.toString());
+ }
+ }
+
+ if (xmlValue instanceof XMLList) {
+ for (int i = 0; i < xmlValue.length(); i++) {
+ XML xml = ((XMLList) xmlValue).item(i);
+
+ if (xml.isAttribute()) {
+ ((XMLList)xmlValue).replace(i, target.makeXmlFromString(xmlName, xml.toString()));
+ }
+ }
+ }
+ } else {
+ xmlValue = target.makeXmlFromString(xmlName, ScriptRuntime.toString(value));
+ }
+
+ XMLList matches = target.getPropertyList(xmlName);
+
+ if (matches.length() == 0) {
+ target.appendChild(xmlValue);
+ } else {
+ // Remove all other matches
+ for (int i = 1; i < matches.length(); i++) {
+ target.removeChild(matches.item(i).childIndex());
+ }
+
+ // Replace first match with new value.
+ XML firstMatch = matches.item(0);
+ target.replace(firstMatch.childIndex(), xmlValue);
+ }
+ }
+ }
+
+ public boolean has(Context cx) {
+ if (xmlObject == null) {
+ return false;
+ }
+ return xmlObject.hasXMLProperty(this);
+ }
+
+ public Object get(Context cx) {
+ if (xmlObject == null) {
+ throw ScriptRuntime.undefReadError(Undefined.instance,
+ toString());
+ }
+ return xmlObject.getXMLProperty(this);
+ }
+
+ public Object set(Context cx, Object value) {
+ if (xmlObject == null) {
+ throw ScriptRuntime.undefWriteError(Undefined.instance,
+ toString(),
+ value);
+ }
+ // Assignment to descendants causes parse error on bad reference
+ // and this should not be called
+ if (isDescendants) throw Kit.codeBug();
+ xmlObject.putXMLProperty(this, value);
+ return value;
+ }
+
+ public boolean delete(Context cx) {
+ if (xmlObject == null) {
+ return true;
+ }
+ xmlObject.deleteXMLProperty(this);
+ return !xmlObject.hasXMLProperty(this);
+ }
+
+ public String toString() {
+ //return qname.localName();
+ StringBuffer buff = new StringBuffer();
+ if (isDescendants) buff.append("..");
+ if (isAttributeName) buff.append('@');
+ if (uri() == null) {
+ buff.append('*');
+ if(localName().equals("*")) {
+ return buff.toString();
+ }
+ } else {
+ buff.append('"').append(uri()).append('"');
+ }
+ buff.append(':').append(localName());
+ return buff.toString();
+ }
+
+ final XmlNode.QName toQname() {
+ return this.qname;
+ }
+
+ final boolean matchesLocalName(String localName) {
+ return localName().equals("*") || localName().equals(localName);
+ }
+
+ final boolean matchesElement(XmlNode.QName qname) {
+ if (this.uri() == null || this.uri().equals(qname.getNamespace().getUri())) {
+ if (this.localName().equals("*") || this.localName().equals(qname.getLocalName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ final boolean matches(XML node) {
+ XmlNode.QName qname = node.getNodeQname();
+ String nodeUri = null;
+ if (qname.getNamespace() != null) {
+ nodeUri = qname.getNamespace().getUri();
+ }
+ if (isAttributeName) {
+ if (node.isAttribute()) {
+ if (this.uri() == null || this.uri().equals(nodeUri)) {
+ if (this.localName().equals("*") || this.localName().equals(qname.getLocalName())) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ // TODO Could throw exception maybe, should not call this method on attribute name with arbitrary node type
+ // unless we traverse all attributes and children habitually
+ return false;
+ }
+ } else {
+ if ( this.uri() == null || ((node.isElement()) && this.uri().equals(nodeUri)) ) {
+ if (localName().equals("*")) return true;
+ if (node.isElement()) {
+ if (localName().equals(qname.getLocalName())) return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /** @deprecated */
+ boolean isAttributeName() {
+ return isAttributeName;
+ }
+
+ // TODO Fix whether this is an attribute XMLName at construction?
+ /** @deprecated */
+ void setAttributeName() {
+// if (isAttributeName) throw new IllegalStateException();
+ isAttributeName = true;
+ }
+
+ /** @deprecated */
+ boolean isDescendants() {
+ return isDescendants;
+ }
+
+ // TODO Fix whether this is an descendant XMLName at construction?
+ /** @deprecated */
+ void setIsDescendants() {
+// if (isDescendants) throw new IllegalStateException();
+ isDescendants = true;
+ }
+}