@Override XMLList children() { ArrayList<XML> list = new ArrayList<XML>(); for (int i = 0; i < length(); i++) { XML xml = getXmlFromAnnotation(i); if (xml != null) { XMLList childList = xml.children(); int cChildren = childList.length(); for (int j = 0; j < cChildren; j++) { list.add(childList.item(j)); } } } XMLList allChildren = newXMLList(); int sz = list.size(); for (int i = 0; i < sz; i++) { allChildren.addToList(list.get(i)); } return allChildren; }
@Override XMLList elements(XMLName name) { XMLList rv = newXMLList(); for (int i = 0; i < length(); i++) { XML xml = getXmlFromAnnotation(i); rv.addToList(xml.elements(name)); } return rv; }
// XMLList will remove will delete all items in the list (a set delete) this differs from the // XMLList delete operator. void remove() { int nLen = length(); for (int i = nLen - 1; i >= 0; i--) { XML xml = getXmlFromAnnotation(i); if (xml != null) { xml.remove(); internalRemoveFromList(i); } } }
@Override public void delete(int index) { if (index >= 0 && index < length()) { XML xml = getXmlFromAnnotation(index); xml.remove(); internalRemoveFromList(index); } }
@Override void deleteXMLProperty(XMLName name) { for (int i = 0; i < length(); i++) { XML xml = getXmlFromAnnotation(i); if (xml.isElement()) { xml.deleteXMLProperty(name); } } }
@Override XMLObjectImpl copy() { XMLList result = newXMLList(); for (int i = 0; i < length(); i++) { XML xml = getXmlFromAnnotation(i); result.addToList(xml.copy()); } return result; }
@Override 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 than 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.getLocalName() != null && targetProperty.getLocalName().length() > 0) { // Add an empty element with our targetProperty name and // then set it. XML xmlValue = newTextElementXML(null, targetProperty, null); addToList(xmlValue); if (xmlName.isAttributeName()) { setAttribute(xmlName, value); } else { XML xml = item(0); xml.putXMLProperty(xmlName, value); // Update the list with the new item at location 0. replace(0, item(0)); } // Now add us to our parent XMLName name2 = XMLName.formProperty( targetProperty.getNamespace().getUri(), targetProperty.getLocalName()); targetObject.putXMLProperty(name2, this); replace(0, targetObject.getXML().getLastXmlChild()); } else { throw ScriptRuntime.typeError("Assignment to empty XMLList without targets not supported"); } } else if (xmlName.isAttributeName()) { setAttribute(xmlName, value); } else { XML xml = item(0); xml.putXMLProperty(xmlName, value); // Update the list with the new item at location 0. replace(0, item(0)); } }
@Override XMLList processingInstructions(XMLName xmlName) { XMLList result = newXMLList(); for (int i = 0; i < length(); i++) { XML xml = getXmlFromAnnotation(i); result.addToList(xml.processingInstructions(xmlName)); } return result; }
@Override boolean contains(Object xml) { boolean result = false; for (int i = 0; i < length(); i++) { XML member = getXmlFromAnnotation(i); if (member.equivalentXml(xml)) { result = true; break; } } return result; }
@Override boolean hasSimpleContent() { if (length() == 0) { return true; } else if (length() == 1) { return getXmlFromAnnotation(0).hasSimpleContent(); } else { for (int i = 0; i < length(); i++) { XML nextElement = getXmlFromAnnotation(i); if (nextElement.isElement()) { return false; } } return true; } }
@Override public String toString() { // ECMA357 10.1.2 if (hasSimpleContent()) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < length(); i++) { XML next = getXmlFromAnnotation(i); if (next.isComment() || next.isProcessingInstruction()) { // do nothing } else { sb.append(next.toString()); } } return sb.toString(); } else { return toXMLString(); } }
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 = "<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 = 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; } }
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); }
/** * If list is empty, return undefined, if elements have different parents return undefined, If * they all have the same parent, return that parent */ @Override Object parent() { if (length() == 0) return Undefined.instance; XML candidateParent = null; for (int i = 0; i < length(); i++) { Object currParent = getXmlFromAnnotation(i).parent(); if (!(currParent instanceof XML)) return Undefined.instance; XML xml = (XML) currParent; if (i == 0) { // Set the first for the rest to compare to. candidateParent = xml; } else { if (candidateParent.is(xml)) { // keep looking } else { return Undefined.instance; } } } return candidateParent; }
@Override boolean hasComplexContent() { boolean complexContent; int length = length(); if (length == 0) { complexContent = false; } else if (length == 1) { complexContent = getXmlFromAnnotation(0).hasComplexContent(); } else { complexContent = false; for (int i = 0; i < length; i++) { XML nextElement = getXmlFromAnnotation(i); if (nextElement.isElement()) { complexContent = true; break; } } } return complexContent; }
/** @deprecated */ void add(XML xml) { _add(xml.getAnnotation()); }
@Override 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 = newXMLFromJs(value.toString()); } else { // Note that later in the code, we will use this as an argument to replace(int,value) // So we will be "replacing" this element with itself // There may well be a better way to do this // TODO Find a way to refactor this whole method and simplify it xmlValue = item(index); if (xmlValue == null) { XML x = item(0); xmlValue = x == null ? newTextElementXML(null, targetProperty, null) : x.copy(); } ((XML) xmlValue).setChildren(value); } } // Find the parent if (index < length()) { parent = item(index).parent(); } else if (length() == 0) { parent = targetObject != null ? targetObject.getXML() : 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) { replaceNode(xmlNode, (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(); replaceNode(xmlNode, list.item(0)); replace(index, list.item(0)); for (int i = 1; i < list.length(); i++) { xmlParent.insertChildAfter(xmlParent.getXmlChild(lastIndexAdded), list.item(i)); lastIndexAdded++; insert(index + i, list.item(i)); } } } } else { // Appending xmlParent.appendChild(xmlValue); addToList(xmlParent.getLastXmlChild()); } } else { // Don't all have same parent, no underlying doc to alter if (index < length()) { XML xmlNode = getXML(_annos, index); if (xmlValue instanceof XML) { replaceNode(xmlNode, (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) { replaceNode(xmlNode, list.item(0)); replace(index, list.item(0)); for (int i = 1; i < list.length(); i++) { insert(index + i, list.item(i)); } } } } else { addToList(xmlValue); } } }
private void setAttribute(XMLName xmlName, Object value) { for (int i = 0; i < length(); i++) { XML xml = getXmlFromAnnotation(i); xml.setAttribute(xmlName, value); } }
private void replaceNode(XML xml, XML with) { xml.replaceWith(with); }