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 
  26 package com.sun.xml.internal.ws.util.xml;
  27 
  28 import com.sun.istack.internal.Nullable;
  29 import com.sun.xml.internal.ws.server.ServerRtException;
  30 import java.net.URI;
  31 import java.net.URL;
  32 import java.util.ArrayList;
  33 import java.util.Collections;
  34 import java.util.Enumeration;
  35 import javax.xml.catalog.CatalogFeatures;
  36 import javax.xml.catalog.CatalogFeatures.Feature;
  37 import javax.xml.catalog.CatalogManager;
  38 import javax.xml.ws.WebServiceException;
  39 import org.xml.sax.EntityResolver;
  40 
  41 /**
  42  *
  43  * @author lukas
  44  */
  45 public class XmlCatalogUtil {
  46 
  47     // Cache CatalogFeatures instance for future usages.
  48     // Resolve feature is set to "continue" value for backward compatibility.
  49     private static final CatalogFeatures CATALOG_FEATURES
  50             = CatalogFeatures.builder().with(Feature.RESOLVE, "continue").build();
  51 
  52     /**
  53      * Gets an EntityResolver using XML catalog
  54      *
  55      * @param catalogUrl
  56      * @return
  57      */
  58     public static EntityResolver createEntityResolver(@Nullable URL catalogUrl) {
  59         ArrayList<URL> urlsArray = new ArrayList<>();
  60         EntityResolver er;
  61         if (catalogUrl != null) {
  62             urlsArray.add(catalogUrl);
  63         }
  64         try {
  65             er = createCatalogResolver(urlsArray);
  66         } catch (Exception e) {
  67             throw new ServerRtException("server.rt.err", e);
  68         }
  69         return er;
  70     }
  71 
  72     /**
  73      * Gets a default EntityResolver for catalog at META-INF/jaxws-catalog.xml
  74      *
  75      * @return
  76      */
  77     public static EntityResolver createDefaultCatalogResolver() {
  78         EntityResolver er;
  79         try {
  80             /**
  81              * Gets a URLs for catalog defined at META-INF/jaxws-catalog.xml
  82              */
  83             ClassLoader cl = Thread.currentThread().getContextClassLoader();
  84             Enumeration<URL> catalogEnum;
  85             if (cl == null) {
  86                 catalogEnum = ClassLoader.getSystemResources("META-INF/jax-ws-catalog.xml");
  87             } else {
  88                 catalogEnum = cl.getResources("META-INF/jax-ws-catalog.xml");
  89             }
  90             er = createCatalogResolver(Collections.list(catalogEnum));
  91         } catch (Exception e) {
  92             throw new WebServiceException(e);
  93         }
  94 
  95         return er;
  96     }
  97 
  98     /**
  99      * Instantiate catalog resolver using new catalog API (javax.xml.catalog.*)
 100      * added in JDK9. Usage of new API removes dependency on internal API
 101      * (com.sun.org.apache.xml.internal) for modular runtime.
 102      */
 103     private static EntityResolver createCatalogResolver(ArrayList<URL> urls) throws Exception {
 104         // Prepare array of catalog URIs
 105         URI[] uris = urls.stream()
 106                              .map(u -> URI.create(u.toExternalForm()))
 107                              .toArray(URI[]::new);
 108 
 109         //Create CatalogResolver with new JDK9+ API
 110         return (EntityResolver) CatalogManager.catalogResolver(CATALOG_FEATURES, uris);
 111     }
 112 
 113 }