1 /*
   2  * Licensed to the Apache Software Foundation (ASF) under one or more
   3  * contributor license agreements.  See the NOTICE file distributed with
   4  * this work for additional information regarding copyright ownership.
   5  * The ASF licenses this file to You under the Apache License, Version 2.0
   6  * (the "License"); you may not use this file except in compliance with
   7  * the License.  You may obtain a copy of the License at
   8  *
   9  *      http://www.apache.org/licenses/LICENSE-2.0
  10  *
  11  * Unless required by applicable law or agreed to in writing, software
  12  * distributed under the License is distributed on an "AS IS" BASIS,
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14  * See the License for the specific language governing permissions and
  15  * limitations under the License.
  16  */
  17 
  18 package com.sun.org.apache.xml.internal.resolver;
  19 
  20 import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
  21 import com.sun.org.apache.xml.internal.resolver.helpers.BootstrapResolver;
  22 import com.sun.org.apache.xml.internal.resolver.helpers.Debug;
  23 import java.io.InputStream;
  24 import java.net.MalformedURLException;
  25 import java.net.URL;
  26 import java.util.MissingResourceException;
  27 import java.util.PropertyResourceBundle;
  28 import java.util.ResourceBundle;
  29 import java.util.StringTokenizer;
  30 import java.util.Vector;
  31 import sun.reflect.misc.ReflectUtil;
  32 
  33 /**
  34  * CatalogManager provides an interface to the catalog properties.
  35  *
  36  * <p>Properties can come from two places: from system properties or
  37  * from a <i>CatalogManager.properties</i> file. This class provides a transparent
  38  * interface to both, with system properties preferred over property file values.</p>
  39  *
  40  * <p>The following table summarizes the properties:</p>
  41  *
  42  * <table border="1">
  43  * <thead>
  44  * <tr>
  45  * <td>System Property</td>
  46  * <td>CatalogManager.properties<br/>Property</td>
  47  * <td>Description</td>
  48  * </tr>
  49  * </thead>
  50  * <tbody>
  51  * <tr>
  52  * <td>xml.catalog.ignoreMissing</td>
  53  * <td> </td>
  54  * <td>If true, a missing <i>CatalogManager.properties</i> file or missing properties
  55  * within that file will not generate warning messages. See also the
  56  * <i>ignoreMissingProperties</i> method.</td>
  57  * </tr>
  58  *
  59  * <tr>
  60  * <td>xml.catalog.files</td>
  61  * <td>catalogs</td>
  62  * <td>The <emph>semicolon-delimited</emph> list of catalog files.</td>
  63  * </tr>
  64  *
  65  * <tr>
  66  * <td> </td>
  67  * <td>relative-catalogs</td>
  68  * <td>If false, relative catalog URIs are made absolute with respect to the base URI of
  69  * the <i>CatalogManager.properties</i> file. This setting only applies to catalog
  70  * URIs obtained from the <i>catalogs</i> property <emph>in the</emph>
  71  * <i>CatalogManager.properties</i> file</td>
  72  * </tr>
  73  *
  74  * <tr>
  75  * <td>xml.catalog.verbosity</td>
  76  * <td>verbosity</td>
  77  * <td>If non-zero, the Catalog classes will print informative and debugging messages.
  78  * The higher the number, the more messages.</td>
  79  * </tr>
  80  *
  81  * <tr>
  82  * <td>xml.catalog.prefer</td>
  83  * <td>prefer</td>
  84  * <td>Which identifier is preferred, "public" or "system"?</td>
  85  * </tr>
  86  *
  87  * <tr>
  88  * <td>xml.catalog.staticCatalog</td>
  89  * <td>static-catalog</td>
  90  * <td>Should a single catalog be constructed for all parsing, or should a different
  91  * catalog be created for each parser?</td>
  92  * </tr>
  93  *
  94  * <tr>
  95  * <td>xml.catalog.allowPI</td>
  96  * <td>allow-oasis-xml-catalog-pi</td>
  97  * <td>If the source document contains "oasis-xml-catalog" processing instructions,
  98  * should they be used?</td>
  99  * </tr>
 100  *
 101  * <tr>
 102  * <td>xml.catalog.className</td>
 103  * <td>catalog-class-name</td>
 104  * <td>If you're using the convenience classes
 105  * <tt>com.sun.org.apache.xml.internal.resolver.tools.*</tt>), this setting
 106  * allows you to specify an alternate class name to use for the underlying
 107  * catalog.</td>
 108  * </tr>
 109  * </tbody>
 110  * </table>
 111  *
 112  * @see Catalog
 113  *
 114  * @author Norman Walsh
 115  * <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
 116  *
 117  * @version 1.0
 118  */
 119 
 120 public class CatalogManager {
 121     private static final String pFiles         = "xml.catalog.files";
 122     private static final String pVerbosity     = "xml.catalog.verbosity";
 123     private static final String pPrefer        = "xml.catalog.prefer";
 124     private static final String pStatic        = "xml.catalog.staticCatalog";
 125     private static final String pAllowPI       = "xml.catalog.allowPI";
 126     private static final String pClassname     = "xml.catalog.className";
 127     private static final String pIgnoreMissing = "xml.catalog.ignoreMissing";
 128 
 129     /** A static CatalogManager instance for sharing */
 130     private static final CatalogManager staticManager = new CatalogManager();
 131 
 132     /** The bootstrap resolver to use when loading XML Catalogs. */
 133     private BootstrapResolver bResolver = new BootstrapResolver();
 134 
 135     /** Flag to ignore missing property files and/or properties */
 136     private boolean ignoreMissingProperties
 137     = (SecuritySupport.getSystemProperty(pIgnoreMissing) != null
 138     || SecuritySupport.getSystemProperty(pFiles) != null);
 139 
 140     /** Holds the resources after they are loaded from the file. */
 141     private ResourceBundle resources;
 142 
 143     /** The name of the CatalogManager properties file. */
 144     private String propertyFile = "CatalogManager.properties";
 145 
 146     /** The location of the propertyFile */
 147     private URL propertyFileURI = null;
 148 
 149     /** Default catalog files list. */
 150     private String defaultCatalogFiles = "./xcatalog";
 151 
 152     /** Current catalog files list. */
 153     private String catalogFiles = null;
 154 
 155     /** Did the catalogFiles come from the properties file? */
 156     private boolean fromPropertiesFile = false;
 157 
 158     /** Default verbosity level if there is no property setting for it. */
 159     private int defaultVerbosity = 1;
 160 
 161     /** Current verbosity level. */
 162     private Integer verbosity = null;
 163 
 164     /** Default preference setting. */
 165     private boolean defaultPreferPublic = true;
 166 
 167     /** Current preference setting. */
 168     private Boolean preferPublic = null;
 169 
 170     /** Default setting of the static catalog flag. */
 171     private boolean defaultUseStaticCatalog = true;
 172 
 173     /** Current setting of the static catalog flag. */
 174     private Boolean useStaticCatalog = null;
 175 
 176     /** The static catalog used by this manager. */
 177     private static volatile Catalog staticCatalog = null;
 178 
 179     /** Default setting of the oasisXMLCatalogPI flag. */
 180     private boolean defaultOasisXMLCatalogPI = true;
 181 
 182     /** Current setting of the oasisXMLCatalogPI flag. */
 183     private Boolean oasisXMLCatalogPI = null;
 184 
 185     /** Default setting of the relativeCatalogs flag. */
 186     private boolean defaultRelativeCatalogs = true;
 187 
 188     /** Current setting of the relativeCatalogs flag. */
 189     private Boolean relativeCatalogs = null;
 190 
 191     /** Current catalog class name. */
 192     private String catalogClassName = null;
 193     /**
 194      * Indicates whether implementation parts should use
 195      *   service loader (or similar).
 196      * Note the default value (false) is the safe option..
 197      */
 198     private boolean useServicesMechanism;
 199 
 200     /** The manager's debug object. Used for printing debugging messages.
 201      *
 202      * <p>This field is public so that objects that have access to this
 203      * CatalogManager can use this debug object.</p>
 204      */
 205     public Debug debug = null;
 206 
 207     /** Constructor. */
 208     public CatalogManager() {
 209         init();
 210     }
 211 
 212     /** Constructor that specifies an explicit property file. */
 213     public CatalogManager(String propertyFile) {
 214         this.propertyFile = propertyFile;
 215         init();
 216   }
 217 
 218   private void init() {
 219         debug = new Debug();
 220     // Note that we don't setDebug() here; we do that lazily. Either the
 221     // user will set it explicitly, or we'll do it automagically if they
 222     // read from the propertyFile for some other reason. That way, there's
 223     // no attempt to read from the file before the caller has had a chance
 224     // to avoid it.
 225     if (System.getSecurityManager() == null) {
 226         useServicesMechanism = true;
 227     }
 228         // Make sure verbosity is set by xml.catalog.verbosity sysprop
 229         // setting, if defined.
 230         queryVerbosityFromSysProp();
 231     }
 232 
 233     /** Set the bootstrap resolver
 234      * @param resolver the bootstrap resolver
 235      */
 236     public void setBootstrapResolver(BootstrapResolver resolver) {
 237         bResolver = resolver;
 238     }
 239 
 240     /** Get the bootstrap resolver
 241      * @return the bootstrap resolver
 242      */
 243     public BootstrapResolver getBootstrapResolver() {
 244         return bResolver;
 245     }
 246 
 247     /** Query system property for verbosity level. */
 248     private void queryVerbosityFromSysProp() {
 249         String verbStr = SecuritySupport.getSystemProperty(pVerbosity);
 250         if (verbStr != null) {
 251             try {
 252                 int verb = Integer.parseInt(verbStr.trim());
 253                 verbosity = new Integer(verb);
 254                 debug.setDebug(verb);
 255             } catch (Exception e) {
 256                 System.err.println("Cannot parse verbosity: \"" + verbStr + "\"");
 257             }
 258         }
 259     }
 260 
 261     /**
 262      * Load the properties from the propertyFile and build the
 263      * resources from it.
 264      */
 265     private synchronized void readProperties() {
 266         try {
 267             propertyFileURI = CatalogManager.class.getResource("/"+propertyFile);
 268             InputStream in =
 269                     CatalogManager.class.getResourceAsStream("/"+propertyFile);
 270             if (in==null) {
 271                 if (!ignoreMissingProperties) {
 272                     System.err.println("Cannot find "+propertyFile);
 273                     // there's no reason to give this warning more than once
 274                     ignoreMissingProperties = true;
 275                 }
 276                 return;
 277             }
 278             resources = new PropertyResourceBundle(in);
 279         } catch (MissingResourceException mre) {
 280             if (!ignoreMissingProperties) {
 281                 System.err.println("Cannot read "+propertyFile);
 282             }
 283         } catch (java.io.IOException e) {
 284             if (!ignoreMissingProperties) {
 285                 System.err.println("Failure trying to read "+propertyFile);
 286             }
 287         }
 288 
 289         // This is a bit of a hack. After we've successfully read the properties,
 290         // use them to set the default debug level, if the user hasn't already set
 291         // the default debug level.
 292         if (verbosity == null) {
 293             try {
 294                 String verbStr = resources.getString("verbosity");
 295                 int verb = Integer.parseInt(verbStr.trim());
 296                 debug.setDebug(verb);
 297                 verbosity = new Integer(verb);
 298             } catch (Exception e) {
 299                 // nop
 300             }
 301         }
 302     }
 303 
 304     /**
 305      * Allow access to the static CatalogManager
 306      */
 307     public static CatalogManager getStaticManager() {
 308         return staticManager;
 309     }
 310 
 311     /**
 312      * How are missing properties handled?
 313      *
 314      * <p>If true, missing or unreadable property files will
 315      * not be reported. Otherwise, a message will be sent to System.err.
 316      * </p>
 317      */
 318     public boolean getIgnoreMissingProperties() {
 319         return ignoreMissingProperties;
 320     }
 321 
 322     /**
 323      * How should missing properties be handled?
 324      *
 325      * <p>If ignore is true, missing or unreadable property files will
 326      * not be reported. Otherwise, a message will be sent to System.err.
 327      * </p>
 328      */
 329     public void setIgnoreMissingProperties(boolean ignore) {
 330         ignoreMissingProperties = ignore;
 331     }
 332 
 333     /**
 334      * How are missing properties handled?
 335      *
 336      * <p>If ignore is true, missing or unreadable property files will
 337      * not be reported. Otherwise, a message will be sent to System.err.
 338      * </p>
 339      *
 340      * @deprecated No longer static; use get/set methods.
 341      */
 342     public void ignoreMissingProperties(boolean ignore) {
 343         setIgnoreMissingProperties(ignore);
 344     }
 345 
 346     /**
 347      * Obtain the verbosity setting from the properties.
 348      *
 349      * @return The verbosity level from the propertyFile or the
 350      * defaultVerbosity.
 351      */
 352     private int queryVerbosity () {
 353         String defaultVerbStr = Integer.toString(defaultVerbosity);
 354 
 355         String verbStr = SecuritySupport.getSystemProperty(pVerbosity);
 356 
 357         if (verbStr == null) {
 358             if (resources==null) readProperties();
 359             if (resources != null) {
 360                 try {
 361                     verbStr = resources.getString("verbosity");
 362                 } catch (MissingResourceException e) {
 363                     verbStr = defaultVerbStr;
 364                 }
 365             } else {
 366                 verbStr = defaultVerbStr;
 367             }
 368         }
 369 
 370         int verb = defaultVerbosity;
 371 
 372         try {
 373             verb = Integer.parseInt(verbStr.trim());
 374         } catch (Exception e) {
 375             System.err.println("Cannot parse verbosity: \"" + verbStr + "\"");
 376         }
 377 
 378         // This is a bit of a hack. After we've successfully got the verbosity,
 379         // we have to use it to set the default debug level,
 380         // if the user hasn't already set the default debug level.
 381         if (verbosity == null) {
 382             debug.setDebug(verb);
 383             verbosity = new Integer(verb);
 384         }
 385 
 386         return verb;
 387     }
 388 
 389     /**
 390      * What is the current verbosity?
 391      */
 392     public int getVerbosity() {
 393         if (verbosity == null) {
 394             verbosity = new Integer(queryVerbosity());
 395         }
 396 
 397         return verbosity.intValue();
 398     }
 399 
 400     /**
 401      * Set the current verbosity.
 402      */
 403     public void setVerbosity (int verbosity) {
 404         this.verbosity = new Integer(verbosity);
 405         debug.setDebug(verbosity);
 406     }
 407 
 408     /**
 409      * What is the current verbosity?
 410      *
 411      * @deprecated No longer static; use get/set methods.
 412      */
 413     public int verbosity () {
 414         return getVerbosity();
 415     }
 416 
 417     /**
 418      * Obtain the relativeCatalogs setting from the properties.
 419      *
 420      * @return The relativeCatalogs setting from the propertyFile or the
 421      * defaultRelativeCatalogs.
 422      */
 423     private boolean queryRelativeCatalogs () {
 424         if (resources==null) readProperties();
 425 
 426         if (resources==null) return defaultRelativeCatalogs;
 427 
 428         try {
 429             String allow = resources.getString("relative-catalogs");
 430             return (allow.equalsIgnoreCase("true")
 431                     || allow.equalsIgnoreCase("yes")
 432                     || allow.equalsIgnoreCase("1"));
 433         } catch (MissingResourceException e) {
 434             return defaultRelativeCatalogs;
 435         }
 436     }
 437 
 438     /**
 439      * Get the relativeCatalogs setting.
 440      *
 441      * <p>This property is used when the catalogFiles property is
 442      * interrogated. If true, then relative catalog entry file names
 443      * are returned. If false, relative catalog entry file names are
 444      * made absolute with respect to the properties file before returning
 445      * them.</p>
 446      *
 447      * <p>This property <emph>only applies</emph> when the catalog files
 448      * come from a properties file. If they come from a system property or
 449      * the default list, they are never considered relative. (What would
 450      * they be relative to?)</p>
 451      *
 452      * <p>In the properties, a value of 'yes', 'true', or '1' is considered
 453      * true, anything else is false.</p>
 454      *
 455      * @return The relativeCatalogs setting from the propertyFile or the
 456      * defaultRelativeCatalogs.
 457      */
 458     public boolean getRelativeCatalogs () {
 459         if (relativeCatalogs == null) {
 460             relativeCatalogs = queryRelativeCatalogs() ? Boolean.TRUE : Boolean.FALSE;
 461         }
 462 
 463         return relativeCatalogs.booleanValue();
 464     }
 465 
 466     /**
 467      * Set the relativeCatalogs setting.
 468      *
 469      * @see #getRelativeCatalogs()
 470      */
 471     public void setRelativeCatalogs (boolean relative) {
 472         relativeCatalogs = relative ? Boolean.TRUE : Boolean.FALSE;
 473     }
 474 
 475     /**
 476      * Get the relativeCatalogs setting.
 477      *
 478      * @deprecated No longer static; use get/set methods.
 479      */
 480     public boolean relativeCatalogs () {
 481         return getRelativeCatalogs();
 482     }
 483 
 484     /**
 485      * Obtain the list of catalog files from the properties.
 486      *
 487      * @return A semicolon delimited list of catlog file URIs
 488      */
 489     private String queryCatalogFiles () {
 490         String catalogList = SecuritySupport.getSystemProperty(pFiles);
 491         fromPropertiesFile = false;
 492 
 493         if (catalogList == null) {
 494             if (resources == null) readProperties();
 495             if (resources != null) {
 496                 try {
 497                     catalogList = resources.getString("catalogs");
 498                     fromPropertiesFile = true;
 499                 } catch (MissingResourceException e) {
 500                     System.err.println(propertyFile + ": catalogs not found.");
 501                     catalogList = null;
 502                 }
 503             }
 504         }
 505 
 506         if (catalogList == null) {
 507             catalogList = defaultCatalogFiles;
 508         }
 509 
 510         return catalogList;
 511     }
 512 
 513     /**
 514      * Return the current list of catalog files.
 515      *
 516      * @return A vector of the catalog file names or null if no catalogs
 517      * are available in the properties.
 518      */
 519     public Vector getCatalogFiles() {
 520         if (catalogFiles == null) {
 521             catalogFiles = queryCatalogFiles();
 522         }
 523 
 524         StringTokenizer files = new StringTokenizer(catalogFiles, ";");
 525         Vector catalogs = new Vector();
 526         while (files.hasMoreTokens()) {
 527             String catalogFile = files.nextToken();
 528             URL absURI = null;
 529 
 530             if (fromPropertiesFile && !relativeCatalogs()) {
 531                 try {
 532                     absURI = new URL(propertyFileURI, catalogFile);
 533                     catalogFile = absURI.toString();
 534                 } catch (MalformedURLException mue) {
 535                     absURI = null;
 536                 }
 537             }
 538 
 539             catalogs.add(catalogFile);
 540         }
 541 
 542         return catalogs;
 543     }
 544 
 545     /**
 546      * Set the list of catalog files.
 547      */
 548     public void setCatalogFiles(String fileList) {
 549         catalogFiles = fileList;
 550         fromPropertiesFile = false;
 551     }
 552 
 553     /**
 554      * Return the current list of catalog files.
 555      *
 556      * @return A vector of the catalog file names or null if no catalogs
 557      * are available in the properties.
 558      *
 559      * @deprecated No longer static; use get/set methods.
 560      */
 561     public Vector catalogFiles() {
 562         return getCatalogFiles();
 563     }
 564 
 565     /**
 566      * Obtain the preferPublic setting from the properties.
 567      *
 568      * <p>In the properties, a value of 'public' is true,
 569      * anything else is false.</p>
 570      *
 571      * @return True if prefer is public or the
 572      * defaultPreferSetting.
 573      */
 574     private boolean queryPreferPublic () {
 575         String prefer = SecuritySupport.getSystemProperty(pPrefer);
 576 
 577         if (prefer == null) {
 578             if (resources==null) readProperties();
 579             if (resources==null) return defaultPreferPublic;
 580             try {
 581                 prefer = resources.getString("prefer");
 582             } catch (MissingResourceException e) {
 583                 return defaultPreferPublic;
 584             }
 585         }
 586 
 587         if (prefer == null) {
 588             return defaultPreferPublic;
 589         }
 590 
 591         return (prefer.equalsIgnoreCase("public"));
 592     }
 593 
 594     /**
 595      * Return the current prefer public setting.
 596      *
 597      * @return True if public identifiers are preferred.
 598      */
 599     public boolean getPreferPublic () {
 600         if (preferPublic == null) {
 601             preferPublic = queryPreferPublic() ? Boolean.TRUE : Boolean.FALSE;
 602         }
 603         return preferPublic.booleanValue();
 604     }
 605 
 606     /**
 607      * Set the prefer public setting.
 608      */
 609     public void setPreferPublic (boolean preferPublic) {
 610         this.preferPublic = preferPublic ? Boolean.TRUE : Boolean.FALSE;
 611     }
 612 
 613     /**
 614      * Return the current prefer public setting.
 615      *
 616      * @return True if public identifiers are preferred.
 617      *
 618      * @deprecated No longer static; use get/set methods.
 619      */
 620     public boolean preferPublic () {
 621         return getPreferPublic();
 622     }
 623 
 624     /**
 625      * Obtain the static-catalog setting from the properties.
 626      *
 627      * <p>In the properties, a value of 'yes', 'true', or '1' is considered
 628      * true, anything else is false.</p>
 629      *
 630      * @return The static-catalog setting from the propertyFile or the
 631      * defaultUseStaticCatalog.
 632      */
 633     private boolean queryUseStaticCatalog () {
 634         String staticCatalog = SecuritySupport.getSystemProperty(pStatic);
 635 
 636         if (staticCatalog == null) {
 637             if (resources==null) readProperties();
 638             if (resources==null) return defaultUseStaticCatalog;
 639             try {
 640                 staticCatalog = resources.getString("static-catalog");
 641             } catch (MissingResourceException e) {
 642                 return defaultUseStaticCatalog;
 643             }
 644         }
 645 
 646         if (staticCatalog == null) {
 647             return defaultUseStaticCatalog;
 648         }
 649 
 650         return (staticCatalog.equalsIgnoreCase("true")
 651                 || staticCatalog.equalsIgnoreCase("yes")
 652                 || staticCatalog.equalsIgnoreCase("1"));
 653     }
 654 
 655     /**
 656      * Get the current use static catalog setting.
 657      */
 658     public boolean getUseStaticCatalog() {
 659         if (useStaticCatalog == null) {
 660             useStaticCatalog = queryUseStaticCatalog() ? Boolean.TRUE : Boolean.FALSE;
 661         }
 662 
 663         return useStaticCatalog.booleanValue();
 664     }
 665 
 666     /**
 667      * Set the use static catalog setting.
 668      */
 669     public void setUseStaticCatalog(boolean useStatic) {
 670         useStaticCatalog = useStatic ? Boolean.TRUE : Boolean.FALSE;
 671     }
 672 
 673     /**
 674      * Get the current use static catalog setting.
 675      *
 676      * @deprecated No longer static; use get/set methods.
 677      */
 678     public boolean staticCatalog() {
 679         return getUseStaticCatalog();
 680     }
 681 
 682     /**
 683      * Get a new catalog instance.
 684      *
 685      * This method always returns a new instance of the underlying catalog class.
 686      */
 687     public Catalog getPrivateCatalog() {
 688         Catalog catalog = staticCatalog;
 689 
 690         if (useStaticCatalog == null) {
 691             useStaticCatalog = getUseStaticCatalog() ? Boolean.TRUE : Boolean.FALSE;
 692         }
 693 
 694         if (catalog == null || !useStaticCatalog.booleanValue()) {
 695 
 696             try {
 697                 String catalogClassName = getCatalogClassName();
 698 
 699                 if (catalogClassName == null) {
 700                     catalog = new Catalog();
 701                 } else {
 702                     try {
 703                         catalog = (Catalog) ReflectUtil.forName(catalogClassName).newInstance();
 704                     } catch (ClassNotFoundException cnfe) {
 705                         debug.message(1,"Catalog class named '"
 706                                 + catalogClassName
 707                                 + "' could not be found. Using default.");
 708                         catalog = new Catalog();
 709                     } catch (ClassCastException cnfe) {
 710                         debug.message(1,"Class named '"
 711                                 + catalogClassName
 712                                 + "' is not a Catalog. Using default.");
 713                         catalog = new Catalog();
 714                     }
 715                 }
 716 
 717                 catalog.setCatalogManager(this);
 718                 catalog.setupReaders();
 719                 catalog.loadSystemCatalogs();
 720             } catch (Exception ex) {
 721                 ex.printStackTrace();
 722             }
 723 
 724             if (useStaticCatalog.booleanValue()) {
 725                 staticCatalog = catalog;
 726             }
 727         }
 728 
 729         return catalog;
 730     }
 731 
 732     /**
 733      * Get a catalog instance.
 734      *
 735      * If this manager uses static catalogs, the same static catalog will
 736      * always be returned. Otherwise a new catalog will be returned.
 737      */
 738     public Catalog getCatalog() {
 739         Catalog catalog = staticCatalog;
 740 
 741         if (useStaticCatalog == null) {
 742             useStaticCatalog = getUseStaticCatalog() ? Boolean.TRUE : Boolean.FALSE;
 743         }
 744 
 745         if (catalog == null || !useStaticCatalog.booleanValue()) {
 746             catalog = getPrivateCatalog();
 747             if (useStaticCatalog.booleanValue()) {
 748                 staticCatalog = catalog;
 749             }
 750         }
 751 
 752         return catalog;
 753     }
 754 
 755     /**
 756      * <p>Obtain the oasisXMLCatalogPI setting from the properties.</p>
 757      *
 758      * <p>In the properties, a value of 'yes', 'true', or '1' is considered
 759      * true, anything else is false.</p>
 760      *
 761      * @return The oasisXMLCatalogPI setting from the propertyFile or the
 762      * defaultOasisXMLCatalogPI.
 763      */
 764     public boolean queryAllowOasisXMLCatalogPI () {
 765         String allow = SecuritySupport.getSystemProperty(pAllowPI);
 766 
 767         if (allow == null) {
 768             if (resources==null) readProperties();
 769             if (resources==null) return defaultOasisXMLCatalogPI;
 770             try {
 771                 allow = resources.getString("allow-oasis-xml-catalog-pi");
 772             } catch (MissingResourceException e) {
 773                 return defaultOasisXMLCatalogPI;
 774             }
 775         }
 776 
 777         if (allow == null) {
 778             return defaultOasisXMLCatalogPI;
 779         }
 780 
 781         return (allow.equalsIgnoreCase("true")
 782                 || allow.equalsIgnoreCase("yes")
 783                 || allow.equalsIgnoreCase("1"));
 784     }
 785 
 786     /**
 787      * Get the current XML Catalog PI setting.
 788      */
 789     public boolean getAllowOasisXMLCatalogPI () {
 790         if (oasisXMLCatalogPI == null) {
 791             oasisXMLCatalogPI = queryAllowOasisXMLCatalogPI() ? Boolean.TRUE : Boolean.FALSE;
 792         }
 793 
 794         return oasisXMLCatalogPI.booleanValue();
 795     }
 796 
 797     public boolean useServicesMechanism() {
 798         return useServicesMechanism;
 799     }
 800     /**
 801      * Set the XML Catalog PI setting
 802      */
 803     public void setAllowOasisXMLCatalogPI(boolean allowPI) {
 804         oasisXMLCatalogPI = allowPI ? Boolean.TRUE : Boolean.FALSE;
 805     }
 806 
 807     /**
 808      * Get the current XML Catalog PI setting.
 809      *
 810      * @deprecated No longer static; use get/set methods.
 811      */
 812     public boolean allowOasisXMLCatalogPI() {
 813         return getAllowOasisXMLCatalogPI();
 814     }
 815 
 816     /**
 817      * Obtain the Catalog class name setting from the properties.
 818      *
 819      */
 820     public String queryCatalogClassName () {
 821         String className = SecuritySupport.getSystemProperty(pClassname);
 822 
 823         if (className == null) {
 824             if (resources==null) readProperties();
 825             if (resources==null) return null;
 826             try {
 827                 return resources.getString("catalog-class-name");
 828             } catch (MissingResourceException e) {
 829                 return null;
 830             }
 831         }
 832 
 833         return className;
 834     }
 835 
 836     /**
 837      * Get the current Catalog class name.
 838      */
 839     public String getCatalogClassName() {
 840         if (catalogClassName == null) {
 841             catalogClassName = queryCatalogClassName();
 842         }
 843 
 844         return catalogClassName;
 845     }
 846 
 847     /**
 848      * Set the Catalog class name.
 849      */
 850     public void setCatalogClassName(String className) {
 851         catalogClassName = className;
 852     }
 853 
 854     /**
 855      * Get the current Catalog class name.
 856      *
 857      * @deprecated No longer static; use get/set methods.
 858      */
 859     public String catalogClassName() {
 860         return getCatalogClassName();
 861     }
 862 }