001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.jxpath;
019
020import java.net.URL;
021import java.util.Objects;
022
023import javax.xml.transform.Source;
024import javax.xml.transform.Transformer;
025import javax.xml.transform.TransformerFactory;
026import javax.xml.transform.dom.DOMResult;
027
028import org.apache.commons.jxpath.xml.DocumentContainer;
029
030/**
031 * An XML document container reads and parses XML only when it is accessed. JXPath traverses Containers transparently - you use the same paths to access objects
032 * in containers as you do to access those objects directly. You can create XMLDocumentContainers for various XML documents that may or may not be accessed by
033 * XPaths. If they are, they will be automatically read, parsed and traversed. If they are not - they won't be read at all.
034 *
035 * @deprecated 1.1 Please use {@link DocumentContainer}
036 */
037@Deprecated
038public class XMLDocumentContainer implements Container {
039
040    private static final long serialVersionUID = 1L;
041
042    /** The delegate document container. */
043    private DocumentContainer delegate;
044
045    /** The DOM document. */
046    private Object document;
047
048    /**
049     * The document source.
050     */
051    private URL xmlURL;
052
053    /**
054     * The transformation source.
055     */
056    private Source source;
057
058    /**
059     * Constructs a new XMLDocumentContainer.
060     *
061     * @param source XML source
062     */
063    public XMLDocumentContainer(final Source source) {
064        this.source = Objects.requireNonNull(source);
065    }
066
067    /**
068     * Constructs a new XMLDocumentContainer.
069     *
070     * @param xmlURL a URL for an XML file. Use getClass().getResource(resourceName) to load XML from a resource file.
071     */
072    public XMLDocumentContainer(final URL xmlURL) {
073        this.xmlURL = xmlURL;
074        delegate = new DocumentContainer(xmlURL);
075    }
076
077    /**
078     * Reads XML, caches it internally and returns the Document.
079     *
080     * @return Object value
081     */
082    @Override
083    public Object getValue() {
084        if (document == null) {
085            try {
086                if (source != null) {
087                    final DOMResult result = new DOMResult();
088                    final Transformer trans = TransformerFactory.newInstance().newTransformer();
089                    trans.transform(source, result);
090                    document = result.getNode();
091                } else {
092                    document = delegate.getValue();
093                }
094            } catch (final Exception ex) {
095                throw new JXPathException(
096                        "Cannot read XML from: " + (xmlURL != null ? xmlURL.toString() : source != null ? source.getSystemId() : "<<undefined source>>"), ex);
097            }
098        }
099        return document;
100    }
101
102    /**
103     * Throws an UnsupportedOperationException
104     *
105     * @param value to set
106     */
107    @Override
108    public void setValue(final Object value) {
109        throw new UnsupportedOperationException();
110    }
111}