1/* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4/* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21package com.sun.org.apache.xml.internal.dtm; 22 23import com.sun.org.apache.xml.internal.utils.PrefixResolver; 24import com.sun.org.apache.xml.internal.utils.XMLStringFactory; 25 26/** 27 * A DTMManager instance can be used to create DTM and 28 * DTMIterator objects, and manage the DTM objects in the system. 29 * 30 * <p>The system property that determines which Factory implementation 31 * to create is named "com.sun.org.apache.xml.internal.utils.DTMFactory". This 32 * property names a concrete subclass of the DTMFactory abstract 33 * class. If the property is not defined, a platform default is be used.</p> 34 * 35 * <p>An instance of this class <emph>must</emph> be safe to use across 36 * thread instances. It is expected that a client will create a single instance 37 * of a DTMManager to use across multiple threads. This will allow sharing 38 * of DTMs across multiple processes.</p> 39 * 40 * <p>Note: this class is incomplete right now. It will be pretty much 41 * modeled after javax.xml.transform.TransformerFactory in terms of its 42 * factory support.</p> 43 * 44 * <p>State: In progress!!</p> 45 */ 46public abstract class DTMManager 47{ 48 49 /** 50 * Factory for creating XMLString objects. 51 * %TBD% Make this set by the caller. 52 */ 53 protected XMLStringFactory m_xsf = null; 54 55 private boolean _useServicesMechanism; 56 /** 57 * Default constructor is protected on purpose. 58 */ 59 protected DTMManager(){} 60 61 /** 62 * Get the XMLStringFactory used for the DTMs. 63 * 64 * 65 * @return a valid XMLStringFactory object, or null if it hasn't been set yet. 66 */ 67 public XMLStringFactory getXMLStringFactory() 68 { 69 return m_xsf; 70 } 71 72 /** 73 * Set the XMLStringFactory used for the DTMs. 74 * 75 * 76 * @param xsf a valid XMLStringFactory object, should not be null. 77 */ 78 public void setXMLStringFactory(XMLStringFactory xsf) 79 { 80 m_xsf = xsf; 81 } 82 83 /** 84 * Obtain a new instance of a <code>DTMManager</code>. 85 * This static method creates a new factory instance 86 * using the default <code>DTMManager</code> implementation, which is 87 * <code>com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault</code>. 88 * </li> 89 * </ul> 90 * 91 * Once an application has obtained a reference to a <code> 92 * DTMManager</code> it can use the factory to configure 93 * and obtain parser instances. 94 * 95 * @return new DTMManager instance, never null. 96 * 97 * @throws DTMException 98 * if the implementation is not available or cannot be instantiated. 99 */ 100 public static DTMManager newInstance(XMLStringFactory xsf) 101 throws DTMException 102 { 103 final DTMManager factoryImpl = new com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault(); 104 factoryImpl.setXMLStringFactory(xsf); 105 106 return factoryImpl; 107 } 108 109 /** 110 * Get an instance of a DTM, loaded with the content from the 111 * specified source. If the unique flag is true, a new instance will 112 * always be returned. Otherwise it is up to the DTMManager to return a 113 * new instance or an instance that it already created and may be being used 114 * by someone else. 115 * 116 * (More parameters may eventually need to be added for error handling 117 * and entity resolution, and to better control selection of implementations.) 118 * 119 * @param source the specification of the source object, which may be null, 120 * in which case it is assumed that node construction will take 121 * by some other means. 122 * @param unique true if the returned DTM must be unique, probably because it 123 * is going to be mutated. 124 * @param whiteSpaceFilter Enables filtering of whitespace nodes, and may 125 * be null. 126 * @param incremental true if the DTM should be built incrementally, if 127 * possible. 128 * @param doIndexing true if the caller considers it worth it to use 129 * indexing schemes. 130 * 131 * @return a non-null DTM reference. 132 */ 133 public abstract DTM getDTM(javax.xml.transform.Source source, 134 boolean unique, DTMWSFilter whiteSpaceFilter, 135 boolean incremental, boolean doIndexing); 136 137 /** 138 * Get the instance of DTM that "owns" a node handle. 139 * 140 * @param nodeHandle the nodeHandle. 141 * 142 * @return a non-null DTM reference. 143 */ 144 public abstract DTM getDTM(int nodeHandle); 145 146 /** 147 * Given a W3C DOM node, try and return a DTM handle. 148 * Note: calling this may be non-optimal. 149 * 150 * @param node Non-null reference to a DOM node. 151 * 152 * @return a valid DTM handle. 153 */ 154 public abstract int getDTMHandleFromNode(org.w3c.dom.Node node); 155 156 /** 157 * Creates a DTM representing an empty <code>DocumentFragment</code> object. 158 * @return a non-null DTM reference. 159 */ 160 public abstract DTM createDocumentFragment(); 161 162 /** 163 * Release a DTM either to a lru pool, or completely remove reference. 164 * DTMs without system IDs are always hard deleted. 165 * State: experimental. 166 * 167 * @param dtm The DTM to be released. 168 * @param shouldHardDelete True if the DTM should be removed no matter what. 169 * @return true if the DTM was removed, false if it was put back in a lru pool. 170 */ 171 public abstract boolean release(DTM dtm, boolean shouldHardDelete); 172 173 /** 174 * Create a new <code>DTMIterator</code> based on an XPath 175 * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or 176 * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>. 177 * 178 * @param xpathCompiler ??? Somehow we need to pass in a subpart of the 179 * expression. I hate to do this with strings, since the larger expression 180 * has already been parsed. 181 * 182 * @param pos The position in the expression. 183 * @return The newly created <code>DTMIterator</code>. 184 */ 185 public abstract DTMIterator createDTMIterator(Object xpathCompiler, 186 int pos); 187 188 /** 189 * Create a new <code>DTMIterator</code> based on an XPath 190 * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or 191 * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>. 192 * 193 * @param xpathString Must be a valid string expressing a 194 * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or 195 * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>. 196 * 197 * @param presolver An object that can resolve prefixes to namespace URLs. 198 * 199 * @return The newly created <code>DTMIterator</code>. 200 */ 201 public abstract DTMIterator createDTMIterator(String xpathString, 202 PrefixResolver presolver); 203 204 /** 205 * Create a new <code>DTMIterator</code> based only on a whatToShow 206 * and a DTMFilter. The traversal semantics are defined as the 207 * descendant access. 208 * <p> 209 * Note that DTMIterators may not be an exact match to DOM 210 * NodeIterators. They are initialized and used in much the same way 211 * as a NodeIterator, but their response to document mutation is not 212 * currently defined. 213 * 214 * @param whatToShow This flag specifies which node types may appear in 215 * the logical view of the tree presented by the iterator. See the 216 * description of <code>NodeFilter</code> for the set of possible 217 * <code>SHOW_</code> values.These flags can be combined using 218 * <code>OR</code>. 219 * @param filter The <code>NodeFilter</code> to be used with this 220 * <code>DTMFilter</code>, or <code>null</code> to indicate no filter. 221 * @param entityReferenceExpansion The value of this flag determines 222 * whether entity reference nodes are expanded. 223 * 224 * @return The newly created <code>DTMIterator</code>. 225 */ 226 public abstract DTMIterator createDTMIterator(int whatToShow, 227 DTMFilter filter, boolean entityReferenceExpansion); 228 229 /** 230 * Create a new <code>DTMIterator</code> that holds exactly one node. 231 * 232 * @param node The node handle that the DTMIterator will iterate to. 233 * 234 * @return The newly created <code>DTMIterator</code>. 235 */ 236 public abstract DTMIterator createDTMIterator(int node); 237 238 /* Flag indicating whether an incremental transform is desired */ 239 public boolean m_incremental = false; 240 241 /* 242 * Flag set by FEATURE_SOURCE_LOCATION. 243 * This feature specifies whether the transformation phase should 244 * keep track of line and column numbers for the input source 245 * document. 246 */ 247 public boolean m_source_location = false; 248 249 /** 250 * Get a flag indicating whether an incremental transform is desired 251 * @return incremental boolean. 252 * 253 */ 254 public boolean getIncremental() 255 { 256 return m_incremental; 257 } 258 259 /** 260 * Set a flag indicating whether an incremental transform is desired 261 * This flag should have the same value as the FEATURE_INCREMENTAL feature 262 * which is set by the TransformerFactory.setAttribut() method before a 263 * DTMManager is created 264 * @param incremental boolean to use to set m_incremental. 265 * 266 */ 267 public void setIncremental(boolean incremental) 268 { 269 m_incremental = incremental; 270 } 271 272 /** 273 * Get a flag indicating whether the transformation phase should 274 * keep track of line and column numbers for the input source 275 * document. 276 * @return source location boolean 277 * 278 */ 279 public boolean getSource_location() 280 { 281 return m_source_location; 282 } 283 284 /** 285 * Set a flag indicating whether the transformation phase should 286 * keep track of line and column numbers for the input source 287 * document. 288 * This flag should have the same value as the FEATURE_SOURCE_LOCATION feature 289 * which is set by the TransformerFactory.setAttribut() method before a 290 * DTMManager is created 291 * @param sourceLocation boolean to use to set m_source_location 292 */ 293 public void setSource_location(boolean sourceLocation){ 294 m_source_location = sourceLocation; 295 } 296 297 /** 298 * Return the state of the services mechanism feature. 299 */ 300 public boolean useServicesMechnism() { 301 return _useServicesMechanism; 302 } 303 304 /** 305 * Set the state of the services mechanism feature. 306 */ 307 public void setServicesMechnism(boolean flag) { 308 _useServicesMechanism = flag; 309 } 310 311 // -------------------- private methods -------------------- 312 313 /** This value, set at compile time, controls how many bits of the 314 * DTM node identifier numbers are used to identify a node within a 315 * document, and thus sets the maximum number of nodes per 316 * document. The remaining bits are used to identify the DTM 317 * document which contains this node. 318 * 319 * If you change IDENT_DTM_NODE_BITS, be sure to rebuild _ALL_ the 320 * files which use it... including the IDKey testcases. 321 * 322 * (FuncGenerateKey currently uses the node identifier directly and 323 * thus is affected when this changes. The IDKEY results will still be 324 * _correct_ (presuming no other breakage), but simple equality 325 * comparison against the previous "golden" files will probably 326 * complain.) 327 * */ 328 public static final int IDENT_DTM_NODE_BITS = 16; 329 330 331 /** When this bitmask is ANDed with a DTM node handle number, the result 332 * is the low bits of the node's index number within that DTM. To obtain 333 * the high bits, add the DTM ID portion's offset as assigned in the DTM 334 * Manager. 335 */ 336 public static final int IDENT_NODE_DEFAULT = (1<<IDENT_DTM_NODE_BITS)-1; 337 338 339 /** When this bitmask is ANDed with a DTM node handle number, the result 340 * is the DTM's document identity number. 341 */ 342 public static final int IDENT_DTM_DEFAULT = ~IDENT_NODE_DEFAULT; 343 344 /** This is the maximum number of DTMs available. The highest DTM is 345 * one less than this. 346 */ 347 public static final int IDENT_MAX_DTMS = (IDENT_DTM_DEFAULT >>> IDENT_DTM_NODE_BITS) + 1; 348 349 350 /** 351 * %TBD% Doc 352 * 353 * NEEDSDOC @param dtm 354 * 355 * NEEDSDOC ($objectName$) @return 356 */ 357 public abstract int getDTMIdentity(DTM dtm); 358 359 /** 360 * %TBD% Doc 361 * 362 * NEEDSDOC ($objectName$) @return 363 */ 364 public int getDTMIdentityMask() 365 { 366 return IDENT_DTM_DEFAULT; 367 } 368 369 /** 370 * %TBD% Doc 371 * 372 * NEEDSDOC ($objectName$) @return 373 */ 374 public int getNodeIdentityMask() 375 { 376 return IDENT_NODE_DEFAULT; 377 } 378} 379