1 package net.sf.saxon.value; 2 3 import net.sf.saxon.Configuration; 4 import net.sf.saxon.ConversionContext; 5 import net.sf.saxon.expr.XPathContext; 6 import net.sf.saxon.expr.StaticContext; 7 import net.sf.saxon.functions.Component; 8 import net.sf.saxon.om.NamePool; 9 import net.sf.saxon.om.XMLChar; 10 import net.sf.saxon.om.Name; 11 import net.sf.saxon.om.QNameException; 12 import net.sf.saxon.style.StandardNames; 13 import net.sf.saxon.trans.DynamicError; 14 import net.sf.saxon.trans.XPathException; 15 import net.sf.saxon.trans.StaticError; 16 import net.sf.saxon.type.*; 17 18 import java.lang.reflect.Constructor ; 19 import java.lang.reflect.InvocationTargetException ; 20 21 22 27 28 public class QNameValue extends AtomicValue { 29 30 private String prefix; private String uri; private String localPart; 33 34 38 43 44 public QNameValue(NamePool namePool, int nameCode) { 45 prefix = namePool.getPrefix(nameCode); 46 uri = namePool.getURI(nameCode); 47 localPart = namePool.getLocalName(nameCode); 48 } 49 50 57 58 public QNameValue(String prefix, String uri, String localName) throws XPathException { 59 if (!XMLChar.isValidNCName(localName)) { 60 DynamicError err = new DynamicError("Malformed local name in QName: '" + localName + '\''); 61 err.setErrorCode("FORG0001"); 62 throw err; 63 } 64 this.prefix = (prefix==null ? "" : prefix); 65 this.uri = (uri==null ? "" : uri); 66 this.localPart = localName; 67 } 68 69 78 79 public static AtomicValue castToQName(StringValue operand, AtomicType targetType, StaticContext env) 80 throws XPathException { 81 try { 82 CharSequence arg = operand.getStringValueCS(); 83 String parts[] = Name.getQNameParts(arg); 84 String uri; 85 if ("".equals(parts[0])) { 86 uri = ""; 87 } else { 88 uri = env.getURIForPrefix(parts[0]); 89 if (uri==null) { 90 StaticError e = new StaticError("Prefix '" + parts[0] + "' has not been declared"); 91 throw e; 92 } 93 } 94 if (targetType.getFingerprint() == StandardNames.XS_QNAME) { 95 return new QNameValue(parts[0], uri, parts[1]); 96 } else if (Type.isSubType(targetType, Type.QNAME_TYPE)) { 97 QNameValue q = new QNameValue(parts[0], uri, parts[1]); 98 AtomicValue av = targetType.makeDerivedValue(q, arg, true); 99 if (av instanceof ValidationErrorValue) { 100 throw ((ValidationErrorValue)av).getException(); 101 } 102 return av; 103 } else { 104 NotationValue n = new NotationValue(parts[0], uri, parts[1]); 105 AtomicValue av = targetType.makeDerivedValue(n, arg, true); 106 if (av instanceof ValidationErrorValue) { 107 throw ((ValidationErrorValue)av).getException(); 108 } 109 return av; 110 } 111 } catch (QNameException err) { 112 StaticError e = new StaticError(err); 113 throw e; 114 } 115 } 116 117 118 122 123 public String getStringValue() { 124 if ("".equals(prefix)) { 125 return localPart; 126 } else { 127 return prefix + ':' + localPart; 128 } 129 } 130 131 134 135 139 142 143 public String getClarkName() { 144 if ("".equals(uri)) { 145 return localPart; 146 } else { 147 return '{' + uri + '}' + localPart; 148 } 149 } 150 151 154 155 public String getLocalName() { 156 return localPart; 157 } 158 159 162 163 public String getNamespaceURI() { 164 return ("".equals(uri) ? null : uri); 165 } 166 167 170 171 public String getPrefix() { 172 return prefix; 173 } 174 175 180 181 public int allocateNameCode(NamePool pool) { 182 return pool.allocate(prefix, uri, localPart); 183 } 184 185 192 193 public AtomicValue getComponent(int part) { 194 if (part == Component.LOCALNAME) { 195 return RestrictedStringValue.makeRestrictedString( 196 localPart, StandardNames.XS_NCNAME, false); 197 } else if (part == Component.NAMESPACE) { 198 return new AnyURIValue(uri); 199 } else if (part == Component.PREFIX) { 200 return RestrictedStringValue.makeRestrictedString( 201 prefix, StandardNames.XS_NCNAME, false); 202 } else { 203 throw new UnsupportedOperationException ("Component of QName must be URI, Local Name, or Prefix"); 204 } 205 } 206 207 213 214 public AtomicValue convertPrimitive(BuiltInAtomicType requiredType, boolean validate, ConversionContext conversion) { 215 switch (requiredType.getPrimitiveType()) { 216 case Type.ATOMIC: 217 case Type.ITEM: 218 case Type.QNAME: 219 return this; 220 case Type.STRING: 221 return new StringValue(getStringValue()); 222 case Type.UNTYPED_ATOMIC: 223 return new UntypedAtomicValue(getStringValue()); 224 default: 225 ValidationException err = new ValidationException("Cannot convert QName to " + 226 requiredType.getDisplayName()); 227 err.setErrorCode("FORG0001"); 229 return new ValidationErrorValue(err); 230 } 231 } 232 233 237 238 public ItemType getItemType() { 239 return Type.QNAME_TYPE; 240 } 241 242 243 249 250 public boolean equals(Object other) { 251 QNameValue val = (QNameValue) other; 252 return localPart.equals(val.localPart) && uri.equals(val.uri); 253 } 254 255 public int hashCode() { 256 return localPart.hashCode() ^ uri.hashCode(); 257 } 258 259 260 263 264 public Object convertToJava(Class target, XPathContext context) throws XPathException { 265 if (target.isAssignableFrom(QNameValue.class)) { 266 return this; 267 } else if (target.getClass().getName().equals("javax.xml.namespace.QName")) { 268 return makeQName(context.getController().getConfiguration()); 270 } else { 271 Object o = super.convertToJava(target, context); 272 if (o == null) { 273 throw new DynamicError("Conversion of QName to " + target.getName() + 274 " is not supported"); 275 } 276 return o; 277 } 278 } 279 280 284 285 public String toString() { 286 return "QName(\"" + uri + "\", \"" + localPart + "\")"; 287 } 288 289 293 294 public Object makeQName(Configuration config) { 295 try { 296 Class qnameClass = config.getClass("javax.xml.namespace.QName", false, null); 297 Class [] argTypes = {String .class, String .class, String .class}; 298 Constructor constructor = qnameClass.getConstructor(argTypes); 299 String [] argValues = {uri, localPart, prefix}; 300 Object result = constructor.newInstance(argValues); 301 return result; 302 } catch (XPathException e) { 303 return null; 304 } catch (NoSuchMethodException e) { 305 return null; 306 } catch (InstantiationException e) { 307 return null; 308 } catch (IllegalAccessException e) { 309 return null; 310 } catch (InvocationTargetException e) { 311 return null; 312 } 313 314 } 315 316 323 } 324 325 343 | Popular Tags |