1 /*
   2  * Copyright (c) 2015, 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 package javax.xml.catalog;
  26 
  27 import java.io.File;
  28 import java.net.MalformedURLException;
  29 import java.net.URI;
  30 import java.net.URISyntaxException;
  31 import java.net.URL;
  32 import java.util.Objects;
  33 import jdk.xml.internal.SecuritySupport;
  34 
  35 /**
  36  * Represents a general Catalog entry.
  37  *
  38  * @since 9
  39  */
  40 abstract class BaseEntry {
  41     final String SLASH = "/";
  42 
  43     CatalogEntryType type;
  44 
  45     //The id attribute
  46     String id;
  47 
  48     //The attribute to be matched, e.g. systemId
  49     String matchId;
  50 
  51     //The baseURI attribute
  52     URL baseURI;
  53 
  54     //Indicates whether the base attribute is specified
  55     boolean baseSpecified = false;
  56 
  57     /**
  58      * CatalogEntryType represents catalog entry types.
  59      */
  60     static enum CatalogEntryType {
  61 
  62         CATALOG("catalogfile"),
  63         CATALOGENTRY("catalog"),
  64         GROUP("group"),
  65         PUBLIC("public"),
  66         SYSTEM("system"),
  67         REWRITESYSTEM("rewriteSystem"),
  68         SYSTEMSUFFIX("systemSuffix"),
  69         DELEGATEPUBLIC("delegatePublic"),
  70         DELEGATESYSTEM("delegateSystem"),
  71         URI("uri"),
  72         REWRITEURI("rewriteURI"),
  73         URISUFFIX("uriSuffix"),
  74         DELEGATEURI("delegateURI"),
  75         NEXTCATALOG("nextCatalog");
  76 
  77         final String literal;
  78 
  79         CatalogEntryType(String literal) {
  80             this.literal = literal;
  81         }
  82 
  83         public boolean isType(String type) {
  84             return literal.equals(type);
  85         }
  86 
  87         static public CatalogEntryType getType(String entryType) {
  88             for (CatalogEntryType type : CatalogEntryType.values()) {
  89                 if (type.isType(entryType)) {
  90                     return type;
  91                 }
  92             }
  93             return null;
  94         }
  95     }
  96 
  97     /**
  98      * Constructs a CatalogEntry
  99      *
 100      * @param type The type of the entry
 101      */
 102     public BaseEntry(CatalogEntryType type) {
 103         this.type = Objects.requireNonNull(type);
 104     }
 105 
 106     /**
 107      * Constructs a CatalogEntry
 108      *
 109      * @param type The type of the entry
 110      * @param base The base URI
 111      */
 112     public BaseEntry(CatalogEntryType type, String base) {
 113         this.type = Objects.requireNonNull(type);
 114         setBaseURI(base);
 115     }
 116 
 117     /**
 118      * Returns the type of the entry
 119      *
 120      * @return The type of the entry
 121      */
 122     public CatalogEntryType getType() {
 123         return type;
 124     }
 125 
 126     /**
 127      * Sets the entry type
 128      *
 129      * @param type The entry type
 130      */
 131     public void setType(CatalogEntryType type) {
 132         this.type = type;
 133     }
 134 
 135     /**
 136      * Returns the id of the entry
 137      *
 138      * @return The id of the entry
 139      */
 140     public String getId() {
 141         return id;
 142     }
 143 
 144     /**
 145      * Set the entry Id
 146      *
 147      * @param id The Id attribute
 148      */
 149     public void setId(String id) {
 150         this.id = id;
 151     }
 152 
 153     /**
 154      * Sets the base URI for the entry
 155      *
 156      * @param base The base URI
 157      */
 158     public final void setBaseURI(String base) {
 159         baseURI = verifyURI("base", null, base);
 160     }
 161 
 162     /**
 163      * Gets the base URI for the entry
 164      *
 165      * @return The base URI as a string.
 166      */
 167     public URL getBaseURI() {
 168         return baseURI;
 169     }
 170 
 171     /**
 172      * Gets the attribute used for matching
 173      *
 174      * @return The value of the field
 175      */
 176     public String getMatchId() {
 177         return matchId;
 178     }
 179 
 180     /**
 181      * Sets the matchId field
 182      * @param matchId The value of the Id
 183      */
 184     public void setMatchId(String matchId) {
 185         this.matchId = matchId;
 186     }
 187 
 188     /**
 189      * Matches the specified string with the identifier attribute of the entry.
 190      *
 191      * @param match The identifier attribute to be matched
 192      * @return The replacement URI if a matching entry is found, null if not.
 193      */
 194     public String match(String match) {
 195         return null;
 196     }
 197 
 198     /**
 199      * Try to match the specified id with the entry. Return the match if it
 200      * is successful and the length of the start String is longer than the
 201      * longest of any previous match.
 202      *
 203      * @param id The id to be matched.
 204      * @param currentMatch The length of start String of previous match if any.
 205      * @return The replacement URI if the match is successful, null if not.
 206      */
 207     public String match(String id, int currentMatch) {
 208         return null;
 209     }
 210 
 211     /**
 212      * Verifies the specified URI.
 213      *
 214      * @param arg The name of the argument
 215      * @param uri The URI to be verified
 216      * @return The URI created from the specified uri
 217      * @throws IllegalArgumentException if the specified uri is null,
 218      * or an URL can not be created based on the specified base and uri
 219      */
 220     URL verifyURI(String arg, URL base, String uri) {
 221         if (uri == null) {
 222             CatalogMessages.reportIAE(new Object[]{uri, arg}, null);
 223         }
 224 
 225         URL url = null;
 226         uri = Normalizer.normalizeURI(uri);
 227 
 228         try {
 229             if (base != null) {
 230                 url = new URL(base, uri);
 231             } else {
 232                 url = new URL(uri);
 233             }
 234         } catch (MalformedURLException e) {
 235             CatalogMessages.reportIAE(new Object[]{uri, arg}, e);
 236         }
 237         return url;
 238     }
 239 
 240     /**
 241      * Replace backslashes with forward slashes. (URLs always use forward
 242      * slashes.)
 243      *
 244      * @param sysid The input system identifier.
 245      * @return The same system identifier with backslashes turned into forward
 246      * slashes.
 247      */
 248     protected String fixSlashes(String sysid) {
 249         return sysid.replace('\\', '/');
 250     }
 251 
 252     /**
 253      * Construct an absolute URI from a relative one, using the current base
 254      * URI.
 255      *
 256      * @param sysid The (possibly relative) system identifier
 257      * @return The system identifier made absolute with respect to the current
 258      * {@link #base}.
 259      */
 260     protected String makeAbsolute(String sysid) {
 261         URL local = null;
 262 
 263         sysid = fixSlashes(sysid);
 264         /**
 265          * try { local = new URL(base, sysid); } catch (MalformedURLException e)
 266          * { catalogManager.debug.message(1, "Malformed URL on system
 267          * identifier", sysid); }
 268          */
 269         if (local != null) {
 270             return local.toString();
 271         } else {
 272             return sysid;
 273         }
 274     }
 275 }