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