1 package net.sf.saxon.style; 2 import net.sf.saxon.Configuration; 3 import net.sf.saxon.event.LocationProvider; 4 import net.sf.saxon.om.AttributeCollectionImpl; 5 import net.sf.saxon.om.NamePool; 6 import net.sf.saxon.om.NamespaceConstant; 7 import net.sf.saxon.om.NodeInfo; 8 import net.sf.saxon.trans.StaticError; 9 import net.sf.saxon.tree.ElementImpl; 10 import net.sf.saxon.tree.NodeFactory; 11 12 import javax.xml.transform.TransformerException ; 13 import javax.xml.transform.TransformerFactoryConfigurationError ; 14 import java.math.BigDecimal ; 15 import java.util.HashMap ; 16 17 23 24 public class StyleNodeFactory implements NodeFactory { 25 26 HashMap userStyles = new HashMap (4); 27 Configuration config; 28 NamePool namePool; 29 boolean allowExtensions; 30 31 32 public StyleNodeFactory(Configuration config) { 33 34 this.config = config; 35 namePool = config.getNamePool(); 36 this.allowExtensions = config.isAllowExternalFunctions(); 37 } 38 39 47 48 public ElementImpl makeElementNode( 49 NodeInfo parent, 50 int nameCode, 51 AttributeCollectionImpl attlist, 52 int[] namespaces, 53 int namespacesUsed, 54 LocationProvider locator, 55 int locationId, 56 int sequence) 57 { 58 boolean toplevel = (parent instanceof XSLStylesheet); 59 String baseURI = null; 60 int lineNumber = -1; 61 62 if (locator!=null) { 63 baseURI = locator.getSystemId(locationId); 64 lineNumber = locator.getLineNumber(locationId); 65 } 66 67 if (parent instanceof DataElement) { 68 DataElement d = new DataElement(); 69 d.setNamespaceDeclarations(namespaces, namespacesUsed); 70 d.initialise(nameCode, attlist, parent, baseURI, lineNumber, sequence); 71 return d; 72 } 73 74 int f = nameCode&0xfffff; 75 76 78 StyleElement e = makeXSLElement(f); 79 80 if (e != null) { try { 82 e.setNamespaceDeclarations(namespaces, namespacesUsed); 83 e.setLineNumber(lineNumber); 84 e.initialise(nameCode, attlist, parent, baseURI, -1, sequence); 85 e.processDefaultCollationAttribute(StandardNames.DEFAULT_COLLATION); 86 e.processExtensionElementAttribute(StandardNames.EXTENSION_ELEMENT_PREFIXES); 87 e.processExcludedNamespaces(StandardNames.EXCLUDE_RESULT_PREFIXES); 88 e.processVersionAttribute(StandardNames.VERSION); 89 e.processDefaultXPathNamespaceAttribute(StandardNames.XPATH_DEFAULT_NAMESPACE); 90 } catch (TransformerException err) { 91 e.setValidationError(err, StyleElement.REPORT_ALWAYS); 92 } 93 return e; 94 95 } else { 97 short uriCode = namePool.getURICode(nameCode); 98 String localname = namePool.getLocalName(nameCode); 99 StyleElement temp = null; 100 101 103 if (uriCode == NamespaceConstant.XSLT_CODE && 104 (parent instanceof XSLStylesheet) && 105 ((XSLStylesheet)parent).getVersion().compareTo(BigDecimal.valueOf('2')) <= 0 ) { 106 temp = new AbsentExtensionElement(); 107 temp.setValidationError(new StaticError("Unknown top-level XSLT declaration"), 108 StyleElement.REPORT_UNLESS_FORWARDS_COMPATIBLE ); 109 } 110 111 Class assumedClass = LiteralResultElement.class; 112 113 117 118 boolean assumedSaxonElement = false; 119 120 122 if (temp==null) { 123 if (uriCode == NamespaceConstant.SAXON_CODE) { 124 temp = makeSaxonElement(f); 125 if (temp!=null) { 126 assumedClass = temp.getClass(); 127 assumedSaxonElement = true; 128 } 129 } else if (toplevel && uriCode != 0) { 130 DataElement d = new DataElement(); 131 d.setNamespaceDeclarations(namespaces, namespacesUsed); 132 d.initialise(nameCode, attlist, parent, baseURI, lineNumber, sequence); 133 return d; 134 } 135 } 136 137 if (temp==null) { 138 temp = new LiteralResultElement(); 139 } 140 141 temp.setNamespaceDeclarations(namespaces, namespacesUsed); 142 143 try { 144 temp.initialise(nameCode, attlist, parent, baseURI, lineNumber, sequence); 145 temp.setLineNumber(lineNumber); 146 temp.processDefaultCollationAttribute(StandardNames.XSL_DEFAULT_COLLATION_CLARK); 147 temp.processExtensionElementAttribute(StandardNames.XSL_EXTENSION_ELEMENT_PREFIXES_CLARK); 148 temp.processExcludedNamespaces(StandardNames.XSL_EXCLUDE_RESULT_PREFIXES_CLARK); 149 temp.processVersionAttribute(StandardNames.XSL_VERSION_CLARK); 150 temp.processDefaultXPathNamespaceAttribute(StandardNames.XSL_XPATH_DEFAULT_NAMESPACE_CLARK); 151 } catch (TransformerException err) { 152 temp.setValidationError(err, StyleElement.REPORT_UNLESS_FORWARDS_COMPATIBLE); 153 } 154 155 157 TransformerException reason; 158 Class actualClass; 159 160 if (uriCode == NamespaceConstant.XSLT_CODE) { 161 reason = new StaticError("Unknown XSLT element: " + localname); 162 ((StaticError)reason).setErrorCode("XTSE0010"); 163 actualClass = AbsentExtensionElement.class; 164 temp.setValidationError(reason, StyleElement.REPORT_UNLESS_FORWARDS_COMPATIBLE); 165 } else if (uriCode == NamespaceConstant.SAXON_CODE) { 166 if (toplevel || temp.isExtensionNamespace(uriCode)) { 167 if (assumedSaxonElement) { 168 actualClass = assumedClass; 170 } else { 171 actualClass = AbsentExtensionElement.class; 172 reason = new StaticError( 173 "Unknown Saxon extension element: " + localname); 174 temp.setValidationError(reason, StyleElement.REPORT_IF_INSTANTIATED); 175 } 176 } else { 177 actualClass = LiteralResultElement.class; 178 } 179 } else if (temp.isExtensionNamespace(uriCode) && !toplevel) { 180 Integer nameKey = new Integer (nameCode&0xfffff); 181 182 actualClass = (Class )userStyles.get(nameKey); 183 if (actualClass==null) { 184 if (allowExtensions) { 185 ExtensionElementFactory factory = getFactory(uriCode); 186 if (factory != null) { 187 actualClass = factory.getExtensionClass(localname); 188 if (actualClass != null) { 189 userStyles.put(nameKey, actualClass); } 191 } 192 } else { 193 actualClass = AbsentExtensionElement.class; 194 reason = new StaticError("Extension elements are disabled"); 195 temp.setValidationError(reason, StyleElement.REPORT_IF_INSTANTIATED); 196 } 197 198 if (actualClass == null) { 199 200 205 actualClass = AbsentExtensionElement.class; 206 StaticError se = new StaticError("Unknown extension element", temp); 207 se.setErrorCode("XTDE1450"); 208 reason = se; 209 temp.setValidationError(reason, StyleElement.REPORT_IF_INSTANTIATED); 210 } 211 } 212 } else { 213 actualClass = LiteralResultElement.class; 214 } 215 216 StyleElement node; 217 if (actualClass.equals(assumedClass)) { 218 node = temp; } else { 220 try { 221 node = (StyleElement)actualClass.newInstance(); 222 } catch (InstantiationException err1) { 223 throw new TransformerFactoryConfigurationError (err1, "Failed to create instance of " + actualClass.getName()); 224 } catch (IllegalAccessException err2) { 225 throw new TransformerFactoryConfigurationError (err2, "Failed to access class " + actualClass.getName()); 226 } 227 node.substituteFor(temp); } 229 return node; 230 } 231 } 232 233 236 237 private StyleElement makeXSLElement(int f) { 238 switch (f) { 239 case StandardNames.XSL_ANALYZE_STRING: 240 return new XSLAnalyzeString(); 241 case StandardNames.XSL_APPLY_IMPORTS: 242 return new XSLApplyImports(); 243 case StandardNames.XSL_APPLY_TEMPLATES: 244 return new XSLApplyTemplates(); 245 case StandardNames.XSL_ATTRIBUTE: 246 return new XSLAttribute(); 247 case StandardNames.XSL_ATTRIBUTE_SET: 248 return new XSLAttributeSet(); 249 case StandardNames.XSL_CALL_TEMPLATE: 250 return new XSLCallTemplate(); 251 case StandardNames.XSL_CHARACTER_MAP: 252 return new XSLCharacterMap(); 253 case StandardNames.XSL_CHOOSE: 254 return new XSLChoose(); 255 case StandardNames.XSL_COMMENT: 256 return new XSLComment(); 257 case StandardNames.XSL_COPY: 258 return new XSLCopy(); 259 case StandardNames.XSL_COPY_OF: 260 return new XSLCopyOf(); 261 case StandardNames.XSL_DECIMAL_FORMAT: 262 return new XSLDecimalFormat(); 263 case StandardNames.XSL_DOCUMENT: 264 return new XSLDocument(); 265 case StandardNames.XSL_ELEMENT: 266 return new XSLElement(); 267 case StandardNames.XSL_FALLBACK: 268 return new XSLFallback(); 269 case StandardNames.XSL_FOR_EACH: 270 return new XSLForEach(); 271 case StandardNames.XSL_FOR_EACH_GROUP: 272 return new XSLForEachGroup(); 273 case StandardNames.XSL_FUNCTION: 274 return new XSLFunction(); 275 case StandardNames.XSL_IF: 276 return new XSLIf(); 277 case StandardNames.XSL_IMPORT: 278 return new XSLImport(); 279 case StandardNames.XSL_IMPORT_SCHEMA: 280 return new XSLImportSchema(); 281 case StandardNames.XSL_INCLUDE: 282 return new XSLInclude(); 283 case StandardNames.XSL_KEY: 284 return new XSLKey(); 285 case StandardNames.XSL_MATCHING_SUBSTRING: 286 return new XSLMatchingSubstring(); 287 case StandardNames.XSL_MESSAGE: 288 return new XSLMessage(); 289 case StandardNames.XSL_NEXT_MATCH: 290 return new XSLNextMatch(); 291 case StandardNames.XSL_NON_MATCHING_SUBSTRING: 292 return new XSLMatchingSubstring(); case StandardNames.XSL_NUMBER: 294 return new XSLNumber(); 295 case StandardNames.XSL_NAMESPACE: 296 return new XSLNamespace(); 297 case StandardNames.XSL_NAMESPACE_ALIAS: 298 return new XSLNamespaceAlias(); 299 case StandardNames.XSL_OTHERWISE: 300 return new XSLOtherwise(); 301 case StandardNames.XSL_OUTPUT: 302 return new XSLOutput(); 303 case StandardNames.XSL_OUTPUT_CHARACTER: 304 return new XSLOutputCharacter(); 305 case StandardNames.XSL_PARAM: 306 return new XSLParam(); 307 case StandardNames.XSL_PERFORM_SORT: 308 return new XSLPerformSort(); 309 case StandardNames.XSL_PRESERVE_SPACE: 310 return new XSLPreserveSpace(); 311 case StandardNames.XSL_PROCESSING_INSTRUCTION: 312 return new XSLProcessingInstruction(); 313 case StandardNames.XSL_RESULT_DOCUMENT: 314 return new XSLResultDocument(); 315 case StandardNames.XSL_SEQUENCE: 316 return new XSLSequence(); 317 case StandardNames.XSL_SORT: 318 return new XSLSort(); 319 case StandardNames.XSL_STRIP_SPACE: 320 return new XSLPreserveSpace(); 321 case StandardNames.XSL_STYLESHEET: 322 return new XSLStylesheet(); 323 case StandardNames.XSL_TEMPLATE: 324 return new XSLTemplate(); 325 case StandardNames.XSL_TEXT: 326 return new XSLText(); 327 case StandardNames.XSL_TRANSFORM: 328 return new XSLStylesheet(); 329 case StandardNames.XSL_VALUE_OF: 330 return new XSLValueOf(); 331 case StandardNames.XSL_VARIABLE: 332 return new XSLVariable(); 333 case StandardNames.XSL_WITH_PARAM: 334 return new XSLWithParam(); 335 case StandardNames.XSL_WHEN: 336 return new XSLWhen(); 337 default: return null; 338 } 339 } 340 341 344 345 private StyleElement makeSaxonElement(int f) { 346 347 switch (f) { 348 349 case StandardNames.SAXON_ASSIGN: 350 return new SaxonAssign(); 351 case StandardNames.SAXON_ENTITY_REF: 352 return new SaxonEntityRef(); 353 case StandardNames.SAXON_CALL_TEMPLATE: 354 return new SaxonCallTemplate(); 355 case StandardNames.SAXON_COLLATION: 356 return new SaxonCollation(); 357 case StandardNames.SAXON_DOCTYPE: 358 return new SaxonDoctype(); 359 case StandardNames.SAXON_IMPORT_QUERY: 360 return new SaxonImportQuery(); 361 case StandardNames.SAXON_SCRIPT: 362 return new SaxonScript(); 363 case StandardNames.SAXON_WHILE: 364 return new SaxonWhile(); 365 default: return null; 366 } 367 } 368 369 373 374 private ExtensionElementFactory getFactory(short uriCode) { 375 String uri = namePool.getURIFromNamespaceCode(uriCode); 376 int lastSlash = uri.lastIndexOf('/'); 377 if (lastSlash<0 || lastSlash==uri.length()-1) { 378 return null; 379 } 380 String factoryClass = uri.substring(lastSlash+1); 381 ExtensionElementFactory factory; 382 383 try { 384 factory = (ExtensionElementFactory)config.getInstance(factoryClass, null); 385 } catch (Exception err) { 386 return null; 387 } 388 return factory; 389 } 390 391 394 395 public boolean isElementAvailable(String uri, String localName) { 396 int fingerprint = namePool.getFingerprint(uri, localName); 397 if (uri.equals(NamespaceConstant.XSLT)) { 398 if (fingerprint==-1) return false; StyleElement e = makeXSLElement(fingerprint); 400 if (e!=null) return e.isInstruction(); 401 } 402 403 if (uri.equals(NamespaceConstant.SAXON)) { 404 if (fingerprint==-1) return false; StyleElement e = makeSaxonElement(fingerprint); 406 if (e!=null) return e.isInstruction(); 407 } 408 if (!allowExtensions) { 409 return false; 411 } 412 short uriCode = namePool.getCodeForURI(uri); 413 ExtensionElementFactory factory = getFactory(uriCode); 414 if (factory==null) return false; 415 Class actualClass = factory.getExtensionClass(localName); 416 return (actualClass != null); 417 418 } 419 420 421 422 423 } 424 425 | Popular Tags |