/**
   * @param containingHtmlElement the name of the HTML element containing el. If the HTML element is
   *     contained inside a template construct then this name may differ from el's immediate parent.
   */
  private void inspectElement(JobEnvelope source, Element el, ElKey containingHtmlElement) {
    ElKey elKey = ElKey.forElement(el);

    // Recurse early so that ihtml:dynamic elements have been parsed before we
    // process the attributes element list.
    for (Node child : Nodes.childrenOf(el)) {
      inspect(source, child, elKey);
    }

    // For each attribute allowed on this element type, ensure that
    // (1) If it is not specified, and its default value is not allowed, then
    //     it is added with a known safe value.
    // (2) Its value is rewritten as appropriate.
    // We don't have to worry about disallowed attributes since those will
    // not be present in scriptsPerNode.  The TemplateSanitizer should have
    // stripped those out.  The TemplateSanitizer should also have stripped out
    // disallowed elements.
    if (!htmlSchema.isElementAllowed(elKey)) {
      return;
    }

    HTML.Element elInfo = htmlSchema.lookupElement(elKey);
    List<HTML.Attribute> attrs = elInfo.getAttributes();
    if (attrs != null) {
      for (HTML.Attribute a : attrs) {
        AttribKey attrKey = a.getKey();
        if (!htmlSchema.isAttributeAllowed(attrKey)) {
          continue;
        }
        Attr attr = null;
        String aUri = attrKey.ns.uri;
        String aName = attrKey.localName;
        Attr unsafe = el.getAttributeNodeNS(aUri, aName);
        if (unsafe != null && a.getValueCriterion().accept(unsafe.getValue())) {
          attr = unsafe;
        } else if ((a.getDefaultValue() != null
                && !a.getValueCriterion().accept(a.getDefaultValue()))
            || !a.isOptional()) {
          attr = el.getOwnerDocument().createAttributeNS(aUri, aName);
          String safeValue;
          if (a.getType() == HTML.Attribute.Type.URI) {
            safeValue = "" + Nodes.getFilePositionFor(el).source().getUri();
          } else {
            safeValue = a.getSafeValue();
          }
          if (safeValue == null) {
            mq.addMessage(
                IhtmlMessageType.MISSING_ATTRIB, Nodes.getFilePositionFor(el), elKey, attrKey);
            continue;
          }
          attr.setNodeValue(safeValue);
          el.setAttributeNodeNS(attr);
        }
        if (attr != null) {
          inspectHtmlAttribute(source, attr, a);
        }
      }
    }
    scriptsPerNode.put(el, null);
  }
