| /* Generated By:JJTree: Do not edit this line. Instanceof.java */ |
| |
| package org.apache.xpath.types; |
| |
| import java.io.PrintStream; |
| import java.util.Vector; |
| import javax.xml.transform.TransformerException; |
| |
| import org.apache.xml.dtm.DTM; |
| import org.apache.xml.dtm.DTMFilter; |
| import org.apache.xml.dtm.XType; |
| import org.apache.xml.utils.QName; |
| import org.apache.xpath.Expression; |
| import org.apache.xpath.ExpressionNode; |
| import org.apache.xpath.ExpressionOwner; |
| import org.apache.xpath.VariableComposeState; |
| import org.apache.xpath.XPathContext; |
| import org.apache.xpath.XPathVisitor; |
| import org.apache.xpath.objects.XBoolean; |
| import org.apache.xpath.objects.XNodeSet; |
| import org.apache.xpath.objects.XObject; |
| import org.apache.xpath.objects.XSequence; |
| import org.apache.xpath.parser.Node; |
| import org.apache.xpath.parser.SchemaContext; |
| import org.apache.xpath.parser.SequenceType; |
| import org.apache.xpath.parser.SimpleNode; |
| import org.apache.xpath.parser.XPath; |
| |
| /** |
| * This class implements the "instance of" production for XPath 2.0. |
| * |
| * <p>(For easy reference, until the spec is more stable...)</p> |
| * <pre> |
| * [9] InstanceofExpr ::= {Expr} ( <"instance" "of"> SequenceType )? |
| * [51] SequenceType ::= (ItemType OccurrenceIndicator) | "empty" |
| * [52] ItemType ::= (("element" | "attribute") ElemOrAttrType?) |
| * | "node" |
| * | "processing-instruction" |
| * | "comment" |
| * | "text" |
| * | "document" |
| * | "item" |
| * | AtomicType |
| * | "untyped" |
| * | <"atomic" "value"> |
| * [53] ElemOrAttrType ::= (QName (SchemaType | SchemaContext?)) | SchemaType |
| * [54] SchemaType ::= <"of" "type"> QName |
| * [55] AtomicType ::= QName |
| * [56] OccurrenceIndicator ::= ("*" | "+" | "?")? |
| * </pre> |
| * |
| * <p>Notes to Joe: You can call just the parser to give a diagnostic dump |
| * of the expression by calling org.apache.xpath.parser.XPath.main() with |
| * an argument of a an expression string (quote it): "foo instance of xsd:integer". |
| * This will dump out thus:</p> |
| * <pre> |
| * Test[0]: foo instance of xsd:integer |
| * |instance of |
| * | child::foo org.apache.xpath.axes.ChildTestIterator |
| * | m_atomicTypeID: 2 |
| * | m_elemOrAttrName: null |
| * | m_occurrenceIndicator: 2 |
| * | m_schemaContext: null |
| * | m_schemaTypeName: null |
| * | m_whatToShow: 0 |
| * Success!!!! |
| * I've only tested: |
| * "foo instance of xsd:integer" |
| * "foo instance of element of type baz" |
| * "foo instance of element yada of type baz" |
| * "foo instance of node" |
| * "foo instance of text" |
| * "foo instance of comment" |
| * "foo instance of untyped" |
| * </pre> |
| * |
| * <p>It's highly likely that there are bugs in the construction with |
| * other expressions. Come get me if that happens.</p> |
| * <p>SchemaContext & co is unimplemented right now. Don't worry about |
| * it for right now.</p> |
| * |
| * Created Jul 17, 2002 |
| * @author sboag |
| */ |
| public class InstanceofExpr extends Expression implements ExpressionOwner |
| { |
| /** The sequence on which to act. **/ |
| private Expression m_targetExpr; |
| |
| /** The node type value, one of DTMFilter.SHOW_ATTRIBUTE, etc. |
| * %REVIEW% Why isn't this just the node type? **/ |
| private int m_whatToShow; |
| |
| /** The atomic type ID, one of XType.BOOLEAN, etc. **/ |
| private int m_atomicTypeID; |
| |
| // Occurence indicator ID values. |
| public static final int ZERO_OR_MORE = 1; |
| public static final int ONE_OR_MORE = 2; |
| public static final int ZERO_OR_ONE = 3; |
| public static final int EMPTY_SEQ = 4; |
| |
| /** The occurance indicator ID. One of ZERO_OR_MORE, etc. or EMPTY_SEQ **/ |
| private int m_occurrenceIndicator = ONE_OR_MORE; |
| |
| /** The ElemOrAttrType name, meaning the tag QName, may be null. */ |
| private QName m_elemOrAttrName; |
| |
| /** The SchemaType name, meaning the tag QName, may be null. */ |
| private QName m_schemaTypeName; |
| |
| /** SchemaContext is not executable for the moment, so leave it |
| * as a NEE until we figure out what we want to do with it. **/ |
| private SchemaContext m_schemaContext; |
| |
| public InstanceofExpr() { |
| super(); |
| |
| } |
| |
| /** Accept the visitor. **/ |
| public Object jjtAccept(org.apache.xpath.parser.XPathVisitor visitor, Object data) { |
| return visitor.visit(this, data); |
| } |
| |
| /** |
| * @see Expression#deepEquals(Expression) |
| */ |
| public boolean deepEquals(Expression expr) |
| { |
| if(!(expr instanceof InstanceofExpr)) |
| return false; |
| return false; |
| } |
| |
| /** |
| * @see Expression#fixupVariables(Vector, int) |
| */ |
| public void fixupVariables(VariableComposeState vcs) |
| { |
| m_targetExpr.fixupVariables(vcs); |
| } |
| |
| |
| /** |
| * @see Expression#execute(XPathContext) |
| */ |
| public XObject execute(XPathContext xctxt) throws TransformerException |
| { |
| // m_atomicTypeID: Integer XType primitive, IFF no m_schemaTypeName |
| // m_schemaContext: SchemaContext, UNSPECIFIED AT THIS TIME |
| // and hence unsupported. |
| boolean isInstance=true; |
| |
| XObject value=m_targetExpr.execute(xctxt); |
| |
| |
| switch(value.getType()) |
| { |
| case XObject.CLASS_UNKNOWN: |
| // If not XSLT type, can't be instance of ...? |
| // %REVIEW% what SHOW_ITEM and SHOW_UNTYPED mean |
| case XObject.CLASS_NULL: |
| isInstance=false; |
| break; |
| |
| case XObject.CLASS_NODESET: |
| case XObject.CLASS_RTREEFRAG: |
| int len=0; |
| XSequence valNodeSet= value.xseq(); |
| for( XObject next=valNodeSet.next(); |
| isInstance && next!=null; |
| next=valNodeSet.next(),++len) |
| { |
| int handle = next.getNodeHandle(); |
| if(DTM.NULL == handle) |
| continue; |
| if(m_whatToShow!=0) |
| { |
| int nodetype=xctxt.getDTM(handle).getNodeType(handle); |
| if(0==(m_whatToShow & 1<<(nodetype-1))) |
| isInstance=false; |
| else if(m_elemOrAttrName!=null) |
| { |
| isInstance&= |
| (m_elemOrAttrName.getNamespace/*URI*/() |
| ==xctxt.getDTM(handle).getNamespaceURI(handle)) |
| && |
| (m_elemOrAttrName.getLocalName() |
| ==xctxt.getDTM(handle).getLocalName(handle)); |
| } |
| } |
| if(m_schemaTypeName!=null) |
| { |
| isInstance&= |
| xctxt.getDTM(handle).isNodeSchemaType( |
| handle, |
| m_schemaTypeName.getNamespaceURI(), |
| m_schemaTypeName.getLocalName()); |
| } |
| else if(m_atomicTypeID!=0) |
| { |
| // Unless DTM implements awareness of these |
| // typenumbers, or our sequence/nodeset layers |
| // handle this for us, we need to convert back |
| // to strings. We also have to convert from the |
| // Schema_datatype namespace, used in requesting the |
| // primitive, to the Schema namespace used when |
| // the node was declared. |
| isInstance&= |
| xctxt.getDTM(handle).isNodeSchemaType( |
| handle, |
| XType.XMLSCHEMA_NAMESPACE, |
| XType.getLocalNameFromType(m_atomicTypeID)); |
| } |
| } // End scan contents |
| switch(m_occurrenceIndicator) |
| { |
| case ZERO_OR_MORE: |
| break; // Anything is OK |
| case ONE_OR_MORE: |
| isInstance&=(len>=1); |
| break; |
| case ZERO_OR_ONE: |
| isInstance&=(len<2); |
| break; |
| case EMPTY_SEQ: |
| isInstance&=(len==0); |
| break; |
| } |
| break; |
| |
| case XObject.CLASS_BOOLEAN: |
| isInstance&=(m_elemOrAttrName==null); |
| isInstance&=(m_schemaTypeName==null); |
| isInstance&=(m_whatToShow==0); |
| isInstance&=(m_atomicTypeID==XType.BOOLEAN); |
| break; |
| |
| case XObject.CLASS_NUMBER: |
| isInstance&=(m_elemOrAttrName==null); |
| isInstance&=(m_schemaTypeName==null); |
| isInstance&=(m_whatToShow==0); |
| // %REVIEW% XNumber is just that, a number. |
| // We want *it* to tell *us* whether it's straight |
| // decimal or double or whatever...? |
| isInstance&=(m_atomicTypeID==XType.DECIMAL |
| || m_atomicTypeID==XType.DOUBLE); |
| break; |
| |
| case XObject.CLASS_STRING: |
| isInstance&=(m_elemOrAttrName==null); |
| isInstance&=(m_schemaTypeName==null); |
| isInstance&=(m_whatToShow==0); |
| isInstance&=(m_atomicTypeID==XType.STRING); |
| break; |
| |
| default: |
| // Should never arise |
| isInstance=false; |
| break; |
| } |
| |
| return isInstance ? XBoolean.S_TRUE : XBoolean.S_FALSE; |
| } |
| |
| |
| /** |
| * @see XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor) |
| */ |
| public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) |
| { |
| m_targetExpr.callVisitors(this, visitor); |
| } |
| |
| |
| /** |
| * @see ExpressionOwner#getExpression() |
| */ |
| public Expression getExpression() |
| { |
| return m_targetExpr; |
| } |
| |
| |
| /** |
| * @see ExpressionOwner#setExpression(Expression) |
| */ |
| public void setExpression(Expression exp) |
| { |
| m_targetExpr = exp; |
| } |
| |
| /** |
| * @see SimpleNode#shouldReduceIfOneChild() |
| */ |
| public boolean shouldReduceIfOneChild() |
| { |
| return (m_whatToShow == 0 && m_atomicTypeID == 0) ? true : false; |
| } |
| |
| |
| /** |
| * Returns the occurrenceIndicator. |
| * @return int |
| */ |
| public int getOccurrenceIndicator() |
| { |
| return m_occurrenceIndicator; |
| } |
| |
| /** |
| * Returns the schemaContext. |
| * @return SchemaContext |
| */ |
| public SchemaContext getSchemaContext() |
| { |
| return m_schemaContext; |
| } |
| |
| /** |
| * Returns the schemaTypeName. |
| * @return QName |
| */ |
| public QName getSchemaTypeName() |
| { |
| return m_schemaTypeName; |
| } |
| |
| /** |
| * Returns the targetExpr. |
| * @return Expression |
| */ |
| public Expression getTargetExpr() |
| { |
| return m_targetExpr; |
| } |
| |
| /** |
| * Returns the whatToShow. |
| * @return int |
| */ |
| public int getWhatToShow() |
| { |
| return m_whatToShow; |
| } |
| |
| /** |
| * Sets the occurrenceIndicator. |
| * @param occurrenceIndicator The occurrenceIndicator to set |
| */ |
| public void setOccurrenceIndicator(int occurrenceIndicator) |
| { |
| m_occurrenceIndicator = occurrenceIndicator; |
| } |
| |
| /** |
| * Sets the schemaContext. |
| * @param schemaContext The schemaContext to set |
| */ |
| public void setSchemaContext(SchemaContext schemaContext) |
| { |
| m_schemaContext = schemaContext; |
| } |
| |
| /** |
| * Sets the schemaTypeName. |
| * @param schemaTypeName The schemaTypeName to set |
| */ |
| public void setSchemaTypeName(QName schemaTypeName) |
| { |
| m_schemaTypeName = schemaTypeName; |
| } |
| |
| /** |
| * Sets the targetExpr. |
| * @param targetExpr The targetExpr to set |
| */ |
| public void setTargetExpr(Expression targetExpr) |
| { |
| m_targetExpr = targetExpr; |
| } |
| |
| /** |
| * Sets the whatToShow. |
| * @param whatToShow The whatToShow to set |
| */ |
| public void setWhatToShow(int whatToShow) |
| { |
| m_whatToShow = whatToShow; |
| } |
| |
| /** |
| * @see org.apache.xpath.parser.Node#jjtAddChild(Node, int) |
| */ |
| public void jjtAddChild(Node n, int i) |
| { |
| if(0 == i) |
| { |
| n = this.fixupPrimarys(n); |
| m_targetExpr = (Expression)n; |
| } |
| else if(2 == i) // skip the child at index 1, which is the instance of keyword. |
| { |
| SequenceType stype = (SequenceType)n; |
| m_atomicTypeID = stype.getAtomicTypeID(); |
| m_elemOrAttrName = stype.getElemOrAttrName(); |
| m_occurrenceIndicator = stype.getOccurrenceIndicator(); |
| m_schemaContext = stype.getSchemaContext(); |
| m_schemaTypeName = stype.getSchemaTypeName(); |
| m_whatToShow = stype.getWhatToShow(); |
| } |
| } |
| |
| /** |
| * @see org.apache.xpath.ExpressionNode#exprGetChild(int) |
| */ |
| public ExpressionNode exprGetChild(int i) |
| { |
| // This doesn't work perfectly, but it's good enough. |
| return (0 == i) ? m_targetExpr : (1 == 0) ? m_schemaContext : null; |
| } |
| |
| /** |
| * @see org.apache.xpath.ExpressionNode#exprGetNumChildren() |
| */ |
| public int exprGetNumChildren() |
| { |
| // This doesn't work perfectly, but it's good enough. |
| return ((null == m_targetExpr) ? 1 : 0)+((null == m_schemaContext) ? 1 : 0); |
| } |
| |
| /** |
| * @see org.apache.xpath.parser.SimpleNode#dump(String, PrintStream) |
| */ |
| public void dump(String prefix, PrintStream ps) |
| { |
| super.dump(prefix, ps); |
| prefix = prefix+" "; |
| ps.print(prefix); |
| ps.println("m_atomicTypeID: "+m_atomicTypeID); |
| ps.print(prefix); |
| ps.println("m_elemOrAttrName: "+m_elemOrAttrName); |
| ps.print(prefix); |
| ps.println("m_occurrenceIndicator: "+m_occurrenceIndicator); |
| ps.print(prefix); |
| ps.println("m_schemaContext: "+m_schemaContext); |
| ps.print(prefix); |
| ps.println("m_schemaTypeName: "+m_schemaTypeName); |
| ps.print(prefix); |
| ps.println("m_whatToShow: "+m_whatToShow); |
| } |
| |
| /** |
| * @see java.lang.Object#toString() |
| */ |
| public String toString() |
| { |
| return "instance of"; |
| } |
| |
| } |