/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.org.apache.xml.internal.security.transforms.implementations;
import javax.xml.transform.TransformerException;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.security.utils.I18n;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import com.sun.org.apache.xpath.internal.NodeSetDTM;
import com.sun.org.apache.xpath.internal.XPathContext;
import com.sun.org.apache.xpath.internal.functions.Function;
import com.sun.org.apache.xpath.internal.objects.XNodeSet;
import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
The 'here()' function returns a node-set containing the attribute or processing instruction node or the parent element of the text node that directly bears the XPath expression. This expression results in an error if the containing XPath expression does not appear in the same XML document against which the XPath expression is being evaluated. Mainpart is stolen from FuncId.java This does crash under Xalan2.2.D7 and works under Xalan2.2.D9 To get this baby to work, a special trick has to be used. The function needs access to the Node where the XPath expression has been defined. This is done by constructing a FuncHere
which has this Node as 'owner'. See Also: - http://www.w3.org/Signature/Drafts/xmldsig-core/Overview.html#function-here
/**
* The 'here()' function returns a node-set containing the attribute or
* processing instruction node or the parent element of the text node
* that directly bears the XPath expression. This expression results
* in an error if the containing XPath expression does not appear in the
* same XML document against which the XPath expression is being evaluated.
*
* Mainpart is stolen from FuncId.java
*
* This does crash under Xalan2.2.D7 and works under Xalan2.2.D9
*
* To get this baby to work, a special trick has to be used. The function needs
* access to the Node where the XPath expression has been defined. This is done
* by constructing a {@link FuncHere} which has this Node as 'owner'.
*
* @see "http://www.w3.org/Signature/Drafts/xmldsig-core/Overview.html#function-here"
*/
public class FuncHere extends Function {
/**
*
*/
private static final long serialVersionUID = 1L;
The here function returns a node-set containing the attribute or
processing instruction node or the parent element of the text node
that directly bears the XPath expression. This expression results
in an error if the containing XPath expression does not appear in the
same XML document against which the XPath expression is being evaluated.
Params: - xctxt –
Throws: - TransformerException –
Returns: the xobject
/**
* The here function returns a node-set containing the attribute or
* processing instruction node or the parent element of the text node
* that directly bears the XPath expression. This expression results
* in an error if the containing XPath expression does not appear in the
* same XML document against which the XPath expression is being evaluated.
*
* @param xctxt
* @return the xobject
* @throws javax.xml.transform.TransformerException
*/
public XObject execute(XPathContext xctxt)
throws javax.xml.transform.TransformerException {
Node xpathOwnerNode = (Node) xctxt.getOwnerObject();
if (xpathOwnerNode == null) {
return null;
}
int xpathOwnerNodeDTM = xctxt.getDTMHandleFromNode(xpathOwnerNode);
int currentNode = xctxt.getCurrentNode();
DTM dtm = xctxt.getDTM(currentNode);
int docContext = dtm.getDocument();
if (DTM.NULL == docContext) {
error(xctxt, XPATHErrorResources.ER_CONTEXT_HAS_NO_OWNERDOC, null);
}
{
// check whether currentNode and the node containing the XPath expression
// are in the same document
Document currentDoc =
XMLUtils.getOwnerDocument(dtm.getNode(currentNode));
Document xpathOwnerDoc = XMLUtils.getOwnerDocument(xpathOwnerNode);
if (currentDoc != xpathOwnerDoc) {
throw new TransformerException(I18n
.translate("xpath.funcHere.documentsDiffer"));
}
}
XNodeSet nodes = new XNodeSet(xctxt.getDTMManager());
NodeSetDTM nodeSet = nodes.mutableNodeset();
{
int hereNode = DTM.NULL;
switch (dtm.getNodeType(xpathOwnerNodeDTM)) {
case Node.ATTRIBUTE_NODE : {
// returns a node-set containing the attribute
hereNode = xpathOwnerNodeDTM;
nodeSet.addNode(hereNode);
break;
}
case Node.PROCESSING_INSTRUCTION_NODE : {
// returns a node-set containing the processing instruction node
hereNode = xpathOwnerNodeDTM;
nodeSet.addNode(hereNode);
break;
}
case Node.TEXT_NODE : {
// returns a node-set containing the parent element of the
// text node that directly bears the XPath expression
hereNode = dtm.getParent(xpathOwnerNodeDTM);
nodeSet.addNode(hereNode);
break;
}
default :
break;
}
}
/** $todo$ Do I have to do this detach() call? */
nodeSet.detach();
return nodes;
}
No arguments to process, so this does nothing.
Params: - vars –
- globalsSize –
/**
* No arguments to process, so this does nothing.
* @param vars
* @param globalsSize
*/
public void fixupVariables(java.util.Vector vars, int globalsSize) {
// do nothing
}
}