📄 xmllist.java
字号:
/* -*- 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.xmlimpl;import java.util.Vector;import org.mozilla.javascript.*;import org.mozilla.javascript.xml.*;import org.apache.xmlbeans.XmlCursor;class XMLList extends XMLObjectImpl implements Function{ static final long serialVersionUID = -4543618751670781135L; static class AnnotationList { private Vector v; AnnotationList () { v = new Vector(); } void add (XML.XScriptAnnotation n) { v.add(n); } XML.XScriptAnnotation item(int index) { return (XML.XScriptAnnotation)(v.get(index)); } void remove (int index) { v.remove(index); } int length() { return v.size(); } }; // Fields private AnnotationList _annos; private XMLObjectImpl targetObject = null; private javax.xml.namespace.QName targetProperty = null;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Constructors // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * */ XMLList(XMLLibImpl lib) { super(lib, lib.xmlListPrototype); _annos = new AnnotationList(); } /** * * @param inputObject */ XMLList(XMLLibImpl lib, Object inputObject) { super(lib, lib.xmlListPrototype); String frag; if (inputObject == null || inputObject instanceof Undefined) { frag = ""; } else if (inputObject instanceof XML) { XML xml = (XML) inputObject; _annos = new AnnotationList(); _annos.add(xml.getAnnotation()); } else if (inputObject instanceof XMLList) { XMLList xmll = (XMLList) inputObject; _annos = new AnnotationList(); for (int i = 0; i < xmll._annos.length(); i++) { _annos.add(xmll._annos.item(i)); } } else { frag = ScriptRuntime.toString(inputObject).trim(); if (!frag.startsWith("<>")) { frag = "<>" + frag + "</>"; } frag = "<fragment>" + frag.substring(2); if (!frag.endsWith("</>")) { throw ScriptRuntime.typeError("XML with anonymous tag missing end anonymous tag"); } frag = frag.substring(0, frag.length() - 3) + "</fragment>"; XML orgXML = XML.createFromJS(lib, frag); // Now orphan the children and add them to our XMLList. XMLList children = (XMLList)orgXML.children(); _annos = new AnnotationList(); for (int i = 0; i < children._annos.length(); i++) { // Copy here is so that they'll be orphaned (parent() will be undefined) _annos.add(((XML) children.item(i).copy()).getAnnotation()); } } } // // // TargetObject/Property accessors // // /** * * @param object * @param property */ void setTargets(XMLObjectImpl object, javax.xml.namespace.QName property) { targetObject = object; targetProperty = property; }//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Private functions // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * * @param index * @return */ XML getXmlFromAnnotation(int index) { XML retVal; if (index >= 0 && index < length()) { XML.XScriptAnnotation anno = _annos.item(index); retVal = XML.getFromAnnotation(lib, anno); } else { retVal = null; } return retVal; } /** * * @param index */ private void internalRemoveFromList (int index) { _annos.remove(index); } /** * * @param index * @param xml */ void replace(int index, XML xml) { if (index < length()) { AnnotationList newAnnoList = new AnnotationList(); // Copy upto item to replace. for (int i = 0; i < index; i++) { newAnnoList.add(_annos.item(i)); } newAnnoList.add(xml.getAnnotation()); // Skip over old item we're going to replace we've already add new item on above line. for (int i = index + 1; i < length(); i++) { newAnnoList.add(_annos.item(i)); } _annos = newAnnoList; } } /** * * @param index * @param xml */ private void insert(int index, XML xml) { if (index < length()) { AnnotationList newAnnoList = new AnnotationList(); // Copy upto item to insert. for (int i = 0; i < index; i++) { newAnnoList.add(_annos.item(i)); } newAnnoList.add(xml.getAnnotation()); for (int i = index; i < length(); i++) { newAnnoList.add(_annos.item(i)); } _annos = newAnnoList; } } // // // methods overriding ScriptableObject // // public String getClassName () { return "XMLList"; } // // // methods overriding IdScriptableObject // // /** * * @param index * @param start * @return */ public Object get(int index, Scriptable start) { //Log("get index: " + index); if (index >= 0 && index < length()) { return getXmlFromAnnotation(index); } else { return Scriptable.NOT_FOUND; } } /** * * @param name * @param start * @return */ boolean hasXMLProperty(XMLName xmlName) { boolean result = false; // 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 0 <= index && index < length(); } /** * * @param name * @param value */ void putXMLProperty(XMLName xmlName, Object value) { //Log("put property: " + name); // Special-case checks for undefined and null if (value == null) { value = "null"; } else if (value instanceof Undefined) { value = "undefined"; } if (length() > 1) { throw ScriptRuntime.typeError("Assignment to lists with more that one item is not supported"); } else if (length() == 0) { // Secret sauce for super-expandos. // We set an element here, and then add ourselves to our target. if (targetObject != null && targetProperty != null && !targetProperty.getLocalPart().equals("*")) { // Add an empty element with our targetProperty name and then set it. XML xmlValue = XML.createTextElement(lib, targetProperty, ""); addToList(xmlValue); if(xmlName.isAttributeName()) { setAttribute(xmlName, value); } else { XML xml = (XML)item(0); xml.putXMLProperty(xmlName, value); // Update the list with the new item at location 0. replace(0, (XML)item(0)); } // Now add us to our parent XMLName name2 = XMLName.formProperty(targetProperty.getNamespaceURI(), targetProperty.getLocalPart()); targetObject.putXMLProperty(name2, this); } else { throw ScriptRuntime.typeError("Assignment to empty XMLList without targets not supported"); } } else if(xmlName.isAttributeName()) { setAttribute(xmlName, value); } else { XML xml = (XML)item(0); xml.putXMLProperty(xmlName, value); // Update the list with the new item at location 0. replace(0, (XML)item(0)); } } /** * * @param name * @return */ Object getXMLProperty(XMLName name) { return getPropertyList(name); } /** * * @param index * @param value */ public void put(int index, Scriptable start, Object value) { Object parent = Undefined.instance; // Convert text into XML if needed. XMLObject xmlValue; // Special-case checks for undefined and null if (value == null) { value = "null"; } else if (value instanceof Undefined) { value = "undefined"; } if (value instanceof XMLObject) { xmlValue = (XMLObject) value; } else { if (targetProperty == null) { xmlValue = XML.createFromJS(lib, value.toString()); } else { xmlValue = XML.createTextElement(lib, targetProperty, value.toString()); } } // Find the parent if (index < length()) { parent = item(index).parent(); } else { // Appending parent = parent(); } if (parent instanceof XML) { // found parent, alter doc XML xmlParent = (XML) parent; if (index < length()) { // We're replacing the the node. XML xmlNode = getXmlFromAnnotation(index); if (xmlValue instanceof XML) { xmlNode.replaceAll((XML) xmlValue); replace(index, xmlNode); } else if (xmlValue instanceof XMLList) { // Replace the first one, and add the rest on the list. XMLList list = (XMLList) xmlValue; if (list.length() > 0) { int lastIndexAdded = xmlNode.childIndex(); xmlNode.replaceAll((XML)list.item(0)); replace(index, (XML)list.item(0)); for (int i = 1; i < list.length(); i++) { xmlParent.insertChildAfter(xmlParent.getXmlChild(lastIndexAdded), list.item(i)); lastIndexAdded++; insert(index + i, (XML)list.item(i)); } } } } else { // Appending xmlParent.appendChild(xmlValue); addToList(xmlParent.getXmlChild(index)); } } else { // Don't all have same parent, no underlying doc to alter if (index < length()) { XML xmlNode = XML.getFromAnnotation(lib, _annos.item(index)); if (xmlValue instanceof XML) { xmlNode.replaceAll((XML) xmlValue); replace(index, xmlNode); } else if (xmlValue instanceof XMLList) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -