package client.net.sf.saxon.ce.om; import java.util.*; /** * An object representing the collection of documents handled during * a single transformation. * * <p>The function of allocating document numbers is performed * by the DocumentNumberAllocator in the Configuration, not by the DocumentPool. This has a * number of effects: in particular it allows operations involving multiple * documents (such as generateId() and document()) to occur in a free-standing * XPath environment.</p> */ public final class DocumentPool { // The document pool ensures that the document() // function, when called twice with the same URI, returns the same document // each time. For this purpose we use a hashtable from // URI to DocumentInfo object. private Map<DocumentURI, DocumentInfo> documentNameMap = new HashMap<DocumentURI, DocumentInfo>(10); // The set of documents known to be unavailable. These documents must remain // unavailable for the duration of a transformation or query! private Set<DocumentURI> unavailableDocuments = new HashSet<DocumentURI>(10); /** * Add a document to the pool * @param doc The DocumentInfo for the document in question * @param uri The document-uri property of the document. */ public void add(DocumentInfo doc, String uri) { if (uri!=null) { documentNameMap.put(new DocumentURI(uri), doc); } } /** * Add a document to the pool * @param doc The DocumentInfo for the document in question * @param uri The document-uri property of the document. */ public void add(DocumentInfo doc, DocumentURI uri) { if (uri!=null) { documentNameMap.put(uri, doc); } } /** * Get the document with a given document-uri * @param uri The document-uri property of the document. * @return the DocumentInfo with the given document-uri property if it exists, * or null if it is not found. */ public DocumentInfo find(String uri) { return documentNameMap.get(new DocumentURI(uri)); } /** * Get the document with a given document-uri * @param uri The document-uri property of the document. * @return the DocumentInfo with the given document-uri property if it exists, * or null if it is not found. */ public DocumentInfo find(DocumentURI uri) { return documentNameMap.get(uri); } /** * Get the URI for a given document node, if it is present in the pool. This supports the * document-uri() function. * @param doc The document node * @return The uri of the document node, if present in the pool, or the systemId of the document node otherwise */ public String getDocumentURI(NodeInfo doc) { Iterator<DocumentURI> iter = documentNameMap.keySet().iterator(); while (iter.hasNext()) { DocumentURI uri = iter.next(); if (find(uri).isSameNodeInfo(doc)) { return uri.toString(); } } return null; } /** * Determine whether a given document is present in the pool * @param doc the document being sought * @return true if the document is present, false otherwise */ public boolean contains(DocumentInfo doc) { // relies on "equals" for nodes comparing node identity return documentNameMap.values().contains(doc); } /** * Release a document from the document pool. This means that if the same document is * loaded again later, the source will need to be re-parsed, and nodes will get new identities. * @param doc the document to be discarded from the pool * @return the document supplied in the doc parameter */ public DocumentInfo discard(DocumentInfo doc) { for (Map.Entry<DocumentURI, DocumentInfo> e : documentNameMap.entrySet()) { DocumentURI name = e.getKey(); DocumentInfo entry = e.getValue(); if (entry.isSameNodeInfo(doc)) { documentNameMap.remove(name); return doc; } } return doc; } /** * Add a document URI to the set of URIs known to be unavailable (because doc-available() has returned * false * @param uri the URI of the unavailable document */ public void markUnavailable(DocumentURI uri) { unavailableDocuments.add(uri); } /** * Ask whether a document URI is in the set of URIs known to be unavailable, because doc-available() * has been previously called and has returned false */ public boolean isMarkedUnavailable(DocumentURI uri) { return unavailableDocuments.contains(uri); } } // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.