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.io.File;
  31 import java.net.URI;
  32 import java.net.URL;
  33 import java.util.ArrayList;
  34 import java.util.Collections;
  35 import java.util.Enumeration;
  36 import javax.xml.catalog.CatalogFeatures;
  37 import javax.xml.catalog.CatalogFeatures.Feature;
  38 import javax.xml.catalog.CatalogManager;
  39 import javax.xml.ws.WebServiceException;
  40 import org.xml.sax.EntityResolver;
  41 
  42 /**
  43  *
  44  * @author lukas
  45  */
  46 public 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 }