1 package net.sf.saxon.expr; 2 import net.sf.saxon.om.Item; 3 import net.sf.saxon.om.NamePool; 4 import net.sf.saxon.om.NodeInfo; 5 import net.sf.saxon.om.SequenceIterator; 6 import net.sf.saxon.pattern.NoNodeTest; 7 import net.sf.saxon.pattern.NodeTest; 8 import net.sf.saxon.trans.XPathException; 9 import net.sf.saxon.type.*; 10 import net.sf.saxon.value.AtomicValue; 11 import net.sf.saxon.value.EmptySequence; 12 import net.sf.saxon.value.Value; 13 14 20 21 public final class SingletonAtomizer extends UnaryExpression { 22 23 private boolean allowEmpty; 24 private RoleLocator role; 25 26 31 32 public SingletonAtomizer(Expression sequence, RoleLocator role, boolean allowEmpty) { 33 super(sequence); 34 this.allowEmpty = allowEmpty; 35 this.role = role; 36 } 37 38 41 42 public Expression simplify(StaticContext env) throws XPathException { 43 operand = operand.simplify(env); 44 if (operand instanceof AtomicValue) { 45 return operand; 46 } 47 return this; 48 } 49 50 53 54 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 55 operand = operand.typeCheck(env, contextItemType); 56 resetStaticProperties(); 57 if (operand instanceof EmptySequence) { 58 if(!allowEmpty) { 59 typeError("An empty sequence is not allowed as the " + 60 role.getMessage(), role.getErrorCode(), null); 61 } 62 return operand; 63 } 64 if (Type.isSubType(operand.getItemType(), Type.ANY_ATOMIC_TYPE)) { 65 return operand; 66 } 67 return this; 68 } 69 70 71 75 76 public int computeSpecialProperties() { 77 int p = super.computeSpecialProperties(); 78 return p | StaticProperty.NON_CREATIVE; 79 } 80 81 85 86 public Item evaluateItem(XPathContext context) throws XPathException { 87 int found = 0; 88 Item result = null; 89 SequenceIterator iter = operand.iterate(context); 90 while (true) { 91 Item item = iter.next(); 92 if (item == null) { 93 break; 94 } 95 if (item instanceof AtomicValue) { 96 if (found++ > 0) { 97 typeError( 98 "A sequence of more than one item is not allowed as the " + 99 role.getMessage(), role.getErrorCode(), context); 100 } 101 result = item; 102 } else { 103 Value value = ((NodeInfo)item).atomize(); 104 found += value.getLength(); 105 if (found > 1) { 106 typeError( 107 "A sequence of more than one item is not allowed as the " + 108 role.getMessage(), role.getErrorCode(), context); 109 } 110 result = value.itemAt(0); 111 } 112 } 113 if (found == 0 && !allowEmpty) { 114 typeError("An empty sequence is not allowed as the " + 115 role.getMessage(), role.getErrorCode(), null); 116 } 117 return result; 118 } 119 120 125 126 public ItemType getItemType() { 127 ItemType in = operand.getItemType(); 128 if (in instanceof AtomicType) { 129 return in; 130 } 131 if (in instanceof NodeTest) { 132 if (in instanceof NoNodeTest) { 134 return in; 135 } 136 int kinds = ((NodeTest)in).getNodeKindMask(); 137 if ((kinds | UNTYPED_KINDS) == UNTYPED_KINDS) { 138 return Type.UNTYPED_ATOMIC_TYPE; 139 } 140 141 SchemaType schemaType = ((NodeTest)in).getContentType(); 142 if (schemaType instanceof SimpleType) { 143 return ((SimpleType)schemaType).getCommonAtomicType(); 144 } else if (((ComplexType)schemaType).isSimpleContent()) { 145 return ((ComplexType)schemaType).getSimpleContentType().getCommonAtomicType(); 146 } else if (schemaType instanceof AnyType) { 147 return Type.ANY_ATOMIC_TYPE; 150 } else { 151 return Type.UNTYPED_ATOMIC_TYPE; 154 } 155 } 156 return Type.ANY_ATOMIC_TYPE; 157 } 158 159 162 private static final int STRING_KINDS = 163 (1<<Type.NAMESPACE) | (1<<Type.COMMENT) | (1<<Type.PROCESSING_INSTRUCTION); 164 165 168 169 private static final int UNTYPED_KINDS = 170 (1<<Type.TEXT) | (1<<Type.DOCUMENT); 171 172 175 176 private static final int UNTYPED_IF_UNTYPED_KINDS = 177 (1<<Type.TEXT) | (1<<Type.ELEMENT) | (1<<Type.DOCUMENT) | (1<<Type.ATTRIBUTE); 178 179 182 183 public int computeCardinality() { 184 if (allowEmpty) { 185 return StaticProperty.ALLOWS_ZERO_OR_ONE; 186 } else { 187 return StaticProperty.EXACTLY_ONE; 188 } 189 } 190 191 195 196 protected String displayOperator(NamePool pool) { 197 return "atomize singleton"; 198 } 199 200 } 201 202 203 204 | Popular Tags |