diff options
author | Egil Moeller <egil.moller@freecode.no> | 2010-03-22 00:16:53 +0100 |
---|---|---|
committer | Egil Moeller <egil.moller@freecode.no> | 2010-03-22 00:16:53 +0100 |
commit | fc00cfedd6c25d1634a1e0d28a7b7bc5f42e1cd7 (patch) | |
tree | 928419d6bfe794865e4b8f0634bd792f795c4b8a /trunk/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XML.java | |
parent | 0fdab3db005c4fa31fb8306b573c0b35073d3e56 (diff) | |
parent | d56b9b3b82cdebcaeb00eec0fcb4326ad21adaa8 (diff) | |
download | etherpad-fc00cfedd6c25d1634a1e0d28a7b7bc5f42e1cd7.tar.gz etherpad-fc00cfedd6c25d1634a1e0d28a7b7bc5f42e1cd7.tar.xz etherpad-fc00cfedd6c25d1634a1e0d28a7b7bc5f42e1cd7.zip |
Merge branch 'master' into plugin-framework
Diffstat (limited to 'trunk/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XML.java')
-rw-r--r-- | trunk/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XML.java | 3092 |
1 files changed, 0 insertions, 3092 deletions
diff --git a/trunk/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XML.java b/trunk/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XML.java deleted file mode 100644 index c8818a5..0000000 --- a/trunk/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XML.java +++ /dev/null @@ -1,3092 +0,0 @@ -/* -*- 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): - * Ethan Hugg - * Terry Lucas - * Milen Nankov - * - * 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.xml.impl.xmlbeans; - -import java.io.Serializable; -import java.util.*; - -import org.mozilla.javascript.*; - -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlCursor.XmlBookmark; -import org.apache.xmlbeans.XmlCursor.TokenType; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; - -class XML extends XMLObjectImpl -{ - static final long serialVersionUID = -630969919086449092L; - - final static class XScriptAnnotation extends XmlBookmark implements Serializable - { - private static final long serialVersionUID = 1L; - - javax.xml.namespace.QName _name; - XML _xScriptXML; - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // Constructurs - // - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - XScriptAnnotation (XmlCursor curs) - { - _name = curs.getName(); - } - - } - - /** - * - */ - final static class NamespaceDeclarations - { - private int _prefixIdx; - private StringBuffer _namespaceDecls; - private String _defaultNSURI; - - - NamespaceDeclarations (XmlCursor curs) - { - _prefixIdx = 0; - _namespaceDecls = new StringBuffer(); - - skipNonElements(curs); - _defaultNSURI = curs.namespaceForPrefix(""); - - if (isAnyDefaultNamespace()) - { - addDecl("", _defaultNSURI); - } - } - - - private void addDecl (String prefix, String ns) - { - _namespaceDecls.append((prefix.length() > 0 ? - "declare namespace " + prefix : - "default element namespace") + - " = \"" + ns + "\"" + "\n"); - } - - - String getNextPrefix (String ns) - { - String prefix = "NS" + _prefixIdx++; - - _namespaceDecls.append("declare namespace " + prefix + " = " + "\"" + ns + "\"" + "\n"); - - return prefix; - } - - - boolean isAnyDefaultNamespace () - { - return _defaultNSURI != null ?_defaultNSURI.length() > 0 : false; - } - - - String getDeclarations() - { - return _namespaceDecls.toString(); - } - } - - // Fields - //static final XML prototype = new XML(); - private XScriptAnnotation _anno; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // Constructors - // - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * - * @param anno - */ - private XML(XMLLibImpl lib, XScriptAnnotation anno) - { - super(lib, lib.xmlPrototype); - _anno = anno; - _anno._xScriptXML = this; - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // Public factories for creating a XScript XML object given an XBean cursor. - // - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - - static XML createEmptyXML(XMLLibImpl lib) - { - XScriptAnnotation anno; - - XmlObject xo = XmlObject.Factory.newInstance(); - XmlCursor curs = xo.newCursor(); - try { - anno = new XScriptAnnotation(curs); - curs.setBookmark(anno); - } finally { - curs.dispose(); - } - - return new XML(lib, anno); - } - - private static XML createXML (XMLLibImpl lib, XmlCursor curs) - { - if (curs.currentTokenType().isStartdoc()) - { - curs.toFirstContentToken(); - } - - XScriptAnnotation anno = findAnnotation(curs); - - return new XML(lib, anno); - } - - /** - * Special constructor for making an attribute - * - */ - private static XML createAttributeXML(XMLLibImpl lib, XmlCursor cursor) - { - if (!cursor.isAttr()) - throw new IllegalArgumentException(); - - XScriptAnnotation anno = new XScriptAnnotation(cursor); - cursor.setBookmark(anno); - - return new XML(lib, anno); - } - - - /** - * - * @param qname - * @param value - * @return - */ - static XML createTextElement(XMLLibImpl lib, javax.xml.namespace.QName qname, String value) - { - XScriptAnnotation anno; - - XmlObject xo = XmlObject.Factory.newInstance(); - XmlCursor cursor = xo.newCursor(); - try { - cursor.toNextToken(); - - cursor.beginElement(qname.getLocalPart(), qname.getNamespaceURI()); - //if(namespace.length() > 0) - // cursor.insertNamespace("", namespace); - cursor.insertChars(value); - - cursor.toStartDoc(); - cursor.toNextToken(); - anno = new XScriptAnnotation(cursor); - cursor.setBookmark(anno); - } finally { - cursor.dispose(); - } - - return new XML(lib, anno); - } - - static XML createFromXmlObject(XMLLibImpl lib, XmlObject xo) - { - XScriptAnnotation anno; - XmlCursor curs = xo.newCursor(); - if (curs.currentTokenType().isStartdoc()) - { - curs.toFirstContentToken(); - } - try { - anno = new XScriptAnnotation(curs); - curs.setBookmark(anno); - } finally { - curs.dispose(); - } - return new XML(lib, anno); - } - - static XML createFromJS(XMLLibImpl lib, Object inputObject) - { - XmlObject xo; - boolean isText = false; - String frag; - - if (inputObject == null || inputObject == Undefined.instance) { - frag = ""; - } else if (inputObject instanceof XMLObjectImpl) { - // todo: faster way for XMLObjects? - frag = ((XMLObjectImpl) inputObject).toXMLString(0); - } else { - if (inputObject instanceof Wrapper) { - Object wrapped = ((Wrapper)inputObject).unwrap(); - if (wrapped instanceof XmlObject) { - return createFromXmlObject(lib, (XmlObject)wrapped); - } - } - frag = ScriptRuntime.toString(inputObject); - } - - if (frag.trim().startsWith("<>")) - { - throw ScriptRuntime.typeError("Invalid use of XML object anonymous tags <></>."); - } - - if (frag.indexOf("<") == -1) - { - // Must be solo text node, wrap in XML fragment - isText = true; - frag = "<textFragment>" + frag + "</textFragment>"; - } - - XmlOptions options = new XmlOptions(); - - if (lib.ignoreComments) - { - options.put(XmlOptions.LOAD_STRIP_COMMENTS); - } - - if (lib.ignoreProcessingInstructions) - { - options.put(XmlOptions.LOAD_STRIP_PROCINSTS); - } - - if (lib.ignoreWhitespace) - { - options.put(XmlOptions.LOAD_STRIP_WHITESPACE); - } - - try - { - xo = XmlObject.Factory.parse(frag, options); - - // Apply the default namespace - Context cx = Context.getCurrentContext(); - String defaultURI = lib.getDefaultNamespaceURI(cx); - - if(defaultURI.length() > 0) - { - XmlCursor cursor = xo.newCursor(); - boolean isRoot = true; - while(!cursor.toNextToken().isEnddoc()) - { - if(!cursor.isStart()) continue; - - // Check if this element explicitly sets the - // default namespace - boolean defaultNSDeclared = false; - cursor.push(); - while(cursor.toNextToken().isAnyAttr()) - { - if(cursor.isNamespace()) - { - if(cursor.getName().getLocalPart().length() == 0) - { - defaultNSDeclared = true; - break; - } - } - } - cursor.pop(); - if(defaultNSDeclared) - { - cursor.toEndToken(); - continue; - } - - // Check if this element's name is in no namespace - javax.xml.namespace.QName qname = cursor.getName(); - if(qname.getNamespaceURI().length() == 0) - { - // Change the namespace - qname = new javax.xml.namespace.QName(defaultURI, - qname.getLocalPart()); - cursor.setName(qname); - } - - if(isRoot) - { - // Declare the default namespace - cursor.push(); - cursor.toNextToken(); - cursor.insertNamespace("", defaultURI); - cursor.pop(); - - isRoot = false; - } - } - cursor.dispose(); - } - } - catch (XmlException xe) - { -/* -todo need to handle namespace prefix not found in XML look for namespace type in the scope change. - - String errorMsg = "Use of undefined namespace prefix: "; - String msg = xe.getError().getMessage(); - if (msg.startsWith(errorMsg)) - { - String prefix = msg.substring(errorMsg.length()); - } -*/ - String errMsg = xe.getMessage(); - if (errMsg.equals("error: Unexpected end of file after null")) - { - // Create an empty document. - xo = XmlObject.Factory.newInstance(); - } - else - { - throw ScriptRuntime.typeError(xe.getMessage()); - } - } - catch (Throwable e) - { - // todo: TLL Catch specific exceptions during parse. - throw ScriptRuntime.typeError("Not Parsable as XML"); - } - - XmlCursor curs = xo.newCursor(); - if (curs.currentTokenType().isStartdoc()) - { - curs.toFirstContentToken(); - } - - if (isText) - { - // Move it to point to the text node - curs.toFirstContentToken(); - } - - XScriptAnnotation anno; - try - { - anno = new XScriptAnnotation(curs); - curs.setBookmark(anno); - } - finally - { - curs.dispose(); - } - - return new XML(lib, anno); - } - - static XML getFromAnnotation(XMLLibImpl lib, XScriptAnnotation anno) - { - if (anno._xScriptXML == null) - { - anno._xScriptXML = new XML(lib, anno); - } - - return anno._xScriptXML; - } - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // Private functions: - // - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * - * @param curs - * @return - */ - private static TokenType skipNonElements (XmlCursor curs) - { - TokenType tt = curs.currentTokenType(); - while (tt.isComment() || tt.isProcinst()) - { - tt = curs.toNextToken(); - } - - return tt; - } - - /** - * - * @param curs - * @return - */ - protected static XScriptAnnotation findAnnotation(XmlCursor curs) - { - XmlBookmark anno = curs.getBookmark(XScriptAnnotation.class); - if (anno == null) - { - anno = new XScriptAnnotation(curs); - curs.setBookmark(anno); - } - - return (XScriptAnnotation)anno; - } - - /** - * - * @return - */ - private XmlOptions getOptions() - { - XmlOptions options = new XmlOptions(); - - if (lib.ignoreComments) - { - options.put(XmlOptions.LOAD_STRIP_COMMENTS); - } - - if (lib.ignoreProcessingInstructions) - { - options.put(XmlOptions.LOAD_STRIP_PROCINSTS); - } - - if (lib.ignoreWhitespace) - { - options.put(XmlOptions.LOAD_STRIP_WHITESPACE); - } - - if (lib.prettyPrinting) - { - options.put(XmlOptions.SAVE_PRETTY_PRINT, null); - options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, new Integer(lib.prettyIndent)); - } - - return options; - } - - - /** - * - * @param cursor - * @param opts - * @return - */ - private static String dumpNode(XmlCursor cursor, XmlOptions opts) - { - if (cursor.isText()) - return cursor.getChars(); - - if (cursor.isFinish()) - return ""; - - cursor.push(); - boolean wanRawText = cursor.isStartdoc() && !cursor.toFirstChild(); - cursor.pop(); - - return wanRawText ? cursor.getTextValue() : cursor.xmlText( opts ); - } - - /** - * - * @return - */ - private XmlCursor newCursor () - { - XmlCursor curs; - - if (_anno != null) - { - curs = _anno.createCursor(); - if (curs == null) - { - // Orphaned case. - XmlObject doc = XmlObject.Factory.newInstance(); - curs = doc.newCursor(); - - if (_anno._name != null) - { - curs.toNextToken(); - curs.insertElement(_anno._name); - curs.toPrevSibling(); - } - - curs.setBookmark(_anno); - } - } - else - { - XmlObject doc = XmlObject.Factory.newInstance(); - curs = doc.newCursor(); - } - - return curs; - } - - /* - * fUseStartDoc used by child(int index) the index is at startDoc is the element at the top-level - * otherwise we always want to drill in. - */ - private boolean moveToChild(XmlCursor curs, long index, boolean fFirstChild, boolean fUseStartDoc) - { - if (index < 0) - throw new IllegalArgumentException(); - - long idxChild = 0; - - if (!fUseStartDoc && curs.currentTokenType().isStartdoc()) - { - // We always move to the children of the top node. - // todo: This assumes that we want have multiple top-level nodes. Which we should be able tohave. - curs.toFirstContentToken(); - } - - TokenType tt = curs.toFirstContentToken(); - if (!tt.isNone() && !tt.isEnd()) - { - while (true) - { - if (index == idxChild) - { - return true; - } - - tt = curs.currentTokenType(); - if (tt.isText()) - { - curs.toNextToken(); - } - else if (tt.isStart()) - { - // Need to do this we want to be pointing at the text if that after the end token. - curs.toEndToken(); - curs.toNextToken(); - } - else if (tt.isComment() || tt.isProcinst()) - { - continue; - } - else - { - break; - } - - idxChild++; - } - } - else if (fFirstChild && index == 0) - { - // Drill into where first child would be. -// curs.toFirstContentToken(); - return true; - } - - return false; - } - - /** - * - * @return - */ - XmlCursor.TokenType tokenType() - { - XmlCursor.TokenType result; - - XmlCursor curs = newCursor(); - - if (curs.isStartdoc()) - { - curs.toFirstContentToken(); - } - - result = curs.currentTokenType(); - - curs.dispose(); - - return result; - } - /** - * - * @param srcCurs - * @param destCurs - * @param fDontMoveIfSame - * @return - */ - private boolean moveSrcToDest (XmlCursor srcCurs, XmlCursor destCurs, boolean fDontMoveIfSame) - { - boolean fMovedSomething = true; - TokenType tt; - do - { - if (fDontMoveIfSame && srcCurs.isInSameDocument(destCurs) && (srcCurs.comparePosition(destCurs) == 0)) - { - // If the source and destination are pointing at the same place then there's nothing to move. - fMovedSomething = false; - break; - } - - // todo ***TLL*** Use replaceContents (when added) and eliminate children removes (see above todo). - if (destCurs.currentTokenType().isStartdoc()) - { - destCurs.toNextToken(); - } - - // todo ***TLL*** Can Eric support notion of copy instead of me copying then moving??? - XmlCursor copyCurs = copy(srcCurs); - - copyCurs.moveXml(destCurs); - - copyCurs.dispose(); - - tt = srcCurs.currentTokenType(); - } while (!tt.isStart() && !tt.isEnd() && !tt.isEnddoc()); - - return fMovedSomething; - } - - /** - * - * @param cursToCopy - * @return - */ - private XmlCursor copy (XmlCursor cursToCopy) - { - XmlObject xo = XmlObject.Factory.newInstance(); - - XmlCursor copyCurs = null; - - if (cursToCopy.currentTokenType().isText()) - { - try - { - // Try just as a textnode, to do that we need to wrap the text in a special fragment tag - // that is not visible from the XmlCursor. - copyCurs = XmlObject.Factory.parse("<x:fragment xmlns:x=\"http://www.openuri.org/fragment\">" + - cursToCopy.getChars() + - "</x:fragment>").newCursor(); - if (!cursToCopy.toNextSibling()) - { - if (cursToCopy.currentTokenType().isText()) - { - cursToCopy.toNextToken(); // It's not an element it's text so skip it. - } - } - } - catch (Exception ex) - { - throw ScriptRuntime.typeError(ex.getMessage()); - } - } - else - { - copyCurs = xo.newCursor(); - copyCurs.toFirstContentToken(); - if (cursToCopy.currentTokenType() == XmlCursor.TokenType.STARTDOC) - { - cursToCopy.toNextToken(); - } - - cursToCopy.copyXml(copyCurs); - if (!cursToCopy.toNextSibling()) // If element skip element. - { - if (cursToCopy.currentTokenType().isText()) - { - cursToCopy.toNextToken(); // It's not an element it's text so skip it. - } - } - - } - - copyCurs.toStartDoc(); - copyCurs.toFirstContentToken(); - - return copyCurs; - } - - private static final int APPEND_CHILD = 1; - private static final int PREPEND_CHILD = 2; - - /** - * - * @param curs - * @param xmlToInsert - */ - private void insertChild(XmlCursor curs, Object xmlToInsert) - { - if (xmlToInsert == null || xmlToInsert instanceof Undefined) - { - // Do nothing - } - else if (xmlToInsert instanceof XmlCursor) - { - moveSrcToDest((XmlCursor)xmlToInsert, curs, true); - } - else if (xmlToInsert instanceof XML) - { - XML xmlValue = (XML) xmlToInsert; - - // If it's an attribute, then change to text node - if (xmlValue.tokenType() == XmlCursor.TokenType.ATTR) - { - insertChild(curs, xmlValue.toString()); - } - else - { - XmlCursor cursToInsert = ((XML) xmlToInsert).newCursor(); - - moveSrcToDest(cursToInsert, curs, true); - - cursToInsert.dispose(); - } - } - else if (xmlToInsert instanceof XMLList) - { - XMLList list = (XMLList) xmlToInsert; - - for (int i = 0; i < list.length(); i++) - { - insertChild(curs, list.item(i)); - } - } - else - { - // Convert to string and make XML out of it - String xmlStr = ScriptRuntime.toString(xmlToInsert); - XmlObject xo = XmlObject.Factory.newInstance(); // Create an empty document. - - XmlCursor sourceCurs = xo.newCursor(); - sourceCurs.toNextToken(); - - // To hold the text. - sourceCurs.insertChars(xmlStr); - - sourceCurs.toPrevToken(); - - // Call us again with the cursor. - moveSrcToDest(sourceCurs, curs, true); - } - } - - /** - * - * @param childToMatch - * @param xmlToInsert - * @param addToType - */ - private void insertChild(XML childToMatch, Object xmlToInsert, int addToType) - { - XmlCursor curs = newCursor(); - TokenType tt = curs.currentTokenType(); - XmlCursor xmlChildCursor = childToMatch.newCursor(); - - if (tt.isStartdoc()) - { - tt = curs.toFirstContentToken(); - } - - if (tt.isContainer()) - { - tt = curs.toNextToken(); - - while (!tt.isEnd()) - { - if (tt.isStart()) - { - // See if this child is the same as the one thep passed in - if (curs.comparePosition(xmlChildCursor) == 0) - { - // Found it - if (addToType == APPEND_CHILD) - { - // Move the cursor to just past the end of this element - curs.toEndToken(); - curs.toNextToken(); - } - - insertChild(curs, xmlToInsert); - break; - } - } - - // Skip over child elements - if (tt.isStart()) - { - tt = curs.toEndToken(); - } - - tt = curs.toNextToken(); - } - - } - - xmlChildCursor.dispose(); - curs.dispose(); - } - - /** - * - * @param curs - */ - protected void removeToken (XmlCursor curs) - { - XmlObject xo = XmlObject.Factory.newInstance(); - - // Don't delete anything move to another document so it gets orphaned nicely. - XmlCursor tmpCurs = xo.newCursor(); - tmpCurs.toFirstContentToken(); - - - curs.moveXml(tmpCurs); - - tmpCurs.dispose(); - } - - /** - * - * @param index - */ - protected void removeChild(long index) - { - XmlCursor curs = newCursor(); - - if (moveToChild(curs, index, false, false)) - { - removeToken(curs); - } - - curs.dispose(); - } - - /** - * - * @param name - * @return - */ - protected static javax.xml.namespace.QName computeQName (Object name) - { - if (name instanceof String) - { - String ns = null; - String localName = null; - - String fullName = (String)name; - localName = fullName; - if (fullName.startsWith("\"")) - { - int idx = fullName.indexOf(":"); - if (idx != -1) - { - ns = fullName.substring(1, idx - 1); // Don't include the "" around the namespace - localName = fullName.substring(idx + 1); - } - } - - if (ns == null) - { - return new javax.xml.namespace.QName(localName); - } - else - { - return new javax.xml.namespace.QName(ns, localName); - } - } - - return null; - } - - /** - * - * @param destCurs - * @param newValue - */ - private void replace(XmlCursor destCurs, XML newValue) - { - if (destCurs.isStartdoc()) - { - // Can't overwrite a whole document (user really wants to overwrite the contents of). - destCurs.toFirstContentToken(); - } - - // Orphan the token -- don't delete it outright on the XmlCursor. - removeToken(destCurs); - - XmlCursor srcCurs = newValue.newCursor(); - if (srcCurs.currentTokenType().isStartdoc()) - { - // Cann't append a whole document (user really wants to append the contents of). - srcCurs.toFirstContentToken(); - } - - moveSrcToDest(srcCurs, destCurs, false); - - // Re-link a new annotation to this cursor -- we just deleted the previous annotation on entrance to replace. - if (!destCurs.toPrevSibling()) - { - destCurs.toPrevToken(); - } - destCurs.setBookmark(new XScriptAnnotation(destCurs)); - - // todo would be nice if destCurs.toNextSibling went to where the next token if the cursor was pointing at the last token in the stream. - destCurs.toEndToken(); - destCurs.toNextToken(); - - srcCurs.dispose(); - } - - /** - * - * @param currXMLNode - * @param xmlValue - * @return - */ - private boolean doPut(XMLName name, XML currXMLNode, XMLObjectImpl xmlValue) - { - boolean result = false; - XmlCursor curs = currXMLNode.newCursor(); - - try - { - // Replace the node with this new xml value. - XML xml; - - int toAssignLen = xmlValue.length(); - - for (int i = 0; i < toAssignLen; i++) - { - if (xmlValue instanceof XMLList) - { - xml = ((XMLList) xmlValue).item(i); - } - else - { - xml = (XML) xmlValue; - } - - // If it's an attribute or text node, make text node. - XmlCursor.TokenType tt = xml.tokenType(); - if (tt == XmlCursor.TokenType.ATTR || tt == XmlCursor.TokenType.TEXT) - { - xml = makeXmlFromString(lib, name, xml.toString()); - } - - if (i == 0) - { - // 1st assignment is replaceChild all others are appendChild - replace(curs, xml); - } - else - { - insertChild(curs, xml); - } - } - - // We're done we've blown away the node because the rvalue was XML... - result = true; - } - catch (Exception ex) - { - ex.printStackTrace(); - throw ScriptRuntime.typeError(ex.getMessage()); - } - finally - { - curs.dispose(); - } - - return result; - } - - /** - * Make a text node element with this element name and text value. - * - * @param name - * @param value - * @return - */ - private XML makeXmlFromString(XMLLibImpl lib, XMLName name, - String value) - { - XML result; - - javax.xml.namespace.QName qname; - - try - { - qname = new javax.xml.namespace.QName(name.uri(), name.localName()); - } - catch(Exception e) - { - throw ScriptRuntime.typeError(e.getMessage()); - } - - result = createTextElement(lib, qname, value); - - return result; - } - - /** - * - * @param name - * @return - */ - private XMLList matchAttributes(XMLName xmlName) - { - XMLList result = new XMLList(lib); - XmlCursor curs = newCursor(); - - if (curs.currentTokenType().isStartdoc()) - { - curs.toFirstContentToken(); - } - - if (curs.isStart()) - { - if (curs.toFirstAttribute()) - { - do - { - if (qnameMatches(xmlName, curs.getName())) - { - result.addToList(createAttributeObject(curs)); - } - } while (curs.toNextAttribute()); - } - } - - curs.dispose(); - - return result; - } - - /** - * - * @param attrCurs - * @return - */ - private XML createAttributeObject (XmlCursor attrCurs) - { - XML result = null; - - if (attrCurs.currentTokenType().isAttr()) - { - result = createAttributeXML(lib, attrCurs); - } - - return result; - } - - // - // - // methods overriding ScriptableObject - // - // - - public String getClassName () - { - return "XML"; - } - - // - // - // methods overriding IdScriptableObject - // - // - - /** - * XML[0] should return this, all other indexes are Undefined - * - * @param index - * @param start - * @return - */ - public Object get(int index, Scriptable start) - { - //Log("get index: " + index); - - if (index == 0) - { - return this; - } - else - { - return Scriptable.NOT_FOUND; - } - } - - /** - * Does the named property exist - * - * @param name - * @param start - * @return - */ - boolean hasXMLProperty(XMLName xmlName) - { - boolean result = false; - - if (prototypeFlag) - { - String name = xmlName.localName(); - - if (getMethod(name) != NOT_FOUND) - { - result = true; - } - } - else - { - // Has now should return true if the property would have results > 0 or - // if it's a method name - String name = xmlName.localName(); - if ((getPropertyList(xmlName).length() > 0) || - (getMethod(name) != NOT_FOUND)) - { - result = true; - } - } - - return result; - } - - - /** - * - * @param index - * @param start - * @return - */ - public boolean has(int index, Scriptable start) - { - return (index == 0); - } - - /** - * - * @return - */ - public Object[] getIds() - { - Object[] enumObjs; - - if (prototypeFlag) - { - enumObjs = new Object[0]; - } - else - { - enumObjs = new Object[1]; - - enumObjs[0] = new Integer(0); - } - - return enumObjs; - } - - - /** - * - * @return - */ - public Object [] getIdsForDebug() - { - return getIds(); - } - - /** - * - * @param name - * @param start - * @return - */ - Object getXMLProperty(XMLName xmlName) - { - Object result = NOT_FOUND; - - if (prototypeFlag) - { - String name = xmlName.localName(); - - result = getMethod(name); - } - else - { - result = getPropertyList(xmlName); - } - - return result; - } - - /** - * - * @param name - * @param start - * @param value - */ - void putXMLProperty(XMLName xmlName, Object value) - { - //Log("put property: " + name + " value: " + value.getClass()); - - if (prototypeFlag) - { - } - else - { - // Special-case checks for undefined and null - if (value == null) - { - value = "null"; - } - else if (value instanceof Undefined) - { - value = "undefined"; - } - - // Get the named property - if (xmlName.isAttributeName()) - { - setAttribute(xmlName, value); - } - else if (xmlName.uri() == null && - xmlName.localName().equals("*")) - { - 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).tokenType() == XmlCursor.TokenType.ATTR) - { - xmlValue = makeXmlFromString(lib, xmlName, xmlValue.toString()); - } - } - - if (xmlValue instanceof XMLList) - { - for (int i = 0; i < xmlValue.length(); i++) - { - XML xml = ((XMLList) xmlValue).item(i); - - if (xml.tokenType() == XmlCursor.TokenType.ATTR) - { - ((XMLList) xmlValue).replace(i, makeXmlFromString(lib, xmlName, xml.toString())); - } - } - } - } - else - { - xmlValue = makeXmlFromString(lib, xmlName, ScriptRuntime.toString(value)); - } - - XMLList matches = getPropertyList(xmlName); - - if (matches.length() == 0) - { - appendChild(xmlValue); - } - else - { - // Remove all other matches - for (int i = 1; i < matches.length(); i++) - { - removeChild(matches.item(i).childIndex()); - } - - // Replace first match with new value. - doPut(xmlName, matches.item(0), xmlValue); - } - } - } - } - - - /** - * - * @param index - * @param start - * @param value - */ - public void put(int index, Scriptable start, Object value) - { - // Spec says assignment to indexed XML object should return type error - throw ScriptRuntime.typeError("Assignment to indexed XML is not allowed"); - } - - - /** - * - * @param name - */ - void deleteXMLProperty(XMLName name) - { - if (!name.isDescendants() && name.isAttributeName()) - { - XmlCursor curs = newCursor(); - - // TODO: Cover the case *::name - if (name.localName().equals("*")) - { - // Delete all attributes. - if (curs.toFirstAttribute()) - { - while (curs.currentTokenType().isAttr()) - { - curs.removeXml(); - } - } - } - else - { - // Delete an attribute. - javax.xml.namespace.QName qname = new javax.xml.namespace.QName( - name.uri(), name.localName()); - curs.removeAttribute(qname); - } - - curs.dispose(); - } - else - { - XMLList matches = getPropertyList(name); - - matches.remove(); - } - } - - - /** - * - * @param index - */ - public void delete(int index) - { - if (index == 0) - { - remove(); - } - } - - // - // - // package utility functions: - // - // - - protected XScriptAnnotation getAnnotation () - { return _anno; } - - - protected void changeNS (String oldURI, String newURI) - { - XmlCursor curs = newCursor(); - while (curs.toParent()) { - /* Goto the top of the document */ - } - - TokenType tt = curs.currentTokenType(); - if (tt.isStartdoc()) - { - tt = curs.toFirstContentToken(); - } - - if (tt.isStart()) - { - do - { - if (tt.isStart() || tt.isAttr() || tt.isNamespace()) - { - javax.xml.namespace.QName currQName = curs.getName(); - if (oldURI.equals(currQName.getNamespaceURI())) - { - curs.setName(new javax.xml.namespace.QName(newURI, currQName.getLocalPart())); - } - } - - tt = curs.toNextToken(); - } while (!tt.isEnddoc() && !tt.isNone()); - } - - curs.dispose(); - } - - - /** - * - */ - void remove () - { - XmlCursor childCurs = newCursor(); - - if (childCurs.currentTokenType().isStartdoc()) - { - // Remove on the document removes all children. - TokenType tt = childCurs.toFirstContentToken(); - while (!tt.isEnd() && !tt.isEnddoc()) - { - removeToken(childCurs); - tt = childCurs.currentTokenType(); // Now see where we're pointing after the delete -- next token. - } - } - else - { - removeToken(childCurs); - } - - childCurs.dispose(); - } - - - /** - * - * @param value - */ - void replaceAll(XML value) - { - XmlCursor curs = newCursor(); - - replace(curs, value); - _anno = value._anno; - - curs.dispose(); - } - - - /** - * - * @param attrName - * @param value - */ - void setAttribute(XMLName xmlName, Object value) - { - if (xmlName.uri() == null && - xmlName.localName().equals("*")) - { - throw ScriptRuntime.typeError("@* assignment not supported."); - } - - XmlCursor curs = newCursor(); - - String strValue = ScriptRuntime.toString(value); - if (curs.currentTokenType().isStartdoc()) - { - curs.toFirstContentToken(); - } - - javax.xml.namespace.QName qName; - - try - { - qName = new javax.xml.namespace.QName(xmlName.uri(), xmlName.localName()); - } - catch(Exception e) - { - throw ScriptRuntime.typeError(e.getMessage()); - } - - if (!curs.setAttributeText(qName, strValue)) - { - if (curs.currentTokenType().isStart()) - { - // Can only add attributes inside of a start. - curs.toNextToken(); - } - curs.insertAttributeWithValue(qName, strValue); - } - - curs.dispose(); - } - - /** - * - * @param namespace - * @return - */ - private XMLList allChildNodes(String namespace) - { - XMLList result = new XMLList(lib); - XmlCursor curs = newCursor(); - TokenType tt = curs.currentTokenType(); - javax.xml.namespace.QName targetProperty = new javax.xml.namespace.QName(namespace, "*"); - - if (tt.isStartdoc()) - { - tt = curs.toFirstContentToken(); - } - - if (tt.isContainer()) - { - tt = curs.toFirstContentToken(); - - while (!tt.isEnd()) - { - if (!tt.isStart()) - { - // Not an element - result.addToList(findAnnotation(curs)); - - // Reset target property to null in this case - targetProperty = null; - } - else - { - // Match namespace as well if specified - if (namespace == null || - namespace.length() == 0 || - namespace.equals("*") || - curs.getName().getNamespaceURI().equals(namespace)) - { - // Add it to the list - result.addToList(findAnnotation(curs)); - - // Set target property if target name is "*", - // Otherwise if target property does not match current, then - // set to null - if (targetProperty != null) - { - if (targetProperty.getLocalPart().equals("*")) - { - targetProperty = curs.getName(); - } - else if (!targetProperty.getLocalPart().equals(curs.getName().getLocalPart())) - { - // Not a match, unset target property - targetProperty = null; - } - } - } - } - - // Skip over child elements - if (tt.isStart()) - { - tt = curs.toEndToken(); - } - - tt = curs.toNextToken(); - } - } - - curs.dispose(); - - // Set the targets for this XMLList. - result.setTargets(this, targetProperty); - - return result; - } - - /** - * - * @return - */ - private XMLList matchDescendantAttributes(XMLName xmlName) - { - XMLList result = new XMLList(lib); - XmlCursor curs = newCursor(); - TokenType tt = curs.currentTokenType(); - - // Set the targets for this XMLList. - result.setTargets(this, null); - - if (tt.isStartdoc()) - { - tt = curs.toFirstContentToken(); - } - - if (tt.isContainer()) - { - int nestLevel = 1; - - while (nestLevel > 0) - { - tt = curs.toNextToken(); - - // Only try to match names for attributes - if (tt.isAttr()) - { - if (qnameMatches(xmlName, curs.getName())) - { - result.addToList(findAnnotation(curs)); - } - } - - if (tt.isStart()) - { - nestLevel++; - } - else if (tt.isEnd()) - { - nestLevel--; - } - else if (tt.isEnddoc()) - { - // Shouldn't get here, but just in case. - break; - } - } - } - - curs.dispose(); - - return result; - } - - /** - * - * @return - */ - private XMLList matchDescendantChildren(XMLName xmlName) - { - XMLList result = new XMLList(lib); - XmlCursor curs = newCursor(); - TokenType tt = curs.currentTokenType(); - - // Set the targets for this XMLList. - result.setTargets(this, null); - - if (tt.isStartdoc()) - { - tt = curs.toFirstContentToken(); - } - - if (tt.isContainer()) - { - int nestLevel = 1; - - while (nestLevel > 0) - { - tt = curs.toNextToken(); - - if (!tt.isAttr() && !tt.isEnd() && !tt.isEnddoc()) - { - // Only try to match names for elements or processing instructions. - if (!tt.isStart() && !tt.isProcinst()) - { - // Not an element or procinst, only add if qname is all - if (xmlName.localName().equals("*")) - { - result.addToList(findAnnotation(curs)); - } - } - else - { - if (qnameMatches(xmlName, curs.getName())) - { - result.addToList(findAnnotation(curs)); - } - } - } - - if (tt.isStart()) - { - nestLevel++; - } - else if (tt.isEnd()) - { - nestLevel--; - } - else if (tt.isEnddoc()) - { - // Shouldn't get here, but just in case. - break; - } - } - } - - curs.dispose(); - - return result; - } - - /** - * - * @param tokenType - * @return - */ - private XMLList matchChildren(XmlCursor.TokenType tokenType) - { - return matchChildren(tokenType, XMLName.formStar()); - } - - /** - * - * @return - */ - private XMLList matchChildren(XmlCursor.TokenType tokenType, XMLName name) - { - XMLList result = new XMLList(lib); - XmlCursor curs = newCursor(); - TokenType tt = curs.currentTokenType(); - javax.xml.namespace.QName qname = new javax.xml.namespace.QName(name.uri(), name.localName()); - javax.xml.namespace.QName targetProperty = qname; - - if (tt.isStartdoc()) - { - tt = curs.toFirstContentToken(); - } - - if (tt.isContainer()) - { - tt = curs.toFirstContentToken(); - - while (!tt.isEnd()) - { - if (tt == tokenType) - { - // Only try to match names for elements or processing instructions. - if (!tt.isStart() && !tt.isProcinst()) - { - // Not an element or no name specified. - result.addToList(findAnnotation(curs)); - - // Reset target property to null in this case - targetProperty = null; - } - else - { - // Match names as well - if (qnameMatches(name, curs.getName())) - { - // Add it to the list - result.addToList(findAnnotation(curs)); - - // Set target property if target name is "*", - // Otherwise if target property does not match current, then - // set to null - if (targetProperty != null) - { - if (targetProperty.getLocalPart().equals("*")) - { - targetProperty = curs.getName(); - } - else if (!targetProperty.getLocalPart().equals(curs.getName().getLocalPart())) - { - // Not a match, unset target property - targetProperty = null; - } - } - } - } - } - - // Skip over child elements - if (tt.isStart()) - { - tt = curs.toEndToken(); - } - - tt = curs.toNextToken(); - } - } - - curs.dispose(); - - if (tokenType == XmlCursor.TokenType.START) - { - // Set the targets for this XMLList. - result.setTargets(this, targetProperty); - } - - return result; - - } - - /** - * - * @param template - * @param match - * @return - */ - private boolean qnameMatches(XMLName template, javax.xml.namespace.QName match) - { - boolean matches = false; - - if (template.uri() == null || - template.uri().equals(match.getNamespaceURI())) - { - // URI OK, test name - if (template.localName().equals("*") || - template.localName().equals(match.getLocalPart())) - { - matches = true; - } - } - - return matches; - } - - // - // - // Methods from section 12.4.4 in the spec - // - // - - /** - * The addNamespace method adds a namespace declaration to the in scope - * namespaces for this XML object and returns this XML object. - * - * @param toAdd - */ - XML addNamespace(Namespace ns) - { - // When a namespace is used it will be added automatically - // to the inScopeNamespaces set. There is no need to add - // Namespaces with undefined prefixes. - String nsPrefix = ns.prefix(); - if (nsPrefix == null) return this; - - XmlCursor cursor = newCursor(); - - try - { - if(!cursor.isContainer()) return this; - - javax.xml.namespace.QName qname = cursor.getName(); - // Don't add a default namespace declarations to containers - // with QNames in no namespace. - if(qname.getNamespaceURI().equals("") && - nsPrefix.equals("")) return this; - - // Get all declared namespaces that are in scope - Map prefixToURI = NamespaceHelper.getAllNamespaces(lib, cursor); - - String uri = (String)prefixToURI.get(nsPrefix); - if(uri != null) - { - // Check if the Namespace is not already in scope - if(uri.equals(ns.uri())) return this; - - cursor.push(); - - // Let's see if we have to delete a namespace declaration - while(cursor.toNextToken().isAnyAttr()) - { - if(cursor.isNamespace()) - { - qname = cursor.getName(); - String prefix = qname.getLocalPart(); - if(prefix.equals(nsPrefix)) - { - // Delete the current Namespace declaration - cursor.removeXml(); - break; - } - } - } - - cursor.pop(); - } - - cursor.toNextToken(); - cursor.insertNamespace(nsPrefix, ns.uri()); - } - finally - { - cursor.dispose(); - } - - return this; - } - - /** - * - * @param xml - * @return - */ - XML appendChild(Object xml) - { - XmlCursor curs = newCursor(); - - if (curs.isStartdoc()) - { - curs.toFirstContentToken(); - } - - // Move the cursor to the end of this element - if (curs.isStart()) - { - curs.toEndToken(); - } - - insertChild(curs, xml); - - curs.dispose(); - - return this; - } - - /** - * - * @param name - * @return - */ - XMLList attribute(XMLName xmlName) - { - return matchAttributes(xmlName); - } - - /** - * - * @return - */ - XMLList attributes() - { - XMLName xmlName = XMLName.formStar(); - return matchAttributes(xmlName); - } - - XMLList child(long index) - { - XMLList result = new XMLList(lib); - result.setTargets(this, null); - result.addToList(getXmlChild(index)); - return result; - } - - XMLList child(XMLName xmlName) - { - if (xmlName == null) - return new XMLList(lib); - - XMLList result; - if (xmlName.localName().equals("*")) - { - result = allChildNodes(xmlName.uri()); - } - else - { - result = matchChildren(XmlCursor.TokenType.START, xmlName); - } - - return result; - } - - /** - * - * @param index - * @return - */ - XML getXmlChild(long index) - { - XML result = null; - XmlCursor curs = newCursor(); - - if (moveToChild(curs, index, false, true)) - { - result = createXML(lib, curs); - } - - curs.dispose(); - - return result; - } - - /** - * - * @return - */ - int childIndex() - { - int index = 0; - - XmlCursor curs = newCursor(); - - TokenType tt = curs.currentTokenType(); - while (true) - { - if (tt.isText()) - { - index++; - if (!curs.toPrevSibling()) - { - break; - } - } - else if (tt.isStart()) - { - tt = curs.toPrevToken(); - if (tt.isEnd()) - { - curs.toNextToken(); - if (!curs.toPrevSibling()) - { - break; - } - - index++; - } - else - { - // Hit the parent start tag so get out we're down counting children. - break; - } - } - else if (tt.isComment() || tt.isProcinst()) - { - curs.toPrevToken(); - } - else - { - break; - } - - tt = curs.currentTokenType(); - } - - index = curs.currentTokenType().isStartdoc() ? -1 : index; - - curs.dispose(); - - return index; - } - - /** - * - * @return - */ - XMLList children() - { - return allChildNodes(null); - } - - /** - * - * @return - */ - XMLList comments() - { - return matchChildren(XmlCursor.TokenType.COMMENT); - } - - /** - * - * @param xml - * @return - */ - boolean contains(Object xml) - { - boolean result = false; - - if (xml instanceof XML) - { - result = equivalentXml(xml); - } - - return result; - } - - /** - * - * @return - */ - Object copy() - { - XmlCursor srcCurs = newCursor(); - - if (srcCurs.isStartdoc()) - { - srcCurs.toFirstContentToken(); - } - - XML xml = createEmptyXML(lib); - - XmlCursor destCurs = xml.newCursor(); - destCurs.toFirstContentToken(); - - srcCurs.copyXml(destCurs); - - destCurs.dispose(); - srcCurs.dispose(); - - return xml; - } - - /** - * - * @param name - * @return - */ - XMLList descendants(XMLName xmlName) - { - XMLList result; - if (xmlName.isAttributeName()) - { - result = matchDescendantAttributes(xmlName); - } - else - { - result = matchDescendantChildren(xmlName); - } - - return result; - } - - /** - * The inScopeNamespaces method returns an Array of Namespace objects - * representing the namespaces in scope for this XML object in the - * context of its parent. - * - * @return Array of all Namespaces in scope for this XML Object. - */ - Object[] inScopeNamespaces() - { - XmlCursor cursor = newCursor(); - Object[] namespaces = NamespaceHelper.inScopeNamespaces(lib, cursor); - cursor.dispose(); - return namespaces; - } - - /** - * - * @param child - * @param xml - */ - XML insertChildAfter(Object child, Object xml) - { - if (child == null) - { - // Spec says inserting after nothing is the same as prepending - prependChild(xml); - } - else if (child instanceof XML) - { - insertChild((XML) child, xml, APPEND_CHILD); - } - - return this; - } - - /** - * - * @param child - * @param xml - */ - XML insertChildBefore(Object child, Object xml) - { - if (child == null) - { - // Spec says inserting before nothing is the same as appending - appendChild(xml); - } - else if (child instanceof XML) - { - insertChild((XML) child, xml, PREPEND_CHILD); - } - - return this; - } - - /** - * - * @return - */ - boolean hasOwnProperty(XMLName xmlName) - { - boolean hasProperty = false; - - if (prototypeFlag) - { - String property = xmlName.localName(); - hasProperty = (0 != findPrototypeId(property)); - } - else - { - hasProperty = (getPropertyList(xmlName).length() > 0); - } - - return hasProperty; - } - - /** - * - * @return - */ - boolean hasComplexContent() - { - return !hasSimpleContent(); - } - - /** - * - * @return - */ - boolean hasSimpleContent() - { - boolean simpleContent = false; - - XmlCursor curs = newCursor(); - - if (curs.isAttr() || curs.isText()) { - return true; - } - - if (curs.isStartdoc()) - { - curs.toFirstContentToken(); - } - - simpleContent = !(curs.toFirstChild()); - - curs.dispose(); - - return simpleContent; - } - - /** - * Length of an XML object is always 1, it's a list of XML objects of size 1. - * - * @return - */ - int length() - { - return 1; - } - - /** - * - * @return - */ - String localName() - { - XmlCursor cursor = newCursor(); - if (cursor.isStartdoc()) - cursor.toFirstContentToken(); - - String name = null; - - if(cursor.isStart() || - cursor.isAttr() || - cursor.isProcinst()) - { - javax.xml.namespace.QName qname = cursor.getName(); - name = qname.getLocalPart(); - } - cursor.dispose(); - - return name; - } - - /** - * The name method returns the qualified name associated with this XML object. - * - * @return The qualified name associated with this XML object. - */ - QName name() - { - XmlCursor cursor = newCursor(); - if (cursor.isStartdoc()) - cursor.toFirstContentToken(); - - QName name = null; - - if(cursor.isStart() || - cursor.isAttr() || - cursor.isProcinst()) - { - javax.xml.namespace.QName qname = cursor.getName(); - if(cursor.isProcinst()) - { - name = new QName(lib, "", qname.getLocalPart(), ""); - } - else - { - String uri = qname.getNamespaceURI(); - String prefix = qname.getPrefix(); - name = new QName(lib, uri, qname.getLocalPart(), prefix); - } - } - - cursor.dispose(); - - return name; - } - - /** - * - * @param prefix - * @return - */ - Object namespace(String prefix) - { - XmlCursor cursor = newCursor(); - if (cursor.isStartdoc()) - { - cursor.toFirstContentToken(); - } - - Object result = null; - - if (prefix == null) - { - if(cursor.isStart() || - cursor.isAttr()) - { - Object[] inScopeNS = NamespaceHelper.inScopeNamespaces(lib, cursor); - // XXX Is it reaaly necessary to create the second cursor? - XmlCursor cursor2 = newCursor(); - if (cursor2.isStartdoc()) - cursor2.toFirstContentToken(); - - result = NamespaceHelper.getNamespace(lib, cursor2, inScopeNS); - - cursor2.dispose(); - } - } - else - { - Map prefixToURI = NamespaceHelper.getAllNamespaces(lib, cursor); - String uri = (String)prefixToURI.get(prefix); - result = (uri == null) ? Undefined.instance : new Namespace(lib, prefix, uri); - } - - cursor.dispose(); - - return result; - } - - /** - * - * @return - */ - Object[] namespaceDeclarations() - { - XmlCursor cursor = newCursor(); - Object[] namespaces = NamespaceHelper.namespaceDeclarations(lib, cursor); - cursor.dispose(); - return namespaces; - } - - /** - * - * @return - */ - Object nodeKind() - { - String result; - XmlCursor.TokenType tt = tokenType(); - - if (tt == XmlCursor.TokenType.ATTR) - { - result = "attribute"; - } - else if (tt == XmlCursor.TokenType.TEXT) - { - result = "text"; - } - else if (tt == XmlCursor.TokenType.COMMENT) - { - result = "comment"; - } - else if (tt == XmlCursor.TokenType.PROCINST) - { - result = "processing-instruction"; - } - else if (tt == XmlCursor.TokenType.START) - { - result = "element"; - } - else - { - // A non-existant node has the nodeKind() of text - result = "text"; - } - - return result; - } - - /** - * - */ - void normalize() - { - XmlCursor curs = newCursor(); - TokenType tt = curs.currentTokenType(); - - // Walk through the tokens removing empty text nodes and merging adjacent text nodes. - if (tt.isStartdoc()) - { - tt = curs.toFirstContentToken(); - } - - if (tt.isContainer()) - { - int nestLevel = 1; - String previousText = null; - - while (nestLevel > 0) - { - tt = curs.toNextToken(); - - if (tt == XmlCursor.TokenType.TEXT) - { - String currentText = curs.getChars().trim(); - - if (currentText.trim().length() == 0) - { - // Empty text node, remove. - removeToken(curs); - curs.toPrevToken(); - } - else if (previousText == null) - { - // No previous text node, reset to trimmed version - previousText = currentText; - } - else - { - // It appears that this case never happens with XBeans. - // Previous text node exists, concatenate - String newText = previousText + currentText; - - curs.toPrevToken(); - removeToken(curs); - removeToken(curs); - curs.insertChars(newText); - } - } - else - { - previousText = null; - } - - if (tt.isStart()) - { - nestLevel++; - } - else if (tt.isEnd()) - { - nestLevel--; - } - else if (tt.isEnddoc()) - { - // Shouldn't get here, but just in case. - break; - } - } - } - - - curs.dispose(); - } - - /** - * - * @return - */ - Object parent() - { - Object parent; - - XmlCursor curs = newCursor(); - - if (curs.isStartdoc()) - { - // At doc level - no parent - parent = Undefined.instance; - } - else - { - if (curs.toParent()) - { - if (curs.isStartdoc()) - { - // Was top-level - no parent - parent = Undefined.instance; - } - else - { - parent = getFromAnnotation(lib, findAnnotation(curs)); - } - } - else - { - // No parent - parent = Undefined.instance; - } - } - - curs.dispose(); - - return parent; - } - - /** - * - * @param xml - * @return - */ - XML prependChild (Object xml) - { - XmlCursor curs = newCursor(); - - if (curs.isStartdoc()) - { - curs.toFirstContentToken(); - } - - // Move the cursor to the first content token - curs.toFirstContentToken(); - - insertChild(curs, xml); - - curs.dispose(); - - return this; - } - - /** - * - * @return - */ - Object processingInstructions(XMLName xmlName) - { - return matchChildren(XmlCursor.TokenType.PROCINST, xmlName); - } - - /** - * - * @param name - * @return - */ - boolean propertyIsEnumerable(Object name) - { - boolean result; - if (name instanceof Integer) { - result = (((Integer)name).intValue() == 0); - } else if (name instanceof Number) { - double x = ((Number)name).doubleValue(); - // Check that number is posotive 0 - result = (x == 0.0 && 1.0 / x > 0); - } else { - result = ScriptRuntime.toString(name).equals("0"); - } - return result; - } - - /** - * - * @param namespace - */ - XML removeNamespace(Namespace ns) - { - XmlCursor cursor = newCursor(); - - try - { - if(cursor.isStartdoc()) - cursor.toFirstContentToken(); - if(!cursor.isStart()) return this; - - String nsPrefix = ns.prefix(); - String nsURI = ns.uri(); - Map prefixToURI = new HashMap(); - int depth = 1; - - while(!(cursor.isEnd() && depth == 0)) - { - if(cursor.isStart()) - { - // Get the namespaces declared in this element. - // The ones with undefined prefixes are not candidates - // for removal because they are used. - prefixToURI.clear(); - NamespaceHelper.getNamespaces(cursor, prefixToURI); - ObjArray inScopeNSBag = new ObjArray(); - Iterator i = prefixToURI.entrySet().iterator(); - while(i.hasNext()) - { - Map.Entry entry = (Map.Entry)i.next(); - ns = new Namespace(lib, (String)entry.getKey(), (String)entry.getValue()); - inScopeNSBag.add(ns); - } - - // Add the URI we are looking for to avoid matching - // non-existing Namespaces. - ns = new Namespace(lib, nsURI); - inScopeNSBag.add(ns); - - Object[] inScopeNS = inScopeNSBag.toArray(); - - // Check the element name - Namespace n = NamespaceHelper.getNamespace(lib, cursor, - inScopeNS); - if(nsURI.equals(n.uri()) && - (nsPrefix == null || - nsPrefix.equals(n.prefix()))) - { - // This namespace is used - return this; - } - - // Check the attributes - cursor.push(); - boolean hasNext = cursor.toFirstAttribute(); - while(hasNext) - { - n = NamespaceHelper.getNamespace(lib, cursor, inScopeNS); - if(nsURI.equals(n.uri()) && - (nsPrefix == null || - nsPrefix.equals(n.prefix()))) - { - // This namespace is used - return this; - } - - hasNext = cursor.toNextAttribute(); - } - cursor.pop(); - - if(nsPrefix == null) - { - // Remove all namespaces declarations that match nsURI - i = prefixToURI.entrySet().iterator(); - while(i.hasNext()) - { - Map.Entry entry = (Map.Entry)i.next(); - if(entry.getValue().equals(nsURI)) - NamespaceHelper.removeNamespace(cursor, (String)entry.getKey()); - } - } - else if(nsURI.equals(prefixToURI.get(nsPrefix))) - { - // Remove the namespace declaration that matches nsPrefix - NamespaceHelper.removeNamespace(cursor, String.valueOf(nsPrefix)); - } - } - - switch(cursor.toNextToken().intValue()) - { - case XmlCursor.TokenType.INT_START: - depth++; - break; - case XmlCursor.TokenType.INT_END: - depth--; - break; - } - } - } - finally - { - cursor.dispose(); - } - - return this; - } - - XML replace(long index, Object xml) - { - XMLList xlChildToReplace = child(index); - if (xlChildToReplace.length() > 0) - { - // One exists an that index - XML childToReplace = xlChildToReplace.item(0); - insertChildAfter(childToReplace, xml); - removeChild(index); - } - return this; - } - - /** - * - * @param propertyName - * @param xml - * @return - */ - XML replace(XMLName xmlName, Object xml) - { - putXMLProperty(xmlName, xml); - return this; - } - - /** - * - * @param xml - */ - XML setChildren(Object xml) - { - // remove all children - XMLName xmlName = XMLName.formStar(); - XMLList matches = getPropertyList(xmlName); - matches.remove(); - - // append new children - appendChild(xml); - - return this; - } - - /** - * - * @param name - */ - void setLocalName(String localName) - { - XmlCursor cursor = newCursor(); - - try - { - if(cursor.isStartdoc()) - cursor.toFirstContentToken(); - - if(cursor.isText() || cursor.isComment()) return; - - - javax.xml.namespace.QName qname = cursor.getName(); - cursor.setName(new javax.xml.namespace.QName( - qname.getNamespaceURI(), localName, qname.getPrefix())); - } - finally - { - cursor.dispose(); - } - } - - /** - * - * @param name - */ - void setName(QName qname) - { - XmlCursor cursor = newCursor(); - - try - { - if(cursor.isStartdoc()) - cursor.toFirstContentToken(); - - if(cursor.isText() || cursor.isComment()) return; - - if(cursor.isProcinst()) - { - String localName = qname.localName(); - cursor.setName(new javax.xml.namespace.QName(localName)); - } - else - { - String prefix = qname.prefix(); - if (prefix == null) { prefix = ""; } - cursor.setName(new javax.xml.namespace.QName( - qname.uri(), qname.localName(), prefix)); - } - } - finally - { - cursor.dispose(); - } - } - - /** - * - * @param ns - */ - void setNamespace(Namespace ns) - { - XmlCursor cursor = newCursor(); - - try - { - if(cursor.isStartdoc()) - cursor.toFirstContentToken(); - - if(cursor.isText() || - cursor.isComment() || - cursor.isProcinst()) return; - - String prefix = ns.prefix(); - if (prefix == null) { - prefix = ""; - } - cursor.setName(new javax.xml.namespace.QName( - ns.uri(), localName(), prefix)); - } - finally - { - cursor.dispose(); - } - } - - /** - * - * @return - */ - XMLList text() - { - return matchChildren(XmlCursor.TokenType.TEXT); - } - - /** - * - * @return - */ - public String toString() - { - String result; - XmlCursor curs = newCursor(); - - if (curs.isStartdoc()) - { - curs.toFirstContentToken(); - } - - if (curs.isText()) - { - result = curs.getChars(); - } - else if (curs.isStart() && hasSimpleContent()) - { - result = curs.getTextValue(); - } - else - { - result = toXMLString(0); - } - - return result; - } - - String toSource(int indent) - { - // XXX Does toXMLString always return valid XML literal? - return toXMLString(indent); - } - - /** - * - * @return - */ - String toXMLString(int indent) - { - // XXX indent is ignored - - String result; - - XmlCursor curs = newCursor(); - - if (curs.isStartdoc()) - { - curs.toFirstContentToken(); - } - - try - { - if (curs.isText()) - { - result = curs.getChars(); - } - else if (curs.isAttr()) - { - result = curs.getTextValue(); - } - else if (curs.isComment() || curs.isProcinst()) - { - result = XML.dumpNode(curs, getOptions()); - - // todo: XBeans-dependent hack here - // If it's a comment or PI, take off the xml-frament stuff - String start = "<xml-fragment>"; - String end = "</xml-fragment>"; - - if (result.startsWith(start)) - { - result = result.substring(start.length()); - } - - if (result.endsWith(end)) - { - result = result.substring(0, result.length() - end.length()); - } - } - else - { - result = XML.dumpNode(curs, getOptions()); - } - } - finally - { - curs.dispose(); - } - - return result; - } - - /** - * - * @return - */ - Object valueOf() - { - return this; - } - - // - // Other public Functions from XMLObject - // - - /** - * - * @param target - * @return - */ - boolean equivalentXml(Object target) - { - boolean result = false; - - if (target instanceof XML) - { - XML otherXml = (XML) target; - - // Compare with toString() if either side is text node or attribute - // otherwise compare as XML - XmlCursor.TokenType thisTT = tokenType(); - XmlCursor.TokenType otherTT = otherXml.tokenType(); - if (thisTT == XmlCursor.TokenType.ATTR || otherTT == XmlCursor.TokenType.ATTR || - thisTT == XmlCursor.TokenType.TEXT || otherTT == XmlCursor.TokenType.TEXT) - { - result = toString().equals(otherXml.toString()); - } - else - { - XmlCursor cursOne = newCursor(); - XmlCursor cursTwo = otherXml.newCursor(); - - result = LogicalEquality.nodesEqual(cursOne, cursTwo); - - cursOne.dispose(); - cursTwo.dispose(); - -// Old way of comparing by string. -// boolean orgPrettyPrinting = prototype.prettyPrinting; -// prototype.prettyPrinting = true; -// result = toXMLString(0).equals(otherXml.toXMLString(0)); -// prototype.prettyPrinting = orgPrettyPrinting; - } - } - else if (target instanceof XMLList) - { - XMLList otherList = (XMLList) target; - - if (otherList.length() == 1) - { - result = equivalentXml(otherList.getXmlFromAnnotation(0)); - } - } - else if (hasSimpleContent()) - { - String otherStr = ScriptRuntime.toString(target); - - result = toString().equals(otherStr); - } - - return result; - } - - /** - * - * @param name - * @param start - * @return - */ - XMLList getPropertyList(XMLName name) - { - XMLList result; - - // Get the named property - if (name.isDescendants()) - { - result = descendants(name); - } - else if (name.isAttributeName()) - { - result = attribute(name); - } - else - { - result = child(name); - } - - return result; - } - - protected Object jsConstructor(Context cx, boolean inNewExpr, - Object[] args) - { - if (args.length == 0) { - return createFromJS(lib, ""); - } else { - Object arg0 = args[0]; - if (!inNewExpr && arg0 instanceof XML) { - // XML(XML) returns the same object. - return arg0; - } - return createFromJS(lib, arg0); - } - } - - /** - * See ECMA 357, 11_2_2_1, Semantics, 3_f. - */ - public Scriptable getExtraMethodSource(Context cx) - { - if (hasSimpleContent()) { - String src = toString(); - return ScriptRuntime.toObjectOrNull(cx, src); - } - return null; - } - - XmlObject getXmlObject() - { - XmlObject xo; - XmlCursor cursor = newCursor(); - try { - xo = cursor.getObject(); - } finally { - cursor.dispose(); - } - return xo; - } -} |