1/*
2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3 */
4/*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements.  See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License.  You may obtain a copy of the License at
11 *
12 *     http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21package com.sun.org.apache.xalan.internal.xsltc.trax;
22
23import com.sun.org.apache.xalan.internal.XalanConstants;
24import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
25import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
26import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC;
27import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
28import java.io.InputStream;
29import java.io.Reader;
30import javax.xml.XMLConstants;
31import javax.xml.catalog.CatalogFeatures;
32import javax.xml.catalog.CatalogFeatures.Feature;
33import javax.xml.parsers.ParserConfigurationException;
34import javax.xml.parsers.SAXParserFactory;
35import javax.xml.stream.XMLEventReader;
36import javax.xml.stream.XMLStreamReader;
37import javax.xml.transform.Source;
38import javax.xml.transform.TransformerConfigurationException;
39import javax.xml.transform.dom.DOMSource;
40import javax.xml.transform.sax.SAXSource;
41import javax.xml.transform.stax.StAXSource;
42import javax.xml.transform.stream.StreamSource;
43import jdk.xml.internal.JdkXmlFeatures;
44import jdk.xml.internal.JdkXmlUtils;
45import org.w3c.dom.Document;
46import org.xml.sax.InputSource;
47import org.xml.sax.SAXException;
48import org.xml.sax.SAXNotRecognizedException;
49import org.xml.sax.SAXNotSupportedException;
50import org.xml.sax.XMLReader;
51import org.xml.sax.helpers.XMLReaderFactory;
52
53/**
54 * @author Santiago Pericas-Geertsen
55 *
56 * Added Catalog Support for URI resolution
57 */
58public final class Util {
59
60    public static String baseName(String name) {
61        return com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util.baseName(name);
62    }
63
64    public static String noExtName(String name) {
65        return com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util.noExtName(name);
66    }
67
68    public static String toJavaName(String name) {
69        return com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util.toJavaName(name);
70    }
71
72    /**
73     * Creates a SAX2 InputSource object from a TrAX Source object
74     */
75    public static InputSource getInputSource(XSLTC xsltc, Source source)
76        throws TransformerConfigurationException
77    {
78        InputSource input = null;
79
80        String systemId = source.getSystemId();
81
82        try {
83            // Try to get InputSource from SAXSource input
84            if (source instanceof SAXSource) {
85                final SAXSource sax = (SAXSource)source;
86                input = sax.getInputSource();
87                // Pass the SAX parser to the compiler
88                try {
89                    XMLReader reader = sax.getXMLReader();
90
91                     /*
92                      * Fix for bug 24695
93                      * According to JAXP 1.2 specification if a SAXSource
94                      * is created using a SAX InputSource the Transformer or
95                      * TransformerFactory creates a reader via the
96                      * XMLReaderFactory if setXMLReader is not used
97                      */
98
99                    if (reader == null) {
100                       try {
101                           reader= XMLReaderFactory.createXMLReader();
102                           try {
103                                reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
104                                            xsltc.isSecureProcessing());
105                           } catch (SAXNotRecognizedException e) {
106                                XMLSecurityManager.printWarning(reader.getClass().getName(),
107                                        XMLConstants.FEATURE_SECURE_PROCESSING, e);
108                           }
109                       } catch (Exception e ) {
110                           try {
111
112                               //Incase there is an exception thrown
113                               // resort to JAXP
114                               SAXParserFactory parserFactory = FactoryImpl.getSAXFactory(xsltc.useServicesMechnism());
115                               parserFactory.setNamespaceAware(true);
116
117                               if (xsltc.isSecureProcessing()) {
118                                  try {
119                                      parserFactory.setFeature(
120                                          XMLConstants.FEATURE_SECURE_PROCESSING, true);
121                                  }
122                                  catch (org.xml.sax.SAXException se) {}
123                               }
124
125                               reader = parserFactory.newSAXParser()
126                                     .getXMLReader();
127
128
129                           } catch (ParserConfigurationException pce ) {
130                               throw new TransformerConfigurationException
131                                 ("ParserConfigurationException" ,pce);
132                           }
133                       }
134                    }
135                    reader.setFeature
136                        ("http://xml.org/sax/features/namespaces",true);
137                    reader.setFeature
138                        ("http://xml.org/sax/features/namespace-prefixes",false);
139
140                    JdkXmlUtils.setXMLReaderPropertyIfSupport(reader, XMLConstants.ACCESS_EXTERNAL_DTD,
141                            xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD), true);
142
143                    JdkXmlUtils.setXMLReaderPropertyIfSupport(reader, JdkXmlUtils.CDATA_CHUNK_SIZE,
144                            xsltc.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE), false);
145
146                    String lastProperty = "";
147                    try {
148                        XMLSecurityManager securityManager =
149                                (XMLSecurityManager)xsltc.getProperty(XalanConstants.SECURITY_MANAGER);
150                        if (securityManager != null) {
151                            for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
152                                lastProperty = limit.apiProperty();
153                                reader.setProperty(lastProperty,
154                                        securityManager.getLimitValueAsString(limit));
155                            }
156                            if (securityManager.printEntityCountInfo()) {
157                                lastProperty = XalanConstants.JDK_ENTITY_COUNT_INFO;
158                                reader.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES);
159                            }
160                        }
161                    } catch (SAXException se) {
162                        XMLSecurityManager.printWarning(reader.getClass().getName(), lastProperty, se);
163                    }
164
165                    boolean supportCatalog = true;
166                    boolean useCatalog = xsltc.getFeature(JdkXmlFeatures.XmlFeature.USE_CATALOG);
167                    try {
168                        reader.setFeature(JdkXmlUtils.USE_CATALOG, useCatalog);
169                    }
170                    catch (SAXNotRecognizedException | SAXNotSupportedException e) {
171                        supportCatalog = false;
172                    }
173
174                    if (supportCatalog & useCatalog) {
175                        try {
176                            CatalogFeatures cf = (CatalogFeatures)xsltc.getProperty(JdkXmlFeatures.CATALOG_FEATURES);
177                            if (cf != null) {
178                                for (Feature f : CatalogFeatures.Feature.values()) {
179                                    reader.setProperty(f.getPropertyName(), cf.get(f));
180                                }
181                            }
182                        } catch (SAXNotRecognizedException e) {
183                            //shall not happen for internal settings
184                        }
185                    }
186
187                    xsltc.setXMLReader(reader);
188                }catch (SAXNotRecognizedException snre ) {
189                  throw new TransformerConfigurationException
190                       ("SAXNotRecognizedException ",snre);
191                }catch (SAXNotSupportedException snse ) {
192                  throw new TransformerConfigurationException
193                       ("SAXNotSupportedException ",snse);
194                }catch (SAXException se ) {
195                  throw new TransformerConfigurationException
196                       ("SAXException ",se);
197                }
198
199            }
200            // handle  DOMSource
201            else if (source instanceof DOMSource) {
202                final DOMSource domsrc = (DOMSource)source;
203                final Document dom = (Document)domsrc.getNode();
204                final DOM2SAX dom2sax = new DOM2SAX(dom);
205                xsltc.setXMLReader(dom2sax);
206
207                // Try to get SAX InputSource from DOM Source.
208                input = SAXSource.sourceToInputSource(source);
209                if (input == null){
210                    input = new InputSource(domsrc.getSystemId());
211                }
212            }
213
214            // handle StAXSource
215            else if (source instanceof StAXSource) {
216                final StAXSource staxSource = (StAXSource)source;
217                StAXEvent2SAX staxevent2sax = null;
218                StAXStream2SAX staxStream2SAX = null;
219                if (staxSource.getXMLEventReader() != null) {
220                    final XMLEventReader xmlEventReader = staxSource.getXMLEventReader();
221                    staxevent2sax = new StAXEvent2SAX(xmlEventReader);
222                    xsltc.setXMLReader(staxevent2sax);
223                } else if (staxSource.getXMLStreamReader() != null) {
224                    final XMLStreamReader xmlStreamReader = staxSource.getXMLStreamReader();
225                    staxStream2SAX = new StAXStream2SAX(xmlStreamReader);
226                    xsltc.setXMLReader(staxStream2SAX);
227                }
228
229                // get sax InputSource from StAXSource
230                input = SAXSource.sourceToInputSource(source);
231                if (input == null){
232                    input = new InputSource(staxSource.getSystemId());
233                }
234            }
235
236            // Try to get InputStream or Reader from StreamSource
237            else if (source instanceof StreamSource) {
238                final StreamSource stream = (StreamSource)source;
239                final InputStream istream = stream.getInputStream();
240                final Reader reader = stream.getReader();
241                xsltc.setXMLReader(null);     // Clear old XML reader
242
243                // Create InputSource from Reader or InputStream in Source
244                if (istream != null) {
245                    input = new InputSource(istream);
246                }
247                else if (reader != null) {
248                    input = new InputSource(reader);
249                }
250                else {
251                    input = new InputSource(systemId);
252                }
253            }
254            else {
255                ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_SOURCE_ERR);
256                throw new TransformerConfigurationException(err.toString());
257            }
258            input.setSystemId(systemId);
259        }
260        catch (NullPointerException e) {
261            ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR,
262                                        "TransformerFactory.newTemplates()");
263            throw new TransformerConfigurationException(err.toString());
264        }
265        catch (SecurityException e) {
266            ErrorMsg err = new ErrorMsg(ErrorMsg.FILE_ACCESS_ERR, systemId);
267            throw new TransformerConfigurationException(err.toString());
268        }
269        return input;
270    }
271
272}
273