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;
  }
Beispiel #2
0
  @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));
    }
  }
Beispiel #3
0
  @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);
      }
    }
  }