Exemple #2
0
  /**
   * Copy in-scope namespace declarations of the decl node to the decl node itself so that this move
   * won't change the in-scope namespace bindings.
   */
  private void copyInscopeNSAttributes(Element e) {
    Element p = e;
    Set<String> inscopes = new HashSet<String>();
    while (true) {
      NamedNodeMap atts = p.getAttributes();
      for (int i = 0; i < atts.getLength(); i++) {
        Attr a = (Attr) atts.item(i);
        if (Constants.NS_XMLNS.equals(a.getNamespaceURI())) {
          String prefix;
          if (a.getName().indexOf(':') == -1) prefix = "";
          else prefix = a.getLocalName();

          if (inscopes.add(prefix) && p != e) {
            // if this is the first time we see this namespace bindings,
            // copy the declaration.
            // if p==decl, there's no need to. Note that
            // we want to add prefix to inscopes even if p==Decl

            e.setAttributeNodeNS((Attr) a.cloneNode(true));
          }
        }
      }

      if (p.getParentNode() instanceof Document) break;

      p = (Element) p.getParentNode();
    }

    if (!inscopes.contains("")) {
      // if the default namespace was undeclared in the context of decl,
      // it must be explicitly set to "" since the new environment might
      // have a different default namespace URI.
      e.setAttributeNS(Constants.NS_XMLNS, "xmlns", "");
    }
  }
  /**
   * Creates 'wsu:Id' attribute for wsu:Timestamp needed for signature.
   *
   * @param message
   * @return
   * @throws ParserException
   */
  private String createTimestampUuid(SoapMessage message) throws ParserException {

    NodeList timestampList =
        message
            .getHeader()
            .getOwnerDocument()
            .getElementsByTagNameNS(WSU_NAMESPACE, WSU_TIMESTAMP_LOCAL_NAME);

    assert timestampList.getLength() <= 1;

    if (timestampList.getLength() == 1) {
      assert timestampList.item(0).getNodeType() == Node.ELEMENT_NODE;

      Element timestamp = (Element) timestampList.item(0);
      String timestampId = Util.randomNCNameUUID();

      Attr wsuId = timestamp.getOwnerDocument().createAttributeNS(WSU_NAMESPACE, WSU_ID_LOCAL_NAME);
      wsuId.setPrefix(timestamp.getPrefix());

      wsuId.setValue(timestampId);
      timestamp.setAttributeNodeNS(wsuId);
      timestamp.setIdAttributeNode(wsuId, true);

      log.trace("Created wsu:Id for wsu:Timestamp: " + timestampId);

      return timestampId;
    }

    log.trace("Timestamp element not found in the message");

    return null;
  }
  /**
   * serialize the given element
   *
   * @param schemaObject - Parent schema object.contains the extension to be serialized
   * @param classOfType - The class of type to be serialized
   * @param domNode - the parent DOM Node that will ultimately be serialized. The XMLSchema
   *     serialization mechanism is to create a DOM tree first and serialize it
   */
  public void serialize(XmlSchemaObject schemaObject, Class classOfType, Node domNode) {
    Map metaInfoMap = schemaObject.getMetaInfoMap();
    CustomAttribute att = (CustomAttribute) metaInfoMap.get(CustomAttribute.CUSTOM_ATTRIBUTE_QNAME);

    Element elt = (Element) domNode;
    Attr att1 =
        elt.getOwnerDocument()
            .createAttributeNS(
                CustomAttribute.CUSTOM_ATTRIBUTE_QNAME.getNamespaceURI(),
                CustomAttribute.CUSTOM_ATTRIBUTE_QNAME.getLocalPart());
    att1.setValue(att.getPrefix() + ":" + att.getSuffix());
    elt.setAttributeNodeNS(att1);
  }
 private void ajouter() {
   final AffichageFormulaire affP = premierAffichage.chercherAffichage(parent);
   if (noeud instanceof Element) recreerElement();
   else {
     final Element elparent = (Element) parent;
     elparent.setAttributeNodeNS((Attr) noeud);
   }
   affP.lireEnfants();
   affP.getJaxeDocument().textPane.miseAJourArbre();
   affP.majPanel(null);
   final AffichageFormulaire affAj = affP.chercherAffichage(noeud);
   if (affAj != null && affAj.comp != null) affAj.comp.requestFocusInWindow();
 }
 /**
  * Runs the test case.
  *
  * @throws Throwable Any uncaught exception causes test to fail
  */
 public void runTest() throws Throwable {
   Document doc;
   Element element;
   boolean state;
   Attr attribute;
   Attr newAttribute;
   doc = (Document) load("staff", false);
   element = doc.createElementNS("http://www.w3.org/DOM", "elem");
   attribute = doc.createAttributeNS("http://www.w3.org/DOM/Test/createAttributeNS", "attr");
   newAttribute = element.setAttributeNodeNS(attribute);
   element.removeAttributeNS("http://www.w3.org/DOM/Test/createAttributeNS", "attr");
   state = element.hasAttributeNS("http://www.w3.org/DOM/Test/createAttributeNS", "attr");
   assertFalse("elementremoveattributens01", state);
 }
  /** {@inheritDoc} */
  protected void marshallAttributes(XMLObject samlObject, Element domElement)
      throws MarshallingException {
    Keywords words = (Keywords) samlObject;

    if (words.getXMLLang() != null) {
      Attr attribute =
          AttributeSupport.constructAttribute(
              domElement.getOwnerDocument(),
              XMLConstants.XML_NS,
              LangBearing.XML_LANG_ATTR_LOCAL_NAME,
              XMLConstants.XML_PREFIX);
      attribute.setValue(words.getXMLLang());
      domElement.setAttributeNodeNS(attribute);
    }
  }
