- /*
- * Copyright 2001-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*
- * $Id: LoadDocument.java,v 1.25 2004/02/16 22:54:59 minchau Exp $
- */
-
- package com.sun.org.apache.xalan.internal.xsltc.dom;
-
- import java.io.FileNotFoundException;
-
- import javax.xml.transform.stream.StreamSource;
-
- import com.sun.org.apache.xalan.internal.xsltc.DOM;
- import com.sun.org.apache.xalan.internal.xsltc.DOMCache;
- import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
- import com.sun.org.apache.xalan.internal.xsltc.TransletException;
- import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
- import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
- import com.sun.org.apache.xml.internal.dtm.DTM;
- import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
- import com.sun.org.apache.xml.internal.dtm.DTMManager;
- import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase;
- import com.sun.org.apache.xml.internal.dtm.ref.EmptyIterator;
- import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
-
- import org.xml.sax.InputSource;
- import org.xml.sax.XMLReader;
-
- /**
- * @author Morten Jorgensen
- */
- public final class LoadDocument {
-
- private static final String NAMESPACE_FEATURE =
- "http://xml.org/sax/features/namespaces";
-
- /**
- * Interprets the arguments passed from the document() function (see
- * com/sun/org/apache/xalan/internal/xsltc/compiler/DocumentCall.java) and returns an
- * iterator containing the requested nodes. Builds a union-iterator if
- * several documents are requested.
- * 2 arguments arg1 and arg2. document(Obj, node-set) call
- */
- public static DTMAxisIterator documentF(Object arg1, DTMAxisIterator arg2,
- String xslURI, AbstractTranslet translet, DOM dom)
- throws TransletException {
- String baseURI = null;
- final int arg2FirstNode = arg2.next();
- if (arg2FirstNode == DTMAxisIterator.END) {
- // the second argument node-set is empty
- return EmptyIterator.getInstance();
- } else {
- //System.err.println("arg2FirstNode name: "
- // + dom.getNodeName(arg2FirstNode )+"["
- // +Integer.toHexString(arg2FirstNode )+"]");
- baseURI = dom.getDocumentURI(arg2FirstNode);
- if (!SystemIDResolver.isAbsoluteURI(baseURI))
- baseURI = SystemIDResolver.getAbsoluteURIFromRelative(baseURI);
- }
-
- try {
- if (arg1 instanceof String) {
- if (((String)arg1).length() == 0) {
- return document(xslURI, "", translet, dom);
- } else {
- return document((String)arg1, baseURI, translet, dom);
- }
- } else if (arg1 instanceof DTMAxisIterator) {
- return document((DTMAxisIterator)arg1, baseURI, translet, dom);
- } else {
- final String err = "document("+arg1.toString()+")";
- throw new IllegalArgumentException(err);
- }
- } catch (Exception e) {
- throw new TransletException(e);
- }
- }
- /**
- * Interprets the arguments passed from the document() function (see
- * com/sun/org/apache/xalan/internal/xsltc/compiler/DocumentCall.java) and returns an
- * iterator containing the requested nodes. Builds a union-iterator if
- * several documents are requested.
- * 1 arguments arg. document(Obj) call
- */
- public static DTMAxisIterator documentF(Object arg, String xslURI,
- AbstractTranslet translet, DOM dom)
- throws TransletException {
- try {
- if (arg instanceof String) {
- if (xslURI == null )
- xslURI="";
- String baseURI = xslURI;
- if (!SystemIDResolver.isAbsoluteURI(xslURI))
- baseURI = SystemIDResolver.getAbsoluteURIFromRelative(xslURI);
-
- String href = (String)arg;
- if (href.length() == 0) {
- href = "";
- // %OPT% Optimization to cache the stylesheet DOM.
- // The stylesheet DOM is built once and cached
- // in the Templates object.
- TemplatesImpl templates = (TemplatesImpl)translet.getTemplates();
- DOM sdom = null;
- if (templates != null) {
- sdom = templates.getStylesheetDOM();
- }
-
- // If the cached dom exists, we need to migrate it
- // to the new DTMManager and create a DTMAxisIterator
- // for the document.
- if (sdom != null) {
- return document(sdom, translet, dom);
- }
- else {
- return document(href, baseURI, translet, dom, true);
- }
- }
- else {
- return document(href, baseURI, translet, dom);
- }
- } else if (arg instanceof DTMAxisIterator) {
- return document((DTMAxisIterator)arg, null, translet, dom);
- } else {
- final String err = "document("+arg.toString()+")";
- throw new IllegalArgumentException(err);
- }
- } catch (Exception e) {
- throw new TransletException(e);
- }
- }
-
- private static DTMAxisIterator document(String uri, String base,
- AbstractTranslet translet, DOM dom)
- throws Exception
- {
- return document(uri, base, translet, dom, false);
- }
-
- private static DTMAxisIterator document(String uri, String base,
- AbstractTranslet translet, DOM dom,
- boolean cacheDOM)
- throws Exception
- {
- try {
- final String originalUri = uri;
- MultiDOM multiplexer = (MultiDOM)dom;
-
- // Prepend URI base to URI (from context)
- if (base != null && !base.equals("")) {
- uri = SystemIDResolver.getAbsoluteURI(uri, base);
- }
-
- // Return an empty iterator if the URI is clearly invalid
- // (to prevent some unncessary MalformedURL exceptions).
- if (uri == null || uri.equals("")) {
- return(EmptyIterator.getInstance());
- }
-
- // Check if this DOM has already been added to the multiplexer
- int mask = multiplexer.getDocumentMask(uri);
- if (mask != -1) {
- DOM newDom = ((DOMAdapter)multiplexer.getDOMAdapter(uri))
- .getDOMImpl();
- if (newDom instanceof DOMEnhancedForDTM) {
- return new SingletonIterator(((DOMEnhancedForDTM)newDom)
- .getDocument(),
- true);
- }
- }
-
- // Check if we can get the DOM from a DOMCache
- DOMCache cache = translet.getDOMCache();
- DOM newdom;
-
- mask = multiplexer.nextMask(); // peek
-
- if (cache != null) {
- newdom = cache.retrieveDocument(base, originalUri, translet);
- if (newdom == null) {
- final Exception e = new FileNotFoundException(originalUri);
- throw new TransletException(e);
- }
- } else {
- // Parse the input document and construct DOM object
- // Trust the DTMManager to pick the right parser and
- // set up the DOM correctly.
- XSLTCDTMManager dtmManager = (XSLTCDTMManager)multiplexer
- .getDTMManager();
- DOMEnhancedForDTM enhancedDOM =
- (DOMEnhancedForDTM) dtmManager.getDTM(new StreamSource(uri),
- false, null, true, false,
- translet.hasIdCall(), cacheDOM);
- newdom = enhancedDOM;
-
- // Cache the stylesheet DOM in the Templates object
- if (cacheDOM) {
- TemplatesImpl templates = (TemplatesImpl)translet.getTemplates();
- if (templates != null) {
- templates.setStylesheetDOM(enhancedDOM);
- }
- }
-
- translet.prepassDocument(enhancedDOM);
- enhancedDOM.setDocumentURI(uri);
- }
-
- // Wrap the DOM object in a DOM adapter and add to multiplexer
- final DOMAdapter domAdapter = translet.makeDOMAdapter(newdom);
- multiplexer.addDOMAdapter(domAdapter);
-
- // Create index for any key elements
- translet.buildKeys(domAdapter, null, null, newdom.getDocument());
-
- // Return a singleton iterator containing the root node
- return new SingletonIterator(newdom.getDocument(), true);
- } catch (Exception e) {
- throw e;
- }
- }
-
-
- private static DTMAxisIterator document(DTMAxisIterator arg1,
- String baseURI,
- AbstractTranslet translet, DOM dom)
- throws Exception
- {
- UnionIterator union = new UnionIterator(dom);
- int node = DTM.NULL;
-
- while ((node = arg1.next()) != DTM.NULL) {
- String uri = dom.getStringValueX(node);
- //document(node-set) if true; document(node-set,node-set) if false
- if (baseURI == null) {
- baseURI = dom.getDocumentURI(node);
- if (!SystemIDResolver.isAbsoluteURI(baseURI))
- baseURI = SystemIDResolver.getAbsoluteURIFromRelative(baseURI);
- }
- union.addIterator(document(uri, baseURI, translet, dom));
- }
- return(union);
- }
-
- /**
- * Create a DTMAxisIterator for the newdom. This is currently only
- * used to create an iterator for the cached stylesheet DOM.
- *
- * @param newdom the cached stylesheet DOM
- * @param translet the translet
- * @param the main dom (should be a MultiDOM)
- * @return a DTMAxisIterator from the document root
- */
- private static DTMAxisIterator document(DOM newdom,
- AbstractTranslet translet,
- DOM dom)
- throws Exception
- {
- DTMManager dtmManager = ((MultiDOM)dom).getDTMManager();
- // Need to migrate the cached DTM to the new DTMManager
- if (dtmManager != null && newdom instanceof DTM) {
- ((DTM)newdom).migrateTo(dtmManager);
- }
-
- translet.prepassDocument(newdom);
-
- // Wrap the DOM object in a DOM adapter and add to multiplexer
- final DOMAdapter domAdapter = translet.makeDOMAdapter(newdom);
- ((MultiDOM)dom).addDOMAdapter(domAdapter);
-
- // Create index for any key elements
- translet.buildKeys(domAdapter, null, null,
- newdom.getDocument());
-
- // Return a singleton iterator containing the root node
- return new SingletonIterator(newdom.getDocument(), true);
- }
-
- }