1/*
2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.xml.internal.ws.util.xml;
27
28import com.sun.istack.internal.Nullable;
29import com.sun.xml.internal.ws.server.ServerRtException;
30import java.io.File;
31import java.net.URI;
32import java.net.URL;
33import java.util.ArrayList;
34import java.util.Collections;
35import java.util.Enumeration;
36import javax.xml.catalog.CatalogFeatures;
37import javax.xml.catalog.CatalogFeatures.Feature;
38import javax.xml.catalog.CatalogManager;
39import javax.xml.ws.WebServiceException;
40import org.xml.sax.EntityResolver;
41
42/**
43 *
44 * @author lukas
45 */
46public class XmlCatalogUtil {
47
48    // Cache CatalogFeatures instance for future usages.
49    // Resolve feature is set to "continue" value for backward compatibility.
50    private static final CatalogFeatures CATALOG_FEATURES
51            = CatalogFeatures.builder().with(Feature.RESOLVE, "continue").build();
52
53    /**
54     * Gets an EntityResolver using XML catalog
55     *
56     * @param catalogUrl
57     * @return
58     */
59    public static EntityResolver createEntityResolver(@Nullable URL catalogUrl) {
60        ArrayList<URL> urlsArray = new ArrayList<>();
61        EntityResolver er;
62        if (catalogUrl != null) {
63            urlsArray.add(catalogUrl);
64        }
65        try {
66            er = createCatalogResolver(urlsArray);
67        } catch (Exception e) {
68            throw new ServerRtException("server.rt.err", e);
69        }
70        return er;
71    }
72
73    /**
74     * Gets a default EntityResolver for catalog at META-INF/jaxws-catalog.xml
75     *
76     * @return
77     */
78    public static EntityResolver createDefaultCatalogResolver() {
79        EntityResolver er;
80        try {
81            /**
82             * Gets a URLs for catalog defined at META-INF/jaxws-catalog.xml
83             */
84            ClassLoader cl = Thread.currentThread().getContextClassLoader();
85            Enumeration<URL> catalogEnum;
86            if (cl == null) {
87                catalogEnum = ClassLoader.getSystemResources("META-INF/jax-ws-catalog.xml");
88            } else {
89                catalogEnum = cl.getResources("META-INF/jax-ws-catalog.xml");
90            }
91            er = createCatalogResolver(Collections.list(catalogEnum));
92        } catch (Exception e) {
93            throw new WebServiceException(e);
94        }
95
96        return er;
97    }
98
99    /**
100     * Instantiate catalog resolver using new catalog API (javax.xml.catalog.*)
101     * added in JDK9. Usage of new API removes dependency on internal API
102     * (com.sun.org.apache.xml.internal) for modular runtime.
103     */
104    private static EntityResolver createCatalogResolver(ArrayList<URL> urls) throws Exception {
105        // Prepare array of catalog URIs
106        URI[] uris = urls.stream()
107                             .map(u -> URI.create(u.toExternalForm()))
108                             .toArray(URI[]::new);
109
110        //Create CatalogResolver with new JDK9+ API
111        return (EntityResolver) CatalogManager.catalogResolver(CATALOG_FEATURES, uris);
112    }
113
114}
115