From 89bda83e0570ab87c6e449f5955613d5385e90b3 Mon Sep 17 00:00:00 2001 From: "alexanders@b2ef00c0-3703-41da-baef-cfe82387ac0c" Date: Wed, 3 Feb 2010 00:50:41 +0000 Subject: removed obsolete svn folder from hg tree --HG-- extra : convert_revision : svn%3Ab2ef00c0-3703-41da-baef-cfe82387ac0c/trunk%408 --- .../org/mozilla/javascript/xmlimpl/XMLLibImpl.java | 606 +++++++++++++++++++++ 1 file changed, 606 insertions(+) create mode 100644 infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java (limited to 'infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java') diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java new file mode 100644 index 0000000..6d45240 --- /dev/null +++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java @@ -0,0 +1,606 @@ +/* -*- 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 + * David P. Caldwell + * + * 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 java.io.Serializable; + +import org.mozilla.javascript.*; +import org.mozilla.javascript.xml.*; + +public final class XMLLibImpl extends XMLLib implements Serializable { + // TODO Document that this only works with JDK 1.5 or backport its + // features to earlier versions + private static final long serialVersionUID = 1L; + + // + // EXPERIMENTAL Java interface + // + + /** + This experimental interface is undocumented. + */ + public static org.w3c.dom.Node toDomNode(Object xmlObject) { + // Could return DocumentFragment for XMLList + // Probably a single node for XMLList with one element + if (xmlObject instanceof XML) { + return ((XML)xmlObject).toDomNode(); + } else { + throw new IllegalArgumentException("xmlObject is not an XML object in JavaScript."); + } + } + + public static void init(Context cx, Scriptable scope, boolean sealed) { + XMLLibImpl lib = new XMLLibImpl(scope); + XMLLib bound = lib.bindToScope(scope); + if (bound == lib) { + lib.exportToScope(sealed); + } + } + + private Scriptable globalScope; + + private XML xmlPrototype; + private XMLList xmlListPrototype; + private Namespace namespacePrototype; + private QName qnamePrototype; + + private XmlProcessor options = new XmlProcessor(); + + private XMLLibImpl(Scriptable globalScope) { + this.globalScope = globalScope; + } + + /** @deprecated */ + QName qnamePrototype() { + return qnamePrototype; + } + + /** @deprecated */ + Scriptable globalScope() { + return globalScope; + } + + XmlProcessor getProcessor() { + return options; + } + + private void exportToScope(boolean sealed) { + xmlPrototype = newXML(XmlNode.createText(options, "")); + xmlListPrototype = newXMLList(); + namespacePrototype = Namespace.create(this.globalScope, null, XmlNode.Namespace.GLOBAL); + qnamePrototype = QName.create(this, this.globalScope, null, XmlNode.QName.create(XmlNode.Namespace.create(""), "")); + + xmlPrototype.exportAsJSClass(sealed); + xmlListPrototype.exportAsJSClass(sealed); + namespacePrototype.exportAsJSClass(sealed); + qnamePrototype.exportAsJSClass(sealed); + } + + /** @deprecated */ + XMLName toAttributeName(Context cx, Object nameValue) { + if (nameValue instanceof XMLName) { + // TODO Will this always be an XMLName of type attribute name? + return (XMLName)nameValue; + } else if (nameValue instanceof QName) { + return XMLName.create( ((QName)nameValue).getDelegate(), true, false ); + } else if (nameValue instanceof Boolean + || nameValue instanceof Number + || nameValue == Undefined.instance + || nameValue == null) { + throw badXMLName(nameValue); + } else { + // TODO Not 100% sure that putting these in global namespace is the right thing to do + String localName = null; + if (nameValue instanceof String) { + localName = (String)nameValue; + } else { + localName = ScriptRuntime.toString(nameValue); + } + if (localName != null && localName.equals("*")) localName = null; + return XMLName.create(XmlNode.QName.create(XmlNode.Namespace.create(""), localName), true, false); + } + } + + private static RuntimeException badXMLName(Object value) + { + String msg; + if (value instanceof Number) { + msg = "Can not construct XML name from number: "; + } else if (value instanceof Boolean) { + msg = "Can not construct XML name from boolean: "; + } else if (value == Undefined.instance || value == null) { + msg = "Can not construct XML name from "; + } else { + throw new IllegalArgumentException(value.toString()); + } + return ScriptRuntime.typeError(msg+ScriptRuntime.toString(value)); + } + + XMLName toXMLNameFromString(Context cx, String name) { + return XMLName.create( getDefaultNamespaceURI(cx), name ); + } + + /** @deprecated */ + XMLName toXMLName(Context cx, Object nameValue) { + XMLName result; + + if (nameValue instanceof XMLName) { + result = (XMLName)nameValue; + } else if (nameValue instanceof QName) { + QName qname = (QName)nameValue; + result = XMLName.formProperty(qname.uri(), qname.localName()); + } else if (nameValue instanceof String) { + result = toXMLNameFromString(cx, (String)nameValue); + } else if (nameValue instanceof Boolean + || nameValue instanceof Number + || nameValue == Undefined.instance + || nameValue == null) { + throw badXMLName(nameValue); + } else { + String name = ScriptRuntime.toString(nameValue); + result = toXMLNameFromString(cx, name); + } + + return result; + } + + /** + * If value represents Uint32 index, make it available through + * ScriptRuntime.lastUint32Result(cx) and return null. + * Otherwise return the same value as toXMLName(cx, value). + */ + XMLName toXMLNameOrIndex(Context cx, Object value) + { + XMLName result; + + if (value instanceof XMLName) { + result = (XMLName)value; + } else if (value instanceof String) { + String str = (String)value; + long test = ScriptRuntime.testUint32String(str); + if (test >= 0) { + ScriptRuntime.storeUint32Result(cx, test); + result = null; + } else { + result = toXMLNameFromString(cx, str); + } + } else if (value instanceof Number) { + double d = ((Number)value).doubleValue(); + long l = (long)d; + if (l == d && 0 <= l && l <= 0xFFFFFFFFL) { + ScriptRuntime.storeUint32Result(cx, l); + result = null; + } else { + throw badXMLName(value); + } + } else if (value instanceof QName) { + QName qname = (QName)value; + String uri = qname.uri(); + boolean number = false; + result = null; + if (uri != null && uri.length() == 0) { + // Only in this case qname.toString() can resemble uint32 + long test = ScriptRuntime.testUint32String(uri); + if (test >= 0) { + ScriptRuntime.storeUint32Result(cx, test); + number = true; + } + } + if (!number) { + result = XMLName.formProperty(uri, qname.localName()); + } + } else if (value instanceof Boolean + || value == Undefined.instance + || value == null) + { + throw badXMLName(value); + } else { + String str = ScriptRuntime.toString(value); + long test = ScriptRuntime.testUint32String(str); + if (test >= 0) { + ScriptRuntime.storeUint32Result(cx, test); + result = null; + } else { + result = toXMLNameFromString(cx, str); + } + } + + return result; + } + + Object addXMLObjects(Context cx, XMLObject obj1, XMLObject obj2) + { + XMLList listToAdd = newXMLList(); + + if (obj1 instanceof XMLList) { + XMLList list1 = (XMLList)obj1; + if (list1.length() == 1) { + listToAdd.addToList(list1.item(0)); + } else { + // Might be xmlFragment + xmlFragment + xmlFragment + ...; + // then the result will be an XMLList which we want to be an + // rValue and allow it to be assigned to an lvalue. + listToAdd = newXMLListFrom(obj1); + } + } else { + listToAdd.addToList(obj1); + } + + if (obj2 instanceof XMLList) { + XMLList list2 = (XMLList)obj2; + for (int i = 0; i < list2.length(); i++) { + listToAdd.addToList(list2.item(i)); + } + } else if (obj2 instanceof XML) { + listToAdd.addToList(obj2); + } + + return listToAdd; + } + + private Ref xmlPrimaryReference(Context cx, XMLName xmlName, Scriptable scope) { + XMLObjectImpl xmlObj; + XMLObjectImpl firstXml = null; + for (;;) { + // XML object can only present on scope chain as a wrapper + // of XMLWithScope + if (scope instanceof XMLWithScope) { + xmlObj = (XMLObjectImpl)scope.getPrototype(); + if (xmlObj.hasXMLProperty(xmlName)) { + break; + } + if (firstXml == null) { + firstXml = xmlObj; + } + } + scope = scope.getParentScope(); + if (scope == null) { + xmlObj = firstXml; + break; + } + } + + // xmlObj == null corresponds to undefined as the target of + // the reference + if (xmlObj != null) { + xmlName.initXMLObject(xmlObj); + } + return xmlName; + } + + Namespace castToNamespace(Context cx, Object namespaceObj) { + return this.namespacePrototype.castToNamespace(namespaceObj); + } + + private String getDefaultNamespaceURI(Context cx) { + return getDefaultNamespace(cx).uri(); + } + + Namespace newNamespace(String uri) { + return this.namespacePrototype.newNamespace(uri); + } + + Namespace getDefaultNamespace(Context cx) { + if (cx == null) { + cx = Context.getCurrentContext(); + if (cx == null) { + return namespacePrototype; + } + } + + Object ns = ScriptRuntime.searchDefaultNamespace(cx); + if (ns == null) { + return namespacePrototype; + } else { + if (ns instanceof Namespace) { + return (Namespace)ns; + } else { + // TODO Clarify or remove the following comment + // Should not happen but for now it could + // due to bad searchDefaultNamespace implementation. + return namespacePrototype; + } + } + } + + Namespace[] createNamespaces(XmlNode.Namespace[] declarations) { + Namespace[] rv = new Namespace[declarations.length]; + for (int i=0; i")) { + throw ScriptRuntime.typeError("Invalid use of XML object anonymous tags <>."); + } + + if (frag.indexOf("<") == -1) { + // Solo text node + return newXML(XmlNode.createText(options, frag)); + } + return parse(frag); + } + + private XML parse(String frag) { + try { + return newXML(XmlNode.createElement(options, getDefaultNamespaceURI(Context.getCurrentContext()), frag)); + } catch (org.xml.sax.SAXException e) { + throw ScriptRuntime.typeError("Cannot parse XML: " + e.getMessage()); + } + } + + final XML ecmaToXml(Object object) { + // See ECMA357 10.3 + if (object == null || object == Undefined.instance) throw ScriptRuntime.typeError("Cannot convert " + object + " to XML"); + if (object instanceof XML) return (XML)object; + if (object instanceof XMLList) { + XMLList list = (XMLList)object; + if (list.getXML() != null) { + return list.getXML(); + } else { + throw ScriptRuntime.typeError("Cannot convert list of >1 element to XML"); + } + } + // TODO Technically we should fail on anything except a String, Number or Boolean + // See ECMA357 10.3 + // Extension: if object is a DOM node, use that to construct the XML + // object. + if (object instanceof Wrapper) { + object = ((Wrapper) object).unwrap(); + } + if (object instanceof org.w3c.dom.Node) { + org.w3c.dom.Node node = (org.w3c.dom.Node) object; + return newXML(XmlNode.createElementFromNode(node)); + } + // Instead we just blindly cast to a String and let them convert anything. + String s = ScriptRuntime.toString(object); + // TODO Could this get any uglier? + if (s.length() > 0 && s.charAt(0) == '<') { + return parse(s); + } else { + return newXML(XmlNode.createText(options, s)); + } + } + + final XML newTextElementXML(XmlNode reference, XmlNode.QName qname, String value) { + return newXML(XmlNode.newElementWithText(options, reference, qname, value)); + } + + XMLList newXMLList() { + return new XMLList(this, this.globalScope, this.xmlListPrototype); + } + + final XMLList newXMLListFrom(Object inputObject) { + XMLList rv = newXMLList(); + + if (inputObject == null || inputObject instanceof Undefined) { + return rv; + } else if (inputObject instanceof XML) { + XML xml = (XML) inputObject; + rv.getNodeList().add(xml); + return rv; + } else if (inputObject instanceof XMLList) { + XMLList xmll = (XMLList) inputObject; + rv.getNodeList().add(xmll.getNodeList()); + return rv; + } else { + String frag = ScriptRuntime.toString(inputObject).trim(); + + if (!frag.startsWith("<>")) { + frag = "<>" + frag + ""; + } + + frag = "" + frag.substring(2); + if (!frag.endsWith("")) { + throw ScriptRuntime.typeError("XML with anonymous tag missing end anonymous tag"); + } + + frag = frag.substring(0, frag.length() - 3) + ""; + + XML orgXML = newXMLFromJs(frag); + + // Now orphan the children and add them to our XMLList. + XMLList children = orgXML.children(); + + for (int i = 0; i < children.getNodeList().length(); i++) { + // Copy here is so that they'll be orphaned (parent() will be undefined) + rv.getNodeList().add(((XML) children.item(i).copy())); + } + return rv; + } + } + + XmlNode.QName toNodeQName(Context cx, Object namespaceValue, Object nameValue) { + // This is duplication of constructQName(cx, namespaceValue, nameValue) + // but for XMLName + + String localName; + + if (nameValue instanceof QName) { + QName qname = (QName)nameValue; + localName = qname.localName(); + } else { + localName = ScriptRuntime.toString(nameValue); + } + + XmlNode.Namespace ns; + if (namespaceValue == Undefined.instance) { + if ("*".equals(localName)) { + ns = null; + } else { + ns = getDefaultNamespace(cx).getDelegate(); + } + } else if (namespaceValue == null) { + ns = null; + } else if (namespaceValue instanceof Namespace) { + ns = ((Namespace)namespaceValue).getDelegate(); + } else { + ns = this.namespacePrototype.constructNamespace(namespaceValue).getDelegate(); + } + + if (localName != null && localName.equals("*")) localName = null; + return XmlNode.QName.create(ns, localName); + } + + XmlNode.QName toNodeQName(Context cx, String name, boolean attribute) { + XmlNode.Namespace defaultNamespace = getDefaultNamespace(cx).getDelegate(); + if (name != null && name.equals("*")) { + return XmlNode.QName.create(null, null); + } else { + if (attribute) { + return XmlNode.QName.create(XmlNode.Namespace.GLOBAL, name); + } else { + return XmlNode.QName.create(defaultNamespace, name); + } + } + } + + /** + @deprecated Too general; this should be split into overloaded methods. + Is that possible? + */ + XmlNode.QName toNodeQName(Context cx, Object nameValue, boolean attribute) { + if (nameValue instanceof XMLName) { + return ((XMLName)nameValue).toQname(); + } else if (nameValue instanceof QName) { + QName qname = (QName)nameValue; + return qname.getDelegate(); + } else if ( + nameValue instanceof Boolean + || nameValue instanceof Number + || nameValue == Undefined.instance + || nameValue == null + ) { + throw badXMLName(nameValue); + } else { + String local = null; + if (nameValue instanceof String) { + local = (String)nameValue; + } else { + local = ScriptRuntime.toString(nameValue); + } + return toNodeQName(cx, local, attribute); + } + } + + // + // Override methods from XMLLib + // + + public boolean isXMLName(Context _cx, Object nameObj) { + return XMLName.accept(nameObj); + } + + public Object toDefaultXmlNamespace(Context cx, Object uriValue) { + return this.namespacePrototype.constructNamespace(uriValue); + } + + public String escapeTextValue(Object o) { + return options.escapeTextValue(o); + } + + public String escapeAttributeValue(Object o) { + return options.escapeAttributeValue(o); + } + + public Ref nameRef(Context cx, Object name, Scriptable scope, int memberTypeFlags) { + if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) == 0) { + // should only be called foir cases like @name or @[expr] + throw Kit.codeBug(); + } + XMLName xmlName = toAttributeName(cx, name); + return xmlPrimaryReference(cx, xmlName, scope); + } + + public Ref nameRef(Context cx, Object namespace, Object name, Scriptable scope, int memberTypeFlags) { + XMLName xmlName = XMLName.create(toNodeQName(cx, namespace, name), false, false); + + // No idea what is coming in from the parser in this case; is it detecting the "@"? + if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) { + if (!xmlName.isAttributeName()) { + xmlName.setAttributeName(); + } + } + + return xmlPrimaryReference(cx, xmlName, scope); + } +} -- cgit v1.2.3