| /* | |
| * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. Oracle designates this | |
| * particular file as subject to the "Classpath" exception as provided | |
| * by Oracle in the LICENSE file that accompanied this code. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| package jdk.xml.internal; | |
| import static jdk.xml.internal.JdkConstants.FQ_IS_STANDALONE; | |
| import static jdk.xml.internal.JdkConstants.JDK_DEBUG_LIMIT; | |
| import static jdk.xml.internal.JdkConstants.JDK_ENTITY_COUNT_INFO; | |
| import static jdk.xml.internal.JdkConstants.JDK_EXTENSION_CLASSLOADER; | |
| import static jdk.xml.internal.JdkConstants.JDK_EXT_CLASSLOADER; | |
| import static jdk.xml.internal.JdkConstants.JDK_IS_STANDALONE; | |
| import static jdk.xml.internal.JdkConstants.ORACLE_IS_STANDALONE; | |
| import static jdk.xml.internal.JdkConstants.SP_IS_STANDALONE; | |
| import static jdk.xml.internal.JdkConstants.SP_XSLTC_IS_STANDALONE; | |
| import static jdk.xml.internal.JdkConstants.ORACLE_ENABLE_EXTENSION_FUNCTION; | |
| import static jdk.xml.internal.JdkConstants.ORACLE_FEATURE_SERVICE_MECHANISM; | |
| import static jdk.xml.internal.JdkConstants.SP_ENABLE_EXTENSION_FUNCTION; | |
| import static jdk.xml.internal.JdkConstants.SP_ENABLE_EXTENSION_FUNCTION_SPEC; | |
| import static jdk.xml.internal.JdkConstants.CDATA_CHUNK_SIZE; | |
| import static jdk.xml.internal.JdkConstants.OVERRIDE_PARSER; | |
| import static jdk.xml.internal.JdkConstants.RESET_SYMBOL_TABLE; | |
| /** | |
| * Represents a JDK Implementation Specific Property. This class holds the name | |
| * and value of a property along with a state indicating the means through which | |
| * the property has been set. The value may change only if the setter has a state | |
| * that represents an equal or higher overriding order. | |
| * | |
| * @param <T> the type of the property value. | |
| */ | |
| public final class JdkProperty<T> { | |
| private final ImplPropMap pName; | |
| private final Class<T> pType; | |
| private T pValue; | |
| private State pState = State.DEFAULT; | |
| /** | |
| * Constructs a JDkProperty. | |
| * @param name the name of the property | |
| * @param type the type of the value | |
| * @param value the initial value | |
| * @param state the state of the property | |
| */ | |
| public JdkProperty(ImplPropMap name, Class<T> type, T value, State state) { | |
| this.pName = name; | |
| this.pType = type; | |
| this.pValue = value; | |
| this.pState = state; | |
| readSystemProperty(); | |
| } | |
| /** | |
| * Read from system properties, or those in jaxp.properties | |
| */ | |
| private void readSystemProperty() { | |
| if (pState == State.DEFAULT) { | |
| T value = null; | |
| if (pName.systemProperty() != null) { | |
| value = SecuritySupport.getJAXPSystemProperty(pType, pName.systemProperty(), null); | |
| } | |
| if (value == null && pName.systemPropertyOld() != null) { | |
| value = SecuritySupport.getJAXPSystemProperty(pType, pName.systemPropertyOld(), null); | |
| } | |
| if (value != null) { | |
| pValue = value; | |
| pState = State.SYSTEMPROPERTY; | |
| } | |
| } | |
| } | |
| /** | |
| * Returns the property value. | |
| * @return the property value | |
| */ | |
| public T getValue() { | |
| return pValue; | |
| } | |
| /** | |
| * Sets the property value. The value is set only if the setter has a higher | |
| * overriding order. | |
| * @param name the property name | |
| * @param value the value | |
| * @param state the state of the specified property | |
| * @return true if the value is set successfully (because the setter has a | |
| * higher order); false otherwise. | |
| */ | |
| public boolean setValue(String name, T value, State state) { | |
| State pState1; | |
| if ((pState1 = pName.getState(name)) != null) { | |
| if (pState1.compareTo(this.pState) >= 0) { | |
| this.pState = pState1; | |
| pValue = value; | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| /** | |
| * Properties Name Map that includes Implementation-Specific Features and | |
| * Properties except the limits that are defined in XMLSecurityManager. | |
| * The purpose of the map is to provide a map between the new property names | |
| * with a prefix "jdk.xml" as defined in the module summary and legacy names | |
| * with URL style prefixes. The new names are the same as those of their | |
| * System Properties. | |
| */ | |
| @SuppressWarnings("deprecation") | |
| public static enum ImplPropMap { | |
| ISSTANDALONE("isStandalone", FQ_IS_STANDALONE, SP_IS_STANDALONE, true, null, null), | |
| XSLTCISSTANDALONE("xsltcIsStandalone", JDK_IS_STANDALONE, SP_XSLTC_IS_STANDALONE, | |
| true, ORACLE_IS_STANDALONE, null), | |
| CDATACHUNKSIZE("cdataChunkSize", CDATA_CHUNK_SIZE, CDATA_CHUNK_SIZE, false, null, null), | |
| EXTCLSLOADER("extensionClassLoader", JDK_EXT_CLASSLOADER, null, | |
| true, JDK_EXTENSION_CLASSLOADER, null), | |
| ENABLEEXTFUNC("enableExtensionFunctions", ORACLE_ENABLE_EXTENSION_FUNCTION, | |
| SP_ENABLE_EXTENSION_FUNCTION_SPEC, true, null, SP_ENABLE_EXTENSION_FUNCTION), | |
| OVERRIDEPARSER("overrideDefaultParser", OVERRIDE_PARSER, OVERRIDE_PARSER, | |
| false, ORACLE_FEATURE_SERVICE_MECHANISM, ORACLE_FEATURE_SERVICE_MECHANISM), | |
| RESETSYMBOLTABLE("resetSymbolTable", RESET_SYMBOL_TABLE, RESET_SYMBOL_TABLE, | |
| false, null, null), | |
| ENTITYCOUNT("getEntityCountInfo", JDK_DEBUG_LIMIT, null, true, JDK_ENTITY_COUNT_INFO, null) | |
| ; | |
| private final String name; | |
| private final String qName; | |
| private final String spName; | |
| private final boolean differ; | |
| private final String oldQName; | |
| private final String oldSPName; | |
| /** | |
| * Constructs an instance. | |
| * @param name the property name | |
| * @param qName the qualified property name | |
| * @param spName the corresponding System Property | |
| * @param differ a flag indicating whether qName and spName are the same | |
| * @param oldName the legacy property name, null if N/A | |
| * @param oldSPName the legacy System Property name, null if N/A | |
| */ | |
| ImplPropMap(String name, String qName, String spName, boolean differ, | |
| String oldQName, String oldSPName) { | |
| this.name = name; | |
| this.qName = qName; | |
| this.spName = spName; | |
| this.differ = differ; | |
| this.oldQName = oldQName; | |
| this.oldSPName = oldSPName; | |
| } | |
| /** | |
| * Checks whether the specified name is the property. Checks both the | |
| * property and System Property if they differ. Checks also the legacy | |
| * name if applicable. | |
| * | |
| * @param name the specified name | |
| * @return true if there is a match, false otherwise | |
| */ | |
| public boolean is(String name) { | |
| // current spec calls for using a name same as spName | |
| return (spName != null && spName.equals(name)) || | |
| // check qName only if it differs from spName | |
| (differ && qName.equals(name)) || | |
| // check the legacy name if applicable | |
| (oldQName != null && oldQName.equals(name)); | |
| } | |
| /** | |
| * Returns the value indicating whether the qName and spName are different. | |
| * @return the value indicating whether the qName and spName are different | |
| */ | |
| public boolean isNameDiffer() { | |
| return differ; | |
| } | |
| /** | |
| * Returns the state of a property name. By the specification as of JDK 17, | |
| * the "jdk.xml." prefixed System property name is also the current API | |
| * name. Both the URI-based qName and old name if any are legacy. | |
| * | |
| * @param name the property name | |
| * @return the state of the property name, null if no match | |
| */ | |
| public State getState(String name) { | |
| if ((spName != null && spName.equals(name)) || | |
| (spName == null && qName.equals(name))) { | |
| return State.APIPROPERTY; | |
| } else if ((differ && qName.equals(name)) || | |
| (oldQName != null && oldQName.equals(name))) { | |
| //both the URI-style qName and an old name if any are legacy | |
| return State.LEGACY_APIPROPERTY; | |
| } | |
| return null; | |
| } | |
| /** | |
| * Returns the qualified name of the property. | |
| * | |
| * @return the qualified name of the property | |
| */ | |
| public String qName() { | |
| return qName; | |
| } | |
| /** | |
| * Returns the legacy name of the property. | |
| * | |
| * @return the legacy name of the property | |
| */ | |
| public String qNameOld() { | |
| return oldQName; | |
| } | |
| /** | |
| * Returns the name of the corresponding System Property. | |
| * | |
| * @return the name of the System Property | |
| */ | |
| public String systemProperty() { | |
| return spName; | |
| } | |
| /** | |
| * Returns the name of the legacy System Property. | |
| * | |
| * @return the name of the legacy System Property | |
| */ | |
| public String systemPropertyOld() { | |
| return oldSPName; | |
| } | |
| } | |
| /** | |
| * Represents the state of the settings of a property. The states are in | |
| * descending order: the default value, value set by FEATURE_SECURE_PROCESSING (FSP), | |
| * in jaxp.properties, by legacy or new system property, and on factories | |
| * using legacy or new property names. | |
| */ | |
| public static enum State { | |
| //this order reflects the overriding order | |
| DEFAULT("default"), FSP("FEATURE_SECURE_PROCESSING"), JAXPDOTPROPERTIES("jaxp.properties"), | |
| LEGACY_SYSTEMPROPERTY("legacy system property"), SYSTEMPROPERTY("system property"), | |
| LEGACY_APIPROPERTY("legacy property"), APIPROPERTY("property"); | |
| final String literal; | |
| State(String literal) { | |
| this.literal = literal; | |
| } | |
| public String literal() { | |
| return literal; | |
| } | |
| } | |
| } |