View Javadoc
1   /**
2    * Copyright (C) 2014-2017 Philip Helger (www.helger.com)
3    * philip[at]helger[dot]com
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *         http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package com.helger.schematron;
18  
19  import java.io.InputStream;
20  import java.io.Reader;
21  import java.net.MalformedURLException;
22  
23  import javax.annotation.Nonnull;
24  import javax.annotation.Nullable;
25  import javax.annotation.concurrent.Immutable;
26  import javax.xml.transform.Source;
27  import javax.xml.transform.dom.DOMSource;
28  import javax.xml.transform.stream.StreamSource;
29  
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  import org.w3c.dom.Document;
33  import org.w3c.dom.Node;
34  import org.xml.sax.SAXException;
35  
36  import com.helger.commons.ValueEnforcer;
37  import com.helger.commons.annotation.PresentForCodeCoverage;
38  import com.helger.commons.io.resource.URLResource;
39  import com.helger.commons.string.StringHelper;
40  import com.helger.xml.serialize.read.DOMReader;
41  import com.helger.xml.serialize.read.DOMReaderSettings;
42  
43  /**
44   * This is a common utility class.
45   *
46   * @author Philip Helger
47   */
48  @Immutable
49  public final class SchematronResourceHelper
50  {
51    private static final Logger s_aLogger = LoggerFactory.getLogger (SchematronResourceHelper.class);
52  
53    @PresentForCodeCoverage
54    private static final SchematronResourceHelper s_aInstance = new SchematronResourceHelper ();
55  
56    private SchematronResourceHelper ()
57    {}
58  
59    /**
60     * Convert the passed transform source into a DOM node. Currently on
61     * {@link DOMSource} and {@link StreamSource} can be handled.
62     *
63     * @param aSource
64     *        The transform source to use. May not be <code>null</code>.
65     * @param aDRS
66     *        DOMReader settings to use. May not be <code>null</code>.
67     * @return The DOM node and never <code>null</code>.
68     * @throws SAXException
69     *         In case XML parsing fails
70     * @throws IllegalArgumentException
71     *         in case an unsupported {@link Source} implementation is provided.
72     */
73    @Nullable
74    public static Node getNodeOfSource (@Nonnull final Source aSource,
75                                        @Nonnull final DOMReaderSettings aDRS) throws SAXException
76    {
77      ValueEnforcer.notNull (aSource, "Source");
78      ValueEnforcer.notNull (aDRS, "DOMReaderSettings");
79  
80      if (aSource instanceof DOMSource)
81      {
82        // Node is already in DOMSource
83        return ((DOMSource) aSource).getNode ();
84      }
85  
86      if (aSource instanceof StreamSource)
87      {
88        // In StreamSource it can either be a byte stream or a character stream or
89        // a system ID
90        final StreamSource aStreamSource = (StreamSource) aSource;
91  
92        final InputStream aIS = aStreamSource.getInputStream ();
93        if (aIS != null)
94        {
95          // Byte stream
96          final Document aDoc = DOMReader.readXMLDOM (aIS, aDRS != null ? aDRS : new DOMReaderSettings ());
97          if (aDoc == null)
98            throw new IllegalArgumentException ("Failed to read source " + aSource + " as XML from InputStream " + aIS);
99          return aDoc;
100       }
101 
102       final Reader aReader = aStreamSource.getReader ();
103       if (aReader != null)
104       {
105         // CHaracter stream
106         final Document aDoc = DOMReader.readXMLDOM (aReader, aDRS);
107         if (aDoc == null)
108           throw new IllegalArgumentException ("Failed to read source " + aSource + " as XML from Reader " + aReader);
109         return aDoc;
110       }
111 
112       final String sSystemID = aStreamSource.getSystemId ();
113       if (StringHelper.hasText (sSystemID))
114       {
115         // System ID
116         try
117         {
118           final URLResource aURL = new URLResource (sSystemID);
119           final Document aDoc = DOMReader.readXMLDOM (aURL, aDRS);
120           if (aDoc == null)
121             throw new IllegalArgumentException ("Failed to read source " +
122                                                 aSource +
123                                                 " as XML from SystemID '" +
124                                                 sSystemID +
125                                                 "'");
126           return aDoc;
127         }
128         catch (final MalformedURLException ex)
129         {
130           throw new IllegalArgumentException ("Failed to read source " +
131                                               aSource +
132                                               " as XML from SystemID '" +
133                                               sSystemID +
134                                               "': " +
135                                               ex.getMessage ());
136         }
137       }
138 
139       // Neither InputStream nor Reader present
140       s_aLogger.error ("StreamSource contains neither InputStream nor Reader nor SystemID - cannot handle!");
141       return null;
142     }
143 
144     final String sMsg = "Can only handle DOMSource and StreamSource - having " +
145                         aSource +
146                         " with system ID '" +
147                         aSource.getSystemId () +
148                         "'";
149     s_aLogger.error (sMsg);
150     throw new IllegalArgumentException (sMsg);
151   }
152 }