Source Code Cross Referenced for DTMManagerDefault.java in  » XML » xalan » org » apache » xml » dtm » ref » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » xalan » org.apache.xml.dtm.ref 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 1999-2004 The Apache Software Foundation.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *     http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:        /*
017:         * $Id: DTMManagerDefault.java,v 1.52 2004/11/22 17:53:43 mkwan Exp $
018:         */
019:        package org.apache.xml.dtm.ref;
020:
021:        import javax.xml.parsers.DocumentBuilder;
022:        import javax.xml.parsers.DocumentBuilderFactory;
023:        import javax.xml.transform.Source;
024:        import javax.xml.transform.dom.DOMSource;
025:        import javax.xml.transform.sax.SAXSource;
026:        import javax.xml.transform.stream.StreamSource;
027:
028:        import org.apache.xml.dtm.DTM;
029:        import org.apache.xml.dtm.DTMException;
030:        import org.apache.xml.dtm.DTMFilter;
031:        import org.apache.xml.dtm.DTMIterator;
032:        import org.apache.xml.dtm.DTMManager;
033:        import org.apache.xml.dtm.DTMWSFilter;
034:        import org.apache.xml.dtm.ref.dom2dtm.DOM2DTM;
035:        import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM;
036:        import org.apache.xml.dtm.ref.sax2dtm.SAX2RTFDTM;
037:        import org.apache.xml.res.XMLErrorResources;
038:        import org.apache.xml.res.XMLMessages;
039:        import org.apache.xml.utils.PrefixResolver;
040:        import org.apache.xml.utils.SystemIDResolver;
041:        import org.apache.xml.utils.XMLReaderManager;
042:        import org.apache.xml.utils.XMLStringFactory;
043:
044:        import org.w3c.dom.Document;
045:        import org.w3c.dom.Node;
046:
047:        import org.xml.sax.InputSource;
048:        import org.xml.sax.SAXException;
049:        import org.xml.sax.SAXNotRecognizedException;
050:        import org.xml.sax.SAXNotSupportedException;
051:        import org.xml.sax.XMLReader;
052:        import org.xml.sax.helpers.DefaultHandler;
053:
054:        /**
055:         * The default implementation for the DTMManager.
056:         *
057:         * %REVIEW% There is currently a reentrancy issue, since the finalizer
058:         * for XRTreeFrag (which runs in the GC thread) wants to call
059:         * DTMManager.release(), and may do so at the same time that the main
060:         * transformation thread is accessing the manager. Our current solution is
061:         * to make most of the manager's methods <code>synchronized</code>.
062:         * Early tests suggest that doing so is not causing a significant
063:         * performance hit in Xalan. However, it should be noted that there
064:         * is a possible alternative solution: rewrite release() so it merely
065:         * posts a request for release onto a threadsafe queue, and explicitly
066:         * process that queue on an infrequent basis during main-thread
067:         * activity (eg, when getDTM() is invoked). The downside of that solution
068:         * would be a greater delay before the DTM's storage is actually released
069:         * for reuse.
070:         * */
071:        public class DTMManagerDefault extends DTMManager {
072:            //static final boolean JKESS_XNI_EXPERIMENT=true;
073:
074:            /** Set this to true if you want a dump of the DTM after creation. */
075:            private static final boolean DUMPTREE = false;
076:
077:            /** Set this to true if you want a basic diagnostics. */
078:            private static final boolean DEBUG = false;
079:
080:            /**
081:             * Map from DTM identifier numbers to DTM objects that this manager manages.
082:             * One DTM may have several prefix numbers, if extended node indexing
083:             * is in use; in that case, m_dtm_offsets[] will used to control which
084:             * prefix maps to which section of the DTM.
085:             * 
086:             * This array grows as necessary; see addDTM().
087:             * 
088:             * This array grows as necessary; see addDTM(). Growth is uncommon... but
089:             * access needs to be blindingly fast since it's used in node addressing.
090:             */
091:            protected DTM m_dtms[] = new DTM[256];
092:
093:            /** Map from DTM identifier numbers to offsets. For small DTMs with a 
094:             * single identifier, this will always be 0. In overflow addressing, where
095:             * additional identifiers are allocated to access nodes beyond the range of
096:             * a single Node Handle, this table is used to map the handle's node field
097:             * into the actual node identifier.
098:             * 
099:             * This array grows as necessary; see addDTM().
100:             * 
101:             * This array grows as necessary; see addDTM(). Growth is uncommon... but
102:             * access needs to be blindingly fast since it's used in node addressing.
103:             * (And at the moment, that includes accessing it from DTMDefaultBase,
104:             * which is why this is not Protected or Private.)
105:             */
106:            int m_dtm_offsets[] = new int[256];
107:
108:            /**
109:             * The cache for XMLReader objects to be used if the user did not
110:             * supply an XMLReader for a SAXSource or supplied a StreamSource.
111:             */
112:            protected XMLReaderManager m_readerManager = null;
113:
114:            /**
115:             * The default implementation of ContentHandler, DTDHandler and ErrorHandler.
116:             */
117:            protected DefaultHandler m_defaultHandler = new DefaultHandler();
118:
119:            /**
120:             * Add a DTM to the DTM table. This convenience call adds it as the 
121:             * "base DTM ID", with offset 0. The other version of addDTM should 
122:             * be used if you want to add "extended" DTM IDs with nonzero offsets.
123:             *
124:             * @param dtm Should be a valid reference to a DTM.
125:             * @param id Integer DTM ID to be bound to this DTM
126:             */
127:            synchronized public void addDTM(DTM dtm, int id) {
128:                addDTM(dtm, id, 0);
129:            }
130:
131:            /**
132:             * Add a DTM to the DTM table.
133:             *
134:             * @param dtm Should be a valid reference to a DTM.
135:             * @param id Integer DTM ID to be bound to this DTM.
136:             * @param offset Integer addressing offset. The internal DTM Node ID is
137:             * obtained by adding this offset to the node-number field of the 
138:             * public DTM Handle. For the first DTM ID accessing each DTM, this is 0;
139:             * for overflow addressing it will be a multiple of 1<<IDENT_DTM_NODE_BITS.
140:             */
141:            synchronized public void addDTM(DTM dtm, int id, int offset) {
142:                if (id >= IDENT_MAX_DTMS) {
143:                    // TODO: %REVIEW% Not really the right error message.
144:                    throw new DTMException(XMLMessages.createXMLMessage(
145:                            XMLErrorResources.ER_NO_DTMIDS_AVAIL, null)); //"No more DTM IDs are available!");			 
146:                }
147:
148:                // We used to just allocate the array size to IDENT_MAX_DTMS.
149:                // But we expect to increase that to 16 bits, and I'm not willing
150:                // to allocate that much space unless needed. We could use one of our
151:                // handy-dandy Fast*Vectors, but this will do for now.
152:                // %REVIEW%
153:                int oldlen = m_dtms.length;
154:                if (oldlen <= id) {
155:                    // Various growth strategies are possible. I think we don't want 
156:                    // to over-allocate excessively, and I'm willing to reallocate
157:                    // more often to get that. See also Fast*Vector classes.
158:                    //
159:                    // %REVIEW% Should throw a more diagnostic error if we go over the max...
160:                    int newlen = Math.min((id + 256), IDENT_MAX_DTMS);
161:
162:                    DTM new_m_dtms[] = new DTM[newlen];
163:                    System.arraycopy(m_dtms, 0, new_m_dtms, 0, oldlen);
164:                    m_dtms = new_m_dtms;
165:                    int new_m_dtm_offsets[] = new int[newlen];
166:                    System.arraycopy(m_dtm_offsets, 0, new_m_dtm_offsets, 0,
167:                            oldlen);
168:                    m_dtm_offsets = new_m_dtm_offsets;
169:                }
170:
171:                m_dtms[id] = dtm;
172:                m_dtm_offsets[id] = offset;
173:                dtm.documentRegistration();
174:                // The DTM should have been told who its manager was when we created it.
175:                // Do we need to allow for adopting DTMs _not_ created by this manager?
176:            }
177:
178:            /**
179:             * Get the first free DTM ID available. %OPT% Linear search is inefficient!
180:             */
181:            synchronized public int getFirstFreeDTMID() {
182:                int n = m_dtms.length;
183:                for (int i = 1; i < n; i++) {
184:                    if (null == m_dtms[i]) {
185:                        return i;
186:                    }
187:                }
188:                return n; // count on addDTM() to throw exception if out of range
189:            }
190:
191:            /**
192:             * The default table for exandedNameID lookups.
193:             */
194:            private ExpandedNameTable m_expandedNameTable = new ExpandedNameTable();
195:
196:            /**
197:             * Constructor DTMManagerDefault
198:             *
199:             */
200:            public DTMManagerDefault() {
201:            }
202:
203:            /**
204:             * Get an instance of a DTM, loaded with the content from the
205:             * specified source.  If the unique flag is true, a new instance will
206:             * always be returned.  Otherwise it is up to the DTMManager to return a
207:             * new instance or an instance that it already created and may be being used
208:             * by someone else.
209:             * 
210:             * A bit of magic in this implementation: If the source is null, unique is true,
211:             * and incremental and doIndexing are both false, we return an instance of
212:             * SAX2RTFDTM, which see.
213:             * 
214:             * (I think more parameters will need to be added for error handling, and entity
215:             * resolution, and more explicit control of the RTF situation).
216:             *
217:             * @param source the specification of the source object.
218:             * @param unique true if the returned DTM must be unique, probably because it
219:             * is going to be mutated.
220:             * @param whiteSpaceFilter Enables filtering of whitespace nodes, and may
221:             *                         be null.
222:             * @param incremental true if the DTM should be built incrementally, if
223:             *                    possible.
224:             * @param doIndexing true if the caller considers it worth it to use
225:             *                   indexing schemes.
226:             *
227:             * @return a non-null DTM reference.
228:             */
229:            synchronized public DTM getDTM(Source source, boolean unique,
230:                    DTMWSFilter whiteSpaceFilter, boolean incremental,
231:                    boolean doIndexing) {
232:
233:                if (DEBUG && null != source)
234:                    System.out.println("Starting "
235:                            + (unique ? "UNIQUE" : "shared") + " source: "
236:                            + source.getSystemId());
237:
238:                XMLStringFactory xstringFactory = m_xsf;
239:                int dtmPos = getFirstFreeDTMID();
240:                int documentID = dtmPos << IDENT_DTM_NODE_BITS;
241:
242:                if ((null != source) && source instanceof  DOMSource) {
243:                    DOM2DTM dtm = new DOM2DTM(this , (DOMSource) source,
244:                            documentID, whiteSpaceFilter, xstringFactory,
245:                            doIndexing);
246:
247:                    addDTM(dtm, dtmPos, 0);
248:
249:                    //      if (DUMPTREE)
250:                    //      {
251:                    //        dtm.dumpDTM();
252:                    //      }
253:
254:                    return dtm;
255:                } else {
256:                    boolean isSAXSource = (null != source) ? (source instanceof  SAXSource)
257:                            : true;
258:                    boolean isStreamSource = (null != source) ? (source instanceof  StreamSource)
259:                            : false;
260:
261:                    if (isSAXSource || isStreamSource) {
262:                        XMLReader reader = null;
263:                        SAX2DTM dtm;
264:
265:                        try {
266:                            InputSource xmlSource;
267:
268:                            if (null == source) {
269:                                xmlSource = null;
270:                            } else {
271:                                reader = getXMLReader(source);
272:                                xmlSource = SAXSource
273:                                        .sourceToInputSource(source);
274:
275:                                String urlOfSource = xmlSource.getSystemId();
276:
277:                                if (null != urlOfSource) {
278:                                    try {
279:                                        urlOfSource = SystemIDResolver
280:                                                .getAbsoluteURI(urlOfSource);
281:                                    } catch (Exception e) {
282:                                        // %REVIEW% Is there a better way to send a warning?
283:                                        System.err
284:                                                .println("Can not absolutize URL: "
285:                                                        + urlOfSource);
286:                                    }
287:
288:                                    xmlSource.setSystemId(urlOfSource);
289:                                }
290:                            }
291:
292:                            if (source == null && unique && !incremental
293:                                    && !doIndexing) {
294:                                // Special case to support RTF construction into shared DTM.
295:                                // It should actually still work for other uses,
296:                                // but may be slightly deoptimized relative to the base
297:                                // to allow it to deal with carrying multiple documents.
298:                                //
299:                                // %REVIEW% This is a sloppy way to request this mode;
300:                                // we need to consider architectural improvements.
301:                                dtm = new SAX2RTFDTM(this , source, documentID,
302:                                        whiteSpaceFilter, xstringFactory,
303:                                        doIndexing);
304:                            }
305:                            /**************************************************************
306:                            // EXPERIMENTAL 3/22/02
307:                            else if(JKESS_XNI_EXPERIMENT && m_incremental) {        	
308:                              dtm = new XNI2DTM(this, source, documentID, whiteSpaceFilter,
309:                                                xstringFactory, doIndexing);
310:                            }
311:                             **************************************************************/
312:                            // Create the basic SAX2DTM.
313:                            else {
314:                                dtm = new SAX2DTM(this , source, documentID,
315:                                        whiteSpaceFilter, xstringFactory,
316:                                        doIndexing);
317:                            }
318:
319:                            // Go ahead and add the DTM to the lookup table.  This needs to be
320:                            // done before any parsing occurs. Note offset 0, since we've just
321:                            // created a new DTM.
322:                            addDTM(dtm, dtmPos, 0);
323:
324:                            boolean haveXercesParser = (null != reader)
325:                                    && (reader.getClass().getName()
326:                                            .equals("org.apache.xerces.parsers.SAXParser"));
327:
328:                            if (haveXercesParser) {
329:                                incremental = true; // No matter what.  %REVIEW%
330:                            }
331:
332:                            // If the reader is null, but they still requested an incremental
333:                            // build, then we still want to set up the IncrementalSAXSource stuff.
334:                            if (m_incremental && incremental
335:                            /* || ((null == reader) && incremental) */) {
336:                                IncrementalSAXSource coParser = null;
337:
338:                                if (haveXercesParser) {
339:                                    // IncrementalSAXSource_Xerces to avoid threading.
340:                                    try {
341:                                        coParser = (IncrementalSAXSource) Class
342:                                                .forName(
343:                                                        "org.apache.xml.dtm.ref.IncrementalSAXSource_Xerces")
344:                                                .newInstance();
345:                                    } catch (Exception ex) {
346:                                        ex.printStackTrace();
347:                                        coParser = null;
348:                                    }
349:                                }
350:
351:                                if (coParser == null) {
352:                                    // Create a IncrementalSAXSource to run on the secondary thread.
353:                                    if (null == reader) {
354:                                        coParser = new IncrementalSAXSource_Filter();
355:                                    } else {
356:                                        IncrementalSAXSource_Filter filter = new IncrementalSAXSource_Filter();
357:                                        filter.setXMLReader(reader);
358:                                        coParser = filter;
359:                                    }
360:                                }
361:
362:                                /**************************************************************
363:                                // EXPERIMENTAL 3/22/02
364:                                if (JKESS_XNI_EXPERIMENT && m_incremental &&
365:                                      dtm instanceof XNI2DTM && 
366:                                      coParser instanceof IncrementalSAXSource_Xerces) {
367:                                    org.apache.xerces.xni.parser.XMLPullParserConfiguration xpc=
368:                                          ((IncrementalSAXSource_Xerces)coParser)
369:                                                               .getXNIParserConfiguration();
370:                                  if (xpc!=null) {
371:                                    // Bypass SAX; listen to the XNI stream
372:                                    ((XNI2DTM)dtm).setIncrementalXNISource(xpc);
373:                                  } else {
374:                                      // Listen to the SAX stream (will fail, diagnostically...)
375:                                    dtm.setIncrementalSAXSource(coParser);
376:                                  }
377:                                } else
378:                                 ***************************************************************/
379:
380:                                // Have the DTM set itself up as IncrementalSAXSource's listener.
381:                                dtm.setIncrementalSAXSource(coParser);
382:
383:                                if (null == xmlSource) {
384:
385:                                    // Then the user will construct it themselves.
386:                                    return dtm;
387:                                }
388:
389:                                if (null == reader.getErrorHandler()) {
390:                                    reader.setErrorHandler(dtm);
391:                                }
392:                                reader.setDTDHandler(dtm);
393:
394:                                try {
395:                                    // Launch parsing coroutine.  Launches a second thread,
396:                                    // if we're using IncrementalSAXSource.filter().
397:
398:                                    coParser.startParse(xmlSource);
399:                                } catch (RuntimeException re) {
400:
401:                                    dtm.clearCoRoutine();
402:
403:                                    throw re;
404:                                } catch (Exception e) {
405:
406:                                    dtm.clearCoRoutine();
407:
408:                                    throw new org.apache.xml.utils.WrappedRuntimeException(
409:                                            e);
410:                                }
411:                            } else {
412:                                if (null == reader) {
413:
414:                                    // Then the user will construct it themselves.
415:                                    return dtm;
416:                                }
417:
418:                                // not incremental
419:                                reader.setContentHandler(dtm);
420:                                reader.setDTDHandler(dtm);
421:                                if (null == reader.getErrorHandler()) {
422:                                    reader.setErrorHandler(dtm);
423:                                }
424:
425:                                try {
426:                                    reader
427:                                            .setProperty(
428:                                                    "http://xml.org/sax/properties/lexical-handler",
429:                                                    dtm);
430:                                } catch (SAXNotRecognizedException e) {
431:                                } catch (SAXNotSupportedException e) {
432:                                }
433:
434:                                try {
435:                                    reader.parse(xmlSource);
436:                                } catch (RuntimeException re) {
437:                                    dtm.clearCoRoutine();
438:
439:                                    throw re;
440:                                } catch (Exception e) {
441:                                    dtm.clearCoRoutine();
442:
443:                                    throw new org.apache.xml.utils.WrappedRuntimeException(
444:                                            e);
445:                                }
446:                            }
447:
448:                            if (DUMPTREE) {
449:                                System.out.println("Dumping SAX2DOM");
450:                                dtm.dumpDTM(System.err);
451:                            }
452:
453:                            return dtm;
454:                        } finally {
455:                            // Reset the ContentHandler, DTDHandler, ErrorHandler to the DefaultHandler
456:                            // after creating the DTM.
457:                            if (reader != null
458:                                    && !(m_incremental && incremental)) {
459:                                reader.setContentHandler(m_defaultHandler);
460:                                reader.setDTDHandler(m_defaultHandler);
461:                                reader.setErrorHandler(m_defaultHandler);
462:
463:                                // Reset the LexicalHandler to null after creating the DTM.
464:                                try {
465:                                    reader
466:                                            .setProperty(
467:                                                    "http://xml.org/sax/properties/lexical-handler",
468:                                                    null);
469:                                } catch (Exception e) {
470:                                }
471:                            }
472:                            releaseXMLReader(reader);
473:                        }
474:                    } else {
475:
476:                        // It should have been handled by a derived class or the caller
477:                        // made a mistake.
478:                        throw new DTMException(XMLMessages.createXMLMessage(
479:                                XMLErrorResources.ER_NOT_SUPPORTED,
480:                                new Object[] { source })); //"Not supported: " + source);
481:                    }
482:                }
483:            }
484:
485:            /**
486:             * Given a W3C DOM node, try and return a DTM handle.
487:             * Note: calling this may be non-optimal, and there is no guarantee that
488:             * the node will be found in any particular DTM.
489:             *
490:             * @param node Non-null reference to a DOM node.
491:             *
492:             * @return a valid DTM handle.
493:             */
494:            synchronized public int getDTMHandleFromNode(org.w3c.dom.Node node) {
495:                if (null == node)
496:                    throw new IllegalArgumentException(XMLMessages
497:                            .createXMLMessage(
498:                                    XMLErrorResources.ER_NODE_NON_NULL, null)); //"node must be non-null for getDTMHandleFromNode!");
499:
500:                if (node instanceof  org.apache.xml.dtm.ref.DTMNodeProxy)
501:                    return ((org.apache.xml.dtm.ref.DTMNodeProxy) node)
502:                            .getDTMNodeNumber();
503:
504:                else {
505:                    // Find the DOM2DTMs wrapped around this Document (if any)
506:                    // and check whether they contain the Node in question.
507:                    //
508:                    // NOTE that since a DOM2DTM may represent a subtree rather
509:                    // than a full document, we have to be prepared to check more
510:                    // than one -- and there is no guarantee that we will find
511:                    // one that contains ancestors or siblings of the node we're
512:                    // seeking.
513:                    //
514:                    // %REVIEW% We could search for the one which contains this
515:                    // node at the deepest level, and thus covers the widest
516:                    // subtree, but that's going to entail additional work
517:                    // checking more DTMs... and getHandleOfNode is not a
518:                    // cheap operation in most implementations.
519:                    //
520:                    // TODO: %REVIEW% If overflow addressing, we may recheck a DTM
521:                    // already examined. Ouch. But with the increased number of DTMs,
522:                    // scanning back to check this is painful. 
523:                    // POSSIBLE SOLUTIONS: 
524:                    //   Generate a list of _unique_ DTM objects?
525:                    //   Have each DTM cache last DOM node search?
526:                    int max = m_dtms.length;
527:                    for (int i = 0; i < max; i++) {
528:                        DTM this DTM = m_dtms[i];
529:                        if ((null != this DTM) && this DTM instanceof  DOM2DTM) {
530:                            int handle = ((DOM2DTM) this DTM)
531:                                    .getHandleOfNode(node);
532:                            if (handle != DTM.NULL)
533:                                return handle;
534:                        }
535:                    }
536:
537:                    // Not found; generate a new DTM.
538:                    //
539:                    // %REVIEW% Is this really desirable, or should we return null
540:                    // and make folks explicitly instantiate from a DOMSource? The
541:                    // latter is more work but gives the caller the opportunity to
542:                    // explicitly add the DTM to a DTMManager... and thus to know when
543:                    // it can be discarded again, which is something we need to pay much
544:                    // more attention to. (Especially since only DTMs which are assigned
545:                    // to a manager can use the overflow addressing scheme.)
546:                    //
547:                    // %BUG% If the source node was a DOM2DTM$defaultNamespaceDeclarationNode
548:                    // and the DTM wasn't registered with this DTMManager, we will create
549:                    // a new DTM and _still_ not be able to find the node (since it will
550:                    // be resynthesized). Another reason to push hard on making all DTMs
551:                    // be managed DTMs.
552:
553:                    // Since the real root of our tree may be a DocumentFragment, we need to
554:                    // use getParent to find the root, instead of getOwnerDocument.  Otherwise
555:                    // DOM2DTM#getHandleOfNode will be very unhappy.
556:                    Node root = node;
557:                    Node p = (root.getNodeType() == Node.ATTRIBUTE_NODE) ? ((org.w3c.dom.Attr) root)
558:                            .getOwnerElement()
559:                            : root.getParentNode();
560:                    for (; p != null; p = p.getParentNode()) {
561:                        root = p;
562:                    }
563:
564:                    DOM2DTM dtm = (DOM2DTM) getDTM(
565:                            new javax.xml.transform.dom.DOMSource(root), false,
566:                            null, true, true);
567:
568:                    int handle;
569:
570:                    if (node instanceof  org.apache.xml.dtm.ref.dom2dtm.DOM2DTMdefaultNamespaceDeclarationNode) {
571:                        // Can't return the same node since it's unique to a specific DTM, 
572:                        // but can return the equivalent node -- find the corresponding 
573:                        // Document Element, then ask it for the xml: namespace decl.
574:                        handle = dtm.getHandleOfNode(((org.w3c.dom.Attr) node)
575:                                .getOwnerElement());
576:                        handle = dtm.getAttributeNode(handle, node
577:                                .getNamespaceURI(), node.getLocalName());
578:                    } else
579:                        handle = ((DOM2DTM) dtm).getHandleOfNode(node);
580:
581:                    if (DTM.NULL == handle)
582:                        throw new RuntimeException(
583:                                XMLMessages
584:                                        .createXMLMessage(
585:                                                XMLErrorResources.ER_COULD_NOT_RESOLVE_NODE,
586:                                                null)); //"Could not resolve the node to a handle!");
587:
588:                    return handle;
589:                }
590:            }
591:
592:            /**
593:             * This method returns the SAX2 parser to use with the InputSource
594:             * obtained from this URI.
595:             * It may return null if any SAX2-conformant XML parser can be used,
596:             * or if getInputSource() will also return null. The parser must
597:             * be free for use (i.e., not currently in use for another parse().
598:             * After use of the parser is completed, the releaseXMLReader(XMLReader)
599:             * must be called.
600:             *
601:             * @param inputSource The value returned from the URIResolver.
602:             * @return  a SAX2 XMLReader to use to resolve the inputSource argument.
603:             *
604:             * @return non-null XMLReader reference ready to parse.
605:             */
606:            synchronized public XMLReader getXMLReader(Source inputSource) {
607:
608:                try {
609:                    XMLReader reader = (inputSource instanceof  SAXSource) ? ((SAXSource) inputSource)
610:                            .getXMLReader()
611:                            : null;
612:
613:                    // If user did not supply a reader, ask for one from the reader manager
614:                    if (null == reader) {
615:                        if (m_readerManager == null) {
616:                            m_readerManager = XMLReaderManager.getInstance();
617:                        }
618:
619:                        reader = m_readerManager.getXMLReader();
620:                    }
621:
622:                    return reader;
623:
624:                } catch (SAXException se) {
625:                    throw new DTMException(se.getMessage(), se);
626:                }
627:            }
628:
629:            /**
630:             * Indicates that the XMLReader object is no longer in use for the transform.
631:             *
632:             * Note that the getXMLReader method may return an XMLReader that was
633:             * specified on the SAXSource object by the application code.  Such a
634:             * reader should still be passed to releaseXMLReader, but the reader manager
635:             * will only re-use XMLReaders that it created.
636:             *
637:             * @param reader The XMLReader to be released.
638:             */
639:            synchronized public void releaseXMLReader(XMLReader reader) {
640:                if (m_readerManager != null) {
641:                    m_readerManager.releaseXMLReader(reader);
642:                }
643:            }
644:
645:            /**
646:             * Return the DTM object containing a representation of this node.
647:             *
648:             * @param nodeHandle DTM Handle indicating which node to retrieve
649:             *
650:             * @return a reference to the DTM object containing this node.
651:             */
652:            synchronized public DTM getDTM(int nodeHandle) {
653:                try {
654:                    // Performance critical function.
655:                    return m_dtms[nodeHandle >>> IDENT_DTM_NODE_BITS];
656:                } catch (java.lang.ArrayIndexOutOfBoundsException e) {
657:                    if (nodeHandle == DTM.NULL)
658:                        return null; // Accept as a special case.
659:                    else
660:                        throw e; // Programming error; want to know about it.
661:                }
662:            }
663:
664:            /**
665:             * Given a DTM, find the ID number in the DTM tables which addresses
666:             * the start of the document. If overflow addressing is in use, other
667:             * DTM IDs may also be assigned to this DTM.
668:             *
669:             * @param dtm The DTM which (hopefully) contains this node.
670:             *
671:             * @return The DTM ID (as the high bits of a NodeHandle, not as our
672:             * internal index), or -1 if the DTM doesn't belong to this manager.
673:             */
674:            synchronized public int getDTMIdentity(DTM dtm) {
675:                // Shortcut using DTMDefaultBase's extension hooks
676:                // %REVIEW% Should the lookup be part of the basic DTM API?
677:                if (dtm instanceof  DTMDefaultBase) {
678:                    DTMDefaultBase dtmdb = (DTMDefaultBase) dtm;
679:                    if (dtmdb.getManager() == this )
680:                        return dtmdb.getDTMIDs().elementAt(0);
681:                    else
682:                        return -1;
683:                }
684:
685:                int n = m_dtms.length;
686:
687:                for (int i = 0; i < n; i++) {
688:                    DTM tdtm = m_dtms[i];
689:
690:                    if (tdtm == dtm && m_dtm_offsets[i] == 0)
691:                        return i << IDENT_DTM_NODE_BITS;
692:                }
693:
694:                return -1;
695:            }
696:
697:            /**
698:             * Release the DTMManager's reference(s) to a DTM, making it unmanaged.
699:             * This is typically done as part of returning the DTM to the heap after
700:             * we're done with it.
701:             *
702:             * @param dtm the DTM to be released.
703:             * 
704:             * @param shouldHardDelete If false, this call is a suggestion rather than an
705:             * order, and we may not actually release the DTM. This is intended to 
706:             * support intelligent caching of documents... which is not implemented
707:             * in this version of the DTM manager.
708:             *
709:             * @return true if the DTM was released, false if shouldHardDelete was set
710:             * and we decided not to.
711:             */
712:            synchronized public boolean release(DTM dtm,
713:                    boolean shouldHardDelete) {
714:                if (DEBUG) {
715:                    System.out.println("Releasing "
716:                            + (shouldHardDelete ? "HARD" : "soft") + " dtm=" +
717:                            // Following shouldn't need a nodeHandle, but does...
718:                            // and doesn't seem to report the intended value
719:                            dtm.getDocumentBaseURI());
720:                }
721:
722:                if (dtm instanceof  SAX2DTM) {
723:                    ((SAX2DTM) dtm).clearCoRoutine();
724:                }
725:
726:                // Multiple DTM IDs may be assigned to a single DTM. 
727:                // The Right Answer is to ask which (if it supports
728:                // extension, the DTM will need a list anyway). The 
729:                // Wrong Answer, applied if the DTM can't help us,
730:                // is to linearly search them all; this may be very
731:                // painful.
732:                //
733:                // %REVIEW% Should the lookup move up into the basic DTM API?
734:                if (dtm instanceof  DTMDefaultBase) {
735:                    org.apache.xml.utils.SuballocatedIntVector ids = ((DTMDefaultBase) dtm)
736:                            .getDTMIDs();
737:                    for (int i = ids.size() - 1; i >= 0; --i)
738:                        m_dtms[ids.elementAt(i) >>> DTMManager.IDENT_DTM_NODE_BITS] = null;
739:                } else {
740:                    int i = getDTMIdentity(dtm);
741:                    if (i >= 0) {
742:                        m_dtms[i >>> DTMManager.IDENT_DTM_NODE_BITS] = null;
743:                    }
744:                }
745:
746:                dtm.documentRelease();
747:                return true;
748:            }
749:
750:            /**
751:             * Method createDocumentFragment
752:             *
753:             *
754:             * NEEDSDOC (createDocumentFragment) @return
755:             */
756:            synchronized public DTM createDocumentFragment() {
757:
758:                try {
759:                    DocumentBuilderFactory dbf = DocumentBuilderFactory
760:                            .newInstance();
761:
762:                    dbf.setNamespaceAware(true);
763:
764:                    DocumentBuilder db = dbf.newDocumentBuilder();
765:                    Document doc = db.newDocument();
766:                    Node df = doc.createDocumentFragment();
767:
768:                    return getDTM(new DOMSource(df), true, null, false, false);
769:                } catch (Exception e) {
770:                    throw new DTMException(e);
771:                }
772:            }
773:
774:            /**
775:             * NEEDSDOC Method createDTMIterator
776:             *
777:             *
778:             * NEEDSDOC @param whatToShow
779:             * NEEDSDOC @param filter
780:             * NEEDSDOC @param entityReferenceExpansion
781:             *
782:             * NEEDSDOC (createDTMIterator) @return
783:             */
784:            synchronized public DTMIterator createDTMIterator(int whatToShow,
785:                    DTMFilter filter, boolean entityReferenceExpansion) {
786:
787:                /** @todo: implement this org.apache.xml.dtm.DTMManager abstract method */
788:                return null;
789:            }
790:
791:            /**
792:             * NEEDSDOC Method createDTMIterator
793:             *
794:             *
795:             * NEEDSDOC @param xpathString
796:             * NEEDSDOC @param presolver
797:             *
798:             * NEEDSDOC (createDTMIterator) @return
799:             */
800:            synchronized public DTMIterator createDTMIterator(
801:                    String xpathString, PrefixResolver presolver) {
802:
803:                /** @todo: implement this org.apache.xml.dtm.DTMManager abstract method */
804:                return null;
805:            }
806:
807:            /**
808:             * NEEDSDOC Method createDTMIterator
809:             *
810:             *
811:             * NEEDSDOC @param node
812:             *
813:             * NEEDSDOC (createDTMIterator) @return
814:             */
815:            synchronized public DTMIterator createDTMIterator(int node) {
816:
817:                /** @todo: implement this org.apache.xml.dtm.DTMManager abstract method */
818:                return null;
819:            }
820:
821:            /**
822:             * NEEDSDOC Method createDTMIterator
823:             *
824:             *
825:             * NEEDSDOC @param xpathCompiler
826:             * NEEDSDOC @param pos
827:             *
828:             * NEEDSDOC (createDTMIterator) @return
829:             */
830:            synchronized public DTMIterator createDTMIterator(
831:                    Object xpathCompiler, int pos) {
832:
833:                /** @todo: implement this org.apache.xml.dtm.DTMManager abstract method */
834:                return null;
835:            }
836:
837:            /**
838:             * return the expanded name table.
839:             *
840:             * NEEDSDOC @param dtm
841:             *
842:             * NEEDSDOC ($objectName$) @return
843:             */
844:            public ExpandedNameTable getExpandedNameTable(DTM dtm) {
845:                return m_expandedNameTable;
846:            }
847:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.