示例#1
0
void XercesUpdateFactory::applyReplaceElementContent(const PendingUpdate &update, DynamicContext *context)
{
  const XercesNodeImpl *nodeImpl = (const XercesNodeImpl*)update.getTarget()->getInterface(Item::gXQilla);
  DOMElement *domnode = (DOMElement*)nodeImpl->getDOMNode();

  // 1. For each node $C that is a child of $target, the parent property of $C is set to empty.
  DOMNode *child = domnode->getFirstChild();
  while(child != 0) {
    forDeletion_.insert(child);
    child = child->getNextSibling();
  }

  const XMLCh *value = update.getValue().first()->asString(context);
  if(value != 0 && *value != 0) {
    // 2. The parent property of $text is set to $target.
    // 3a. children is set to consist exclusively of $text. If $text is an empty sequence, then $target has
    //     no children.
    // 3b. typed-value and string-value are set to the content property of $text. If $text is an empty sequence,
    //     then typed-value is an empty sequence and string-value is an empty string.
    domnode->appendChild(domnode->getOwnerDocument()->createTextNode(value));
  }

  // 3c. upd:removeType($target) is invoked.
  removeType(domnode);

  addToPutSet(update.getTarget(), &update, context);
}
示例#2
0
void XercesUpdateFactory::applyReplaceAttribute(const PendingUpdate &update, DynamicContext *context)
{
  const XercesNodeImpl *nodeImpl = (const XercesNodeImpl*)update.getTarget()->getInterface(Item::gXQilla);
  DOMAttr *domnode = (DOMAttr*)nodeImpl->getDOMNode();
  Node::Ptr parentNode = nodeImpl->dmParent(context);
  DOMElement *element = domnode->getOwnerElement();
  DOMDocument *doc = element->getOwnerDocument();

  bool untyped = parentNode->dmNodeKind() == Node::element_string &&
    XPath2Utils::equals(parentNode->getTypeName(), DocumentCache::g_szUntyped) &&
    XPath2Utils::equals(parentNode->getTypeURI(), SchemaSymbols::fgURI_SCHEMAFORSCHEMA);

  Result children = update.getValue();
  Item::Ptr item;
  while((item = children->next(context)).notNull()) {
    const XercesNodeImpl *childImpl = (const XercesNodeImpl*)item->getInterface(Item::gXQilla);
    DOMNode *newChild = importNodeFix(doc, const_cast<DOMNode*>(childImpl->getDOMNode()), /*deep*/true);

    // 1. Error checks:
    //    a. If the QNames of any two attribute nodes in $replacement have implied namespace bindings that conflict with
    //       each other, a dynamic error is raised [err:XUDY0024].
    //    b. If the QName of any attribute node in $replacement has an implied namespace binding that conflicts with a
    //       namespace binding in the "namespaces" property of parent($target), a dynamic error is raised [err:XUDY0024].
    // Checks performed by UpdateFactory

    // 2b. If the type-name property of parent($target) is xs:untyped, then upd:setToUntyped() is invoked
    //     on each element node in $replacement.
    if(!untyped) setTypes(newChild, childImpl->getDOMNode());

    // 2a. For each node in $replacement, the parent property is set to parent($target).
    // 4a. If $target is an attribute node, the attributes property of parent($target) is modified by removing $target
    //     and adding the nodes in $replacement (if any).
    // 4b. If $target is an attribute node, the namespaces property of parent($target) is modified to include namespace
    //     bindings for any attribute namespace prefixes in $replacement that did not already have bindings.
    element->setAttributeNode((DOMAttr*)newChild);
  }

  // 3a. $target is marked for deletion.
  forDeletion_.insert(domnode);

  // 4d. upd:removeType(parent($target)) is invoked.
  removeType(element);

  // Use parentNode, since the attr replace could have removed the original attr
  addToPutSet(parentNode, &update, context);
}
示例#3
0
Override::Override(const DOMElement* e, Category& log, const Override* base) : m_base(base), m_acl(NULL)
{
    try {
        // Load the property set.
        load(e,log,this);
        
        // Load any AccessControl provider.
        loadACL(e,log);
    
        // Handle nested Paths.
        DOMElement* path = XMLHelper::getFirstChildElement(e,Path);
        for (int i=1; path; ++i, path=XMLHelper::getNextSiblingElement(path,Path)) {
            const XMLCh* n=path->getAttributeNS(NULL,name);
            
            // Skip any leading slashes.
            while (n && *n==chForwardSlash)
                n++;
            
            // Check for empty name.
            if (!n || !*n) {
                log.warn("skipping Path element (%d) with empty name attribute", i);
                continue;
            }

            // Check for an embedded slash.
            int slash=XMLString::indexOf(n,chForwardSlash);
            if (slash>0) {
                // Copy the first path segment.
                XMLCh* namebuf=new XMLCh[slash + 1];
                for (int pos=0; pos < slash; pos++)
                    namebuf[pos]=n[pos];
                namebuf[slash]=chNull;
                
                // Move past the slash in the original pathname.
                n=n+slash+1;
                
                // Skip any leading slashes again.
                while (*n==chForwardSlash)
                    n++;
                
                if (*n) {
                    // Create a placeholder Path element for the first path segment and replant under it.
                    DOMElement* newpath=path->getOwnerDocument()->createElementNS(shibspconstants::SHIB2SPCONFIG_NS,Path);
                    newpath->setAttributeNS(NULL,name,namebuf);
                    path->setAttributeNS(NULL,name,n);
                    path->getParentNode()->replaceChild(newpath,path);
                    newpath->appendChild(path);
                    
                    // Repoint our locals at the new parent.
                    path=newpath;
                    n=path->getAttributeNS(NULL,name);
                }
                else {
                    // All we had was a pathname with trailing slash(es), so just reset it without them.
                    path->setAttributeNS(NULL,name,namebuf);
                    n=path->getAttributeNS(NULL,name);
                }
                delete[] namebuf;
            }
            
            Override* o=new Override(path,log,this);
            pair<bool,const char*> name=o->getString("name");
            char* dup=strdup(name.second);
            for (char* pch=dup; *pch; pch++)
                *pch=tolower(*pch);
            if (m_map.count(dup)) {
                log.warn("Skipping duplicate Path element (%s)",dup);
                free(dup);
                delete o;
                continue;
            }
            m_map[dup]=o;
            free(dup);
        }
    }
    catch (exception&) {
        delete m_acl;
        for_each(m_map.begin(),m_map.end(),xmltooling::cleanup_pair<string,Override>());
        throw;
    }
}