View Javadoc
1   /**
2    * Copyright (C) 2014-2016 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  
42  /**
43   * This is a common utility class.
44   *
45   * @author Philip Helger
46   */
47  @Immutable
48  public final class SchematronResourceHelper
49  {
50    private static final Logger s_aLogger = LoggerFactory.getLogger (SchematronResourceHelper.class);
51  
52    @PresentForCodeCoverage
53    private static final SchematronResourceHelper s_aInstance = new SchematronResourceHelper ();
54  
55    private SchematronResourceHelper ()
56    {}
57  
58    /**
59     * Convert the passed transform source into a DOM node. Currently on
60     * {@link DOMSource} and {@link StreamSource} can be handled.
61     *
62     * @param aSource
63     *        The transform source to use. May not be <code>null</code>.
64     * @return The DOM node and never <code>null</code>.
65     * @throws SAXException
66     *         In case XML parsing fails
67     * @throws IllegalArgumentException
68     *         in case an unsupported {@link Source} implementation is provided.
69     */
70    @Nullable
71    public static Node getNodeOfSource (@Nonnull final Source aSource) throws SAXException
72    {
73      ValueEnforcer.notNull (aSource, "Source");
74  
75      if (aSource instanceof DOMSource)
76      {
77        // Node is already in DOMSource
78        return ((DOMSource) aSource).getNode ();
79      }
80  
81      if (aSource instanceof StreamSource)
82      {
83        // In StreamSource it can either be a byte stream or a character stream or
84        // a system ID
85        final StreamSource aStreamSource = (StreamSource) aSource;
86  
87        final InputStream aIS = aStreamSource.getInputStream ();
88        if (aIS != null)
89        {
90          // Byte stream
91          final Document aDoc = DOMReader.readXMLDOM (aIS);
92          if (aDoc == null)
93            throw new IllegalArgumentException ("Failed to read source " + aSource + " as XML from InputStream " + aIS);
94          return aDoc;
95        }
96  
97        final Reader aReader = aStreamSource.getReader ();
98        if (aReader != null)
99        {
100         // CHaracter stream
101         final Document aDoc = DOMReader.readXMLDOM (aReader);
102         if (aDoc == null)
103           throw new IllegalArgumentException ("Failed to read source " + aSource + " as XML from Reader " + aReader);
104         return aDoc;
105       }
106 
107       final String sSystemID = aStreamSource.getSystemId ();
108       if (StringHelper.hasText (sSystemID))
109       {
110         // System ID
111         try
112         {
113           final URLResource aURL = new URLResource (sSystemID);
114           final Document aDoc = DOMReader.readXMLDOM (aURL);
115           if (aDoc == null)
116             throw new IllegalArgumentException ("Failed to read source " +
117                                                 aSource +
118                                                 " as XML from SystemID '" +
119                                                 sSystemID +
120                                                 "'");
121           return aDoc;
122         }
123         catch (final MalformedURLException ex)
124         {
125           throw new IllegalArgumentException ("Failed to read source " +
126                                               aSource +
127                                               " as XML from SystemID '" +
128                                               sSystemID +
129                                               "': " +
130                                               ex.getMessage ());
131         }
132       }
133 
134       // Neither InputStream nor Reader present
135       s_aLogger.error ("StreamSource contains neither InputStream nor Reader nor SystemID - cannot handle!");
136       return null;
137     }
138 
139     final String sMsg = "Can only handle DOMSource and StreamSource - having " +
140                         aSource +
141                         " with system ID '" +
142                         aSource.getSystemId () +
143                         "'";
144     s_aLogger.error (sMsg);
145     throw new IllegalArgumentException (sMsg);
146   }
147 }