Exemple #8
0
  @Override
  protected void saveEObjectSingle(EObject o, EStructuralFeature f) {
    StringBuffer buffer = new StringBuffer();

    EObject value = (EObject) helper.getValue(o, f);
    if (value != null) {
      String id = helper.getHREF(value);
      if (id != null) {
        id = convertURI(id);
        buffer.setLength(0);
        // if (!id.startsWith("#"))
        // {
        if (!o.eClass().getEPackage().getNsURI().equals(f.getEType().getEPackage().getNsURI())) {

          EClass eClass = value.eClass();
          EClass expectedType = (EClass) f.getEType();
          if (saveTypeInfo
              ? xmlTypeInfo.shouldSaveType(eClass, expectedType, f)
              : eClass != expectedType
                  && (expectedType.isAbstract()
                      || f.getEGenericType().getETypeParameter() != null)) {
            buffer.append(helper.getQName(eClass));
            buffer.append(' ');
          }
        }
        // }
        buffer.append(id);
        if (!toDOM) {
          String name = helper.getQName(f);
          doc.startAttribute(name);
          doc.addAttributeContent(buffer.toString());
          doc.endAttribute();
        } else {
          helper.populateNameInfo(nameInfo, f);
          Attr attr =
              document.createAttributeNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName());
          attr.setNodeValue(buffer.toString());
          ((Element) currentNode).setAttributeNodeNS(attr);
          handler.recordValues(attr, o, f, value);
        }
      }
    }
  }
  /**
   * Runs the test case.
   *
   * @throws Throwable Any uncaught exception causes test to fail
   */
  public void testSetNamedItemNS1() throws Throwable {
    Document doc;
    NamedNodeMap attributes;
    Node element;
    Attr attribute;

    Attr newAttr1;
    NodeList elementList;
    String attrName;
    doc = (Document) load("staffNS", builder);
    elementList = doc.getElementsByTagNameNS("http://www.nist.gov", "address");
    element = elementList.item(0);
    attributes = element.getAttributes();
    newAttr1 = doc.createAttributeNS("http://www.w3.org/DOM/L1", "streets");
    ((Element) /* Node */ element).setAttributeNodeNS(newAttr1);
    attribute = (Attr) attributes.getNamedItemNS("http://www.w3.org/DOM/L1", "streets");
    attrName = attribute.getNodeName();
    assertEquals("namednodemapsetnameditemns01", "streets", attrName);
  }
 private void changerTexte(final String s) {
   final AffichageFormulaire affP = premierAffichage.chercherAffichage(parent);
   if (noeud instanceof Element) {
     final AffichageFormulaire aff = affP.chercherAffichage(noeud);
     Node noeudTexte = noeud.getFirstChild();
     if (aff == null && !"".equals(s)) recreerElement();
     else if (noeudTexte != null) noeudTexte.setNodeValue(s);
     else {
       noeudTexte = noeud.getOwnerDocument().createTextNode(s);
       noeud.appendChild(noeudTexte);
     }
     affP.majPanel(null);
   } else { // attribut
     final Element elparent = (Element) parent;
     if (!elparent.hasAttributeNS(noeud.getNamespaceURI(), noeud.getLocalName()))
       elparent.setAttributeNodeNS((Attr) noeud);
     noeud.setNodeValue(s);
     affP.majPanel(null);
   }
   final AffichageFormulaire affAj = affP.chercherAffichage(noeud);
   if (affAj != null && affAj.comp != null) affAj.comp.requestFocusInWindow();
 }
  @Override
  public void startElement(
      final String uri, final String localName, final String qName, final Attributes attrs)
      throws SAXException {
    Element e = null;
    if (localName != null && !"".equals(localName)) {
      e = doc.createElementNS(uri, localName);
    } else {
      e = doc.createElement(qName);
    }
    e.setUserData(LINE_NUMBER_KEY_NAME, this.locator.getLineNumber(), null);

    if (current == null) {
      doc.appendChild(e);
    } else {
      current.appendChild(e);
      doc.setUserData(DOCTYPE_KEY_NAME, doctype, null);
    }
    current = e;

    if (attrs != null) {
      for (int i = 0; i < attrs.getLength(); i++) {
        Attr attr = null;
        if (attrs.getLocalName(i) != null && !"".equals(attrs.getLocalName(i))) {
          attr = doc.createAttributeNS(attrs.getURI(i), attrs.getLocalName(i));
          attr.setValue(attrs.getValue(i));
          attr.setUserData(LINE_NUMBER_KEY_NAME, this.locator.getLineNumber(), null);
          current.setAttributeNodeNS(attr);
        } else {
          attr = doc.createAttribute(attrs.getQName(i));
          attr.setValue(attrs.getValue(i));
          attr.setUserData(LINE_NUMBER_KEY_NAME, this.locator.getLineNumber(), null);
          current.setAttributeNode(attr);
        }
      }
    }
  }
  /**
   * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String,
   *     java.lang.String, org.xml.sax.Attributes)
   */
  public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
      throws SAXException {
    // save accumulated character content
    if (inModification && charBuf.length() > 0) {
      //            String normalized = charBuf.toString();
      final String normalized =
          preserveWhitespace
              ? charBuf.toString()
              : charBuf.getNormalizedString(FastStringBuffer.SUPPRESS_BOTH);

      if (normalized.length() > 0) {
        final Text text = doc.createTextNode(charBuf.toString());
        if (stack.isEmpty()) {
          // LOG.debug("appending text to fragment: " + text.getData());
          contents.add(text);
        } else {
          final Element last = stack.peek();
          last.appendChild(text);
        }
      }
      charBuf.setLength(0);
    }
    if (namespaceURI.equals(XUPDATE_NS)) {
      String select = null;
      if (localName.equals(MODIFICATIONS)) {
        startModifications(atts);
        return;
      } else if (localName.equals(VARIABLE)) {
        // variable declaration
        startVariableDecl(atts);
        return;
      } else if (IF.equals(localName)) {
        if (inModification) {
          throw new SAXException("xupdate:if is not allowed inside a modification");
        }
        select = atts.getValue("test");
        final Conditional cond =
            new Conditional(broker, documentSet, select, namespaces, variables);
        cond.setAccessContext(accessCtx);
        conditionals.push(cond);
        return;
      } else if (VALUE_OF.equals(localName)) {
        if (!inModification) {
          throw new SAXException("xupdate:value-of is not allowed outside a modification");
        }

      } else if (APPEND.equals(localName)
          || INSERT_BEFORE.equals(localName)
          || INSERT_AFTER.equals(localName)
          || REMOVE.equals(localName)
          || RENAME.equals(localName)
          || UPDATE.equals(localName)
          || REPLACE.equals(localName)) {
        if (inModification) {
          throw new SAXException("nested modifications are not allowed");
        }
        select = atts.getValue("select");
        if (select == null) {
          throw new SAXException(localName + " requires a select attribute");
        }
        doc = builder.newDocument();
        contents = new NodeListImpl();
        inModification = true;
      } else if ((ELEMENT.equals(localName)
          || ATTRIBUTE.equals(localName)
          || TEXT.equals(localName)
          || PROCESSING_INSTRUCTION.equals(localName)
          || COMMENT.equals(localName))) {
        if (!inModification) {
          throw new SAXException("creation elements are only allowed inside " + "a modification");
        }
        charBuf.setLength(0);
      } else {
        throw new SAXException("Unknown XUpdate element: " + qName);
      }

      // start a new modification section
      if (APPEND.equals(localName)) {
        final String child = atts.getValue("child");
        modification = new Append(broker, documentSet, select, child, namespaces, variables);
      } else if (UPDATE.equals(localName)) {
        modification = new Update(broker, documentSet, select, namespaces, variables);
      } else if (INSERT_BEFORE.equals(localName)) {
        modification =
            new Insert(broker, documentSet, select, Insert.INSERT_BEFORE, namespaces, variables);
      } else if (INSERT_AFTER.equals(localName)) {
        modification =
            new Insert(broker, documentSet, select, Insert.INSERT_AFTER, namespaces, variables);
      } else if (REMOVE.equals(localName)) {
        modification = new Remove(broker, documentSet, select, namespaces, variables);
      } else if (RENAME.equals(localName)) {
        modification = new Rename(broker, documentSet, select, namespaces, variables);
      } else if (REPLACE.equals(localName)) {
        modification = new Replace(broker, documentSet, select, namespaces, variables);
      }

      // process commands for node creation
      else if (ELEMENT.equals(localName)) {
        String name = atts.getValue("name");
        if (name == null) {
          throw new SAXException("element requires a name attribute");
        }
        final int p = name.indexOf(':');
        String namespace = null;
        String prefix = "";
        if (p != Constants.STRING_NOT_FOUND) {
          prefix = name.substring(0, p);
          if (name.length() == p + 1) {
            throw new SAXException("illegal prefix in qname: " + name);
          }
          name = name.substring(p + 1);
          namespace = atts.getValue("namespace");
          if (namespace == null) {
            namespace = (String) namespaces.get(prefix);
          }
          if (namespace == null) {
            throw new SAXException("no namespace defined for prefix " + prefix);
          }
        }
        Element elem;
        if (namespace != null && namespace.length() > 0) {
          elem = doc.createElementNS(namespace, name);
          elem.setPrefix(prefix);
        } else {
          elem = doc.createElement(name);
        }

        if (stack.isEmpty()) {
          contents.add(elem);
        } else {
          final Element last = stack.peek();
          last.appendChild(elem);
        }
        this.setWhitespaceHandling((Element) stack.push(elem));
      } else if (ATTRIBUTE.equals(localName)) {
        final String name = atts.getValue("name");
        if (name == null) {
          throw new SAXException("attribute requires a name attribute");
        }
        final int p = name.indexOf(':');
        String namespace = null;
        if (p != Constants.STRING_NOT_FOUND) {
          final String prefix = name.substring(0, p);
          if (name.length() == p + 1) {
            throw new SAXException("illegal prefix in qname: " + name);
          }
          namespace = atts.getValue("namespace");
          if (namespace == null) {
            namespace = (String) namespaces.get(prefix);
          }
          if (namespace == null) {
            throw new SAXException("no namespace defined for prefix " + prefix);
          }
        }
        Attr attrib =
            namespace != null && namespace.length() > 0
                ? doc.createAttributeNS(namespace, name)
                : doc.createAttribute(name);
        if (stack.isEmpty()) {
          for (int i = 0; i < contents.getLength(); i++) {
            final Node n = contents.item(i);
            String ns = n.getNamespaceURI();
            final String nname = ns == null ? n.getNodeName() : n.getLocalName();
            if (ns == null) {
              ns = "";
            }
            // check for duplicate attributes
            if (n.getNodeType() == Node.ATTRIBUTE_NODE
                && nname.equals(name)
                && ns.equals(namespace)) {
              throw new SAXException(
                  "The attribute " + attrib.getNodeName() + " cannot be specified twice");
            }
          }
          contents.add(attrib);
        } else {
          final Element last = (Element) stack.peek();
          if (namespace != null && last.hasAttributeNS(namespace, name)
              || namespace == null && last.hasAttribute(name)) {
            throw new SAXException(
                "The attribute "
                    + attrib.getNodeName()
                    + " cannot be specified "
                    + "twice on the same element");
          }
          if (namespace != null) {
            last.setAttributeNodeNS(attrib);
          } else {
            last.setAttributeNode(attrib);
          }
        }
        inAttribute = true;
        currentNode = attrib;

        // process value-of
      } else if (VALUE_OF.equals(localName)) {
        select = atts.getValue("select");
        if (select == null) {
          throw new SAXException("value-of requires a select attribute");
        }
        final Sequence seq = processQuery(select);
        if (LOG.isDebugEnabled()) {
          LOG.debug("Found " + seq.getItemCount() + " items for value-of");
        }
        Item item;
        try {
          for (final SequenceIterator i = seq.iterate(); i.hasNext(); ) {
            item = i.nextItem();
            if (Type.subTypeOf(item.getType(), Type.NODE)) {
              final Node node = NodeSetHelper.copyNode(doc, ((NodeValue) item).getNode());
              if (stack.isEmpty()) {
                contents.add(node);
              } else {
                final Element last = (Element) stack.peek();
                last.appendChild(node);
              }
            } else {
              final String value = item.getStringValue();
              characters(value.toCharArray(), 0, value.length());
            }
          }
        } catch (final XPathException e) {
          throw new SAXException(e.getMessage(), e);
        }
      }
    } else if (inModification) {
      final Element elem =
          namespaceURI != null && namespaceURI.length() > 0
              ? doc.createElementNS(namespaceURI, qName)
              : doc.createElement(qName);
      Attr a;
      for (int i = 0; i < atts.getLength(); i++) {
        final String name = atts.getQName(i);
        final String nsURI = atts.getURI(i);
        if (name.startsWith("xmlns")) {
          // Why are these showing up? They are supposed to be stripped out?
        } else {
          a = nsURI != null ? doc.createAttributeNS(nsURI, name) : doc.createAttribute(name);
          a.setValue(atts.getValue(i));
          if (nsURI != null) {
            elem.setAttributeNodeNS(a);
          } else {
            elem.setAttributeNode(a);
          }
        }
      }
      if (stack.isEmpty()) {
        contents.add(elem);
      } else {
        final Element last = (Element) stack.peek();
        last.appendChild(elem);
      }
      this.setWhitespaceHandling((Element) stack.push(elem));
    }
  }
  /**
   * @param featureCollection
   * @param writer
   * @param fragment : true if we write in a stream, dont write start and end elements
   * @throws DataStoreException
   */
  public Element writeFeatureCollection(
      final FeatureCollection featureCollection, final boolean fragment, final boolean wfs)
      throws DataStoreException, ParserConfigurationException {

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    // then we have to create document-loader:
    factory.setNamespaceAware(false);
    DocumentBuilder loader = factory.newDocumentBuilder();

    // creating a new DOM-document...
    Document document = loader.newDocument();

    // the XML header
    if (!fragment) {
      document.setXmlVersion("1.0");
      // writer.writeStartDocument("UTF-8", "1.0");
    }

    // the root Element
    final Element rootElement;
    if (wfs) {
      rootElement = document.createElementNS("http://www.opengis.net/wfs", "FeatureCollection");
      rootElement.setPrefix("wfs");
    } else {
      rootElement = document.createElementNS("http://www.opengis.net/gml", "FeatureCollection");
      rootElement.setPrefix("gml");
    }

    document.appendChild(rootElement);

    String collectionID = "";
    if (featureCollection.getID() != null) {
      collectionID = featureCollection.getID();
    }
    final Attr idAttribute = document.createAttributeNS(Namespaces.GML, "id");
    idAttribute.setValue(collectionID);
    idAttribute.setPrefix("gml");
    rootElement.setAttributeNodeNS(idAttribute);

    if (schemaLocation != null && !schemaLocation.equals("")) {
      rootElement.setAttributeNS(
          "http://www.w3.org/2001/XMLSchema-instance", "schemaLocation", schemaLocation);
    }

    /*FeatureType type = featureCollection.getFeatureType();
    if (type != null && type.getName() != null) {
        String namespace = type.getName().getNamespaceURI();
        if (namespace != null && !namespace.equals(Namespaces.GML)) {
            Prefix prefix    = getPrefix(namespace);
            writer.writeNamespace(prefix.prefix, namespace);
        }
    }*/
    /*
     * The boundedby part
     */
    final Element boundElement = writeBounds(featureCollection.getEnvelope(), document);
    if (boundElement != null) {
      rootElement.appendChild(boundElement);
    }

    // we write each feature member of the collection
    FeatureIterator iterator = featureCollection.iterator();
    try {
      while (iterator.hasNext()) {
        final Feature f = iterator.next();
        final Element memberElement = document.createElementNS(Namespaces.GML, "featureMember");
        memberElement.setPrefix("gml");
        memberElement.appendChild(writeFeature(f, document, true));
        rootElement.appendChild(memberElement);
      }

    } finally {
      // we close the stream
      iterator.close();
    }
    return rootElement;
  }
  /**
   * Write the feature into the stream.
   *
   * @param feature The feature
   * @param root
   * @throws XMLStreamException
   */
  public Element writeFeature(final Feature feature, final Document rootDocument, boolean fragment)
      throws ParserConfigurationException {

    final Document document;
    if (rootDocument == null) {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      // then we have to create document-loader:
      factory.setNamespaceAware(false);
      DocumentBuilder loader = factory.newDocumentBuilder();

      // creating a new DOM-document...
      document = loader.newDocument();
    } else {
      document = rootDocument;
    }

    // the root element of the xml document (type of the feature)
    final FeatureType type = feature.getType();
    final Name typeName = type.getName();
    final String namespace = typeName.getNamespaceURI();
    final String localPart = typeName.getLocalPart();

    final Element rootElement;
    final Prefix prefix;
    if (namespace != null) {
      prefix = getPrefix(namespace);
      rootElement = document.createElementNS(namespace, localPart);
      rootElement.setPrefix(prefix.prefix);

    } else {
      rootElement = document.createElement(localPart);
      prefix = null;
    }
    // if main document set the xmlns
    if (!fragment) {
      rootElement.setAttributeNS(
          "http://www.w3.org/2000/xmlns/", "xmlns:gml", "http://www.opengis.net/gml");
    }
    final Attr idAttr = document.createAttributeNS(Namespaces.GML, "id");
    idAttr.setValue(feature.getIdentifier().getID());
    idAttr.setPrefix("gml");
    rootElement.setAttributeNodeNS(idAttr);

    if (rootDocument == null) {
      document.appendChild(rootElement);
    }
    // write properties in the type order
    for (final PropertyDescriptor desc : type.getDescriptors()) {
      final Collection<Property> props = feature.getProperties(desc.getName());
      for (Property a : props) {
        final Object valueA = a.getValue();
        final PropertyType typeA = a.getType();
        final Name nameA = a.getName();
        final String nameProperty = nameA.getLocalPart();
        String namespaceProperty = nameA.getNamespaceURI();
        if (valueA instanceof Collection && !(typeA instanceof GeometryType)) {
          for (Object value : (Collection) valueA) {
            final Element element;
            if (namespaceProperty != null) {
              element = document.createElementNS(namespaceProperty, nameProperty);
            } else {
              element = document.createElement(nameProperty);
            }
            element.setTextContent(Utils.getStringValue(value));
            if (prefix != null) {
              element.setPrefix(prefix.prefix);
            }
            rootElement.appendChild(element);
          }

        } else if (valueA instanceof Map && !(typeA instanceof GeometryType)) {
          final Map<?, ?> map = (Map) valueA;
          for (Entry<?, ?> entry : map.entrySet()) {
            final Element element;
            if (namespaceProperty != null) {
              element = document.createElementNS(namespaceProperty, nameProperty);
            } else {
              element = document.createElement(nameProperty);
            }
            final Object key = entry.getKey();
            if (key != null) {
              element.setAttribute("name", (String) key);
            }
            element.setTextContent(Utils.getStringValue(entry.getValue()));
            if (prefix != null) {
              element.setPrefix(prefix.prefix);
            }
            rootElement.appendChild(element);
          }

        } else if (!(typeA instanceof GeometryType)) {
          String value = Utils.getStringValue(valueA);
          if (value != null || (value == null && !a.isNillable())) {

            if ((nameProperty.equals("name") || nameProperty.equals("description"))
                && !Namespaces.GML.equals(namespaceProperty)) {
              namespaceProperty = Namespaces.GML;
              LOGGER.warning(
                  "the property name and description of a feature must have the GML namespace");
            }
            final Element element;
            if (namespaceProperty != null) {
              element = document.createElementNS(namespaceProperty, nameProperty);
            } else {
              element = document.createElement(nameProperty);
            }
            if (value != null) {
              element.setTextContent(value);
            }
            if (prefix != null) {
              element.setPrefix(prefix.prefix);
            }
            rootElement.appendChild(element);
          }

          // we add the geometry
        } else {

          if (valueA != null) {
            final Element element;
            if (namespaceProperty != null) {
              element = document.createElementNS(namespaceProperty, nameProperty);
            } else {
              element = document.createElement(nameProperty);
            }
            if (prefix != null) {
              element.setPrefix(prefix.prefix);
            }
            Geometry isoGeometry =
                JTSUtils.toISO(
                    (com.vividsolutions.jts.geom.Geometry) valueA,
                    type.getCoordinateReferenceSystem());
            Marshaller marshaller = null;
            try {
              marshaller = POOL.acquireMarshaller();
              marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
              marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
              marshaller.marshal(OBJECT_FACTORY.buildAnyGeometry(isoGeometry), element);
            } catch (JAXBException ex) {
              LOGGER.log(
                  Level.WARNING,
                  "JAXB Exception while marshalling the iso geometry: " + ex.getMessage(),
                  ex);
            } finally {
              if (marshaller != null) {
                POOL.release(marshaller);
              }
            }
            rootElement.appendChild(element);
          }
        }
      }
    }

    // writer.writeEndElement();
    return rootElement;
  }
    @Override
    public Object invokeProjection(
        final String resolvedXpath, final Object proxy, final Object[] args) throws Throwable {
      //   final String pathToElement = resolvedXpath.replaceAll("\\[@",
      // "[attribute::").replaceAll("/?@.*", "").replaceAll("\\[attribute::", "[@");
      lastInvocationContext.updateMethodArgs(args);
      final Document document = DOMHelper.getOwnerDocumentFor(node);
      assert document != null;
      final Object valueToSet = args[findIndexOfValue];
      final boolean isMultiValue = isMultiValue(method.getParameterTypes()[findIndexOfValue]);
      // ROOT element update
      if ("/*".equals(resolvedXpath)) { // Setting a new root element.
        if (isMultiValue) {
          throw new IllegalArgumentException(
              "Method "
                  + method
                  + " was invoked as setter changing the document root element, but tries to set multiple values.");
        }
        return handeRootElementReplacement(proxy, method, document, valueToSet);
      }
      final boolean wildCardTarget = resolvedXpath.endsWith("/*");
      try {
        if (!lastInvocationContext.isStillValid(resolvedXpath)) {
          final DuplexExpression duplexExpression =
              wildCardTarget
                  ? new DuplexXPathParser(projector.config().getUserDefinedNamespaceMapping())
                      .compile(resolvedXpath.substring(0, resolvedXpath.length() - 2))
                  : new DuplexXPathParser(projector.config().getUserDefinedNamespaceMapping())
                      .compile(resolvedXpath);
          MethodParamVariableResolver resolver = null;
          if (duplexExpression.isUsingVariables()) {
            resolver =
                new MethodParamVariableResolver(
                    method, args, duplexExpression, projector.config().getStringRenderer(), null);
            duplexExpression.setXPathVariableResolver(resolver);
          }
          Class<?> targetComponentType = findTargetComponentType(method);
          lastInvocationContext =
              new InvocationContext(
                  resolvedXpath,
                  null,
                  null,
                  duplexExpression,
                  resolver,
                  targetComponentType,
                  projector);
        }
        final DuplexExpression duplexExpression = lastInvocationContext.getDuplexExpression();
        if (duplexExpression.getExpressionType().isMustEvalAsString()) {
          throw new XBPathException("Unwriteable xpath selector used ", method, resolvedXpath);
        }
        // MULTIVALUE
        if (isMultiValue) {
          if (duplexExpression.getExpressionType().equals(ExpressionType.ATTRIBUTE)) {
            throw new IllegalArgumentException(
                "Method "
                    + method
                    + " was invoked as setter changing some attribute, but was declared to set multiple values. I can not create multiple attributes for one path.");
          }
          final Iterable<?> iterable2Set =
              valueToSet == null
                  ? Collections.emptyList()
                  : (valueToSet.getClass().isArray())
                      ? ReflectionHelper.array2ObjectList(valueToSet)
                      : (Iterable<?>) valueToSet;
          if (wildCardTarget) {
            // TODO: check support of ParameterizedType e.g. Supplier
            final Element parentElement = (Element) duplexExpression.ensureExistence(node);
            DOMHelper.removeAllChildren(parentElement);
            int count = 0;
            for (Object o : iterable2Set) {
              if (o == null) {
                continue;
              }
              ++count;
              if (o instanceof Node) {
                DOMHelper.appendClone(parentElement, (Node) o);
                continue;
              }
              if (o instanceof DOMAccess) {
                DOMHelper.appendClone(parentElement, ((DOMAccess) o).getDOMBaseElement());
                continue;
              }
              throw new XBPathException(
                  "When using a wildcard target, the type to set must be a DOM Node or another projection. Otherwise I can not determine the element name.",
                  method,
                  resolvedXpath);
            }
            return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(count));
          }
          final Element parentElement = duplexExpression.ensureParentExistence(node);
          duplexExpression.deleteAllMatchingChildren(parentElement);
          int count = applyIterableSetOnElement(iterable2Set, parentElement, duplexExpression);
          return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(count));
        }

        // ATTRIBUTES
        if (duplexExpression.getExpressionType().equals(ExpressionType.ATTRIBUTE)) {
          if (wildCardTarget) {
            // TODO: This may never happen, right?
            throw new XBPathException(
                "Wildcards are not allowed when writing to an attribute. I need to know to which Element I should set the attribute",
                method,
                resolvedXpath);
          }
          Attr attribute = (Attr) duplexExpression.ensureExistence(node);
          if (valueToSet == null) {
            attribute.getOwnerElement().removeAttributeNode(attribute);
            return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(1));
          }

          DOMHelper.setStringValue(attribute, valueToSet.toString());
          return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(1));
        }

        if ((valueToSet instanceof Node) || (valueToSet instanceof DOMAccess)) {
          if (valueToSet instanceof Attr) {
            if (wildCardTarget) {
              throw new XBPathException(
                  "Wildcards are not allowed when writing an attribute. I need to know to which Element I should set the attribute",
                  method,
                  resolvedXpath);
            }
            Element parentNode = duplexExpression.ensureParentExistence(node);
            if (((Attr) valueToSet).getNamespaceURI() != null) {
              parentNode.setAttributeNodeNS((Attr) valueToSet);
              return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(1));
            }
            parentNode.setAttributeNode((Attr) valueToSet);
            return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(1));
          }
          final Element newNodeOrigin =
              valueToSet instanceof DOMAccess
                  ? ((DOMAccess) valueToSet).getDOMBaseElement()
                  : (Element) valueToSet;
          final Element newNode = (Element) newNodeOrigin.cloneNode(true);
          DOMHelper.ensureOwnership(document, newNode);
          if (wildCardTarget) {
            Element parentElement = (Element) duplexExpression.ensureExistence(node);
            DOMHelper.removeAllChildren(parentElement);
            parentElement.appendChild(newNode);
            return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(1));
          }
          Element previousElement = (Element) duplexExpression.ensureExistence(node);

          DOMHelper.replaceElement(previousElement, newNode);
          return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(1));
        }

        final Element elementToChange = (Element) duplexExpression.ensureExistence(node);
        if (valueToSet == null) {
          // TODO: This should depend on the parameter type?
          // If param type == String, no structural change might be expected.
          DOMHelper.removeAllChildren(elementToChange);
        } else {
          final String asString =
              projector
                  .config()
                  .getStringRenderer()
                  .render(
                      valueToSet.getClass(),
                      valueToSet,
                      duplexExpression.getExpressionFormatPattern());
          elementToChange.setTextContent(asString);
        }
        return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(1));
      } catch (XBPathParsingException e) {
        throw new XBPathException(e, method, resolvedXpath);
      }
    }
 @Kroll.method
 public AttrProxy setAttributeNodeNS(AttrProxy newAttr) throws DOMException {
   return getProxy(element.setAttributeNodeNS(newAttr.getAttr()));
 }