1 /*
2  * Copyright (c) 2011, 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.org.apache.xalan.internal.utils;
27 
28 import com.sun.org.apache.xalan.internal.XalanConstants;
29 import jdk.xml.internal.SecuritySupport;
30 
31 /**
32  * This is the base class for features and properties
33  *
34  */
35 public abstract class FeaturePropertyBase {
36 
37     /**
38      * States of the settings of a property, in the order: default value, value
39      * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system
40      * properties, and jaxp api properties
41      */
42     public static enum State {
43         //this order reflects the overriding order
44         DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY
45     }
46 
47 
48     /**
49      * Values of the properties as defined in enum Properties
50      */
51     String[] values = null;
52     /**
53      * States of the settings for each property in Properties above
54      */
55     State[] states = {State.DEFAULT, State.DEFAULT};
56 
57 
58     /**
59      * Set the value for a specific property.
60      *
61      * @param property the property
62      * @param state the state of the property
63      * @param value the value of the property
64      */
setValue(Enum<?> property, State state, String value)65     public void setValue(Enum<?> property, State state, String value) {
66         //only update if it shall override
67         if (state.compareTo(states[property.ordinal()]) >= 0) {
68             values[property.ordinal()] = value;
69             states[property.ordinal()] = state;
70         }
71     }
72 
73     /**
74      * Set the value of a property by its index
75      * @param index the index of the property
76      * @param state the state of the property
77      * @param value the value of the property
78      */
setValue(int index, State state, String value)79     public void setValue(int index, State state, String value) {
80         //only update if it shall override
81         if (state.compareTo(states[index]) >= 0) {
82             values[index] = value;
83             states[index] = state;
84         }
85     }
86 
87      /**
88      * Set value by property name and state
89      * @param propertyName property name
90      * @param state the state of the property
91      * @param value the value of the property
92      * @return true if the property is managed by the security property manager;
93      *         false if otherwise.
94      */
setValue(String propertyName, State state, Object value)95     public boolean setValue(String propertyName, State state, Object value) {
96         int index = getIndex(propertyName);
97         if (index > -1) {
98             setValue(index, state, (String)value);
99             return true;
100         }
101         return false;
102     }
103 
104      /**
105      * Set value by property name and state
106      * @param propertyName property name
107      * @param state the state of the property
108      * @param value the value of the property
109      * @return true if the property is managed by the security property manager;
110      *         false if otherwise.
111      */
setValue(String propertyName, State state, boolean value)112     public boolean setValue(String propertyName, State state, boolean value) {
113         int index = getIndex(propertyName);
114         if (index > -1) {
115             if (value) {
116                 setValue(index, state, XalanConstants.FEATURE_TRUE);
117             } else {
118                 setValue(index, state, XalanConstants.FEATURE_FALSE);
119             }
120             return true;
121         }
122         return false;
123     }
124 
125     /**
126      * Return the value of the specified property
127      *
128      * @param property the property
129      * @return the value of the property
130      */
getValue(Enum<?> property)131     public String getValue(Enum<?> property) {
132         return values[property.ordinal()];
133     }
134 
135     /**
136      * Return the value of the specified property
137      *
138      * @param property the property
139      * @return the value of the property
140      */
getValue(String property)141     public String getValue(String property) {
142         int index = getIndex(property);
143         if (index > -1) {
144             return getValueByIndex(index);
145         }
146         return null;
147     }
148 
149     /**
150      * Return the value of the specified property.
151      *
152      * @param propertyName the property name
153      * @return the value of the property as a string. If a property is managed
154      * by this manager, its value shall not be null.
155      */
getValueAsString(String propertyName)156     public String getValueAsString(String propertyName) {
157         int index = getIndex(propertyName);
158         if (index > -1) {
159             return getValueByIndex(index);
160         }
161 
162         return null;
163     }
164 
165     /**
166      * Return the value of a property by its ordinal
167      * @param index the index of a property
168      * @return value of a property
169      */
getValueByIndex(int index)170     public String getValueByIndex(int index) {
171         return values[index];
172     }
173 
174     /**
175      * Get the index by property name
176      * @param propertyName property name
177      * @return the index of the property if found; return -1 if not
178      */
getIndex(String propertyName)179     public abstract int getIndex(String propertyName);
180 
getIndex(Class<E> property, String propertyName)181     public <E extends Enum<E>> int getIndex(Class<E> property, String propertyName) {
182         for (Enum<E> enumItem : property.getEnumConstants()) {
183             if (enumItem.toString().equals(propertyName)) {
184                 //internally, ordinal is used as index
185                 return enumItem.ordinal();
186             }
187         }
188         return -1;
189     };
190 
191 
192     /**
193      * Read from system properties, or those in jaxp.properties
194      *
195      * @param property the property
196      * @param systemProperty the name of the system property
197      */
getSystemProperty(Enum<?> property, String systemProperty)198     void getSystemProperty(Enum<?> property, String systemProperty) {
199         try {
200             String value = SecuritySupport.getSystemProperty(systemProperty);
201             if (value != null) {
202                 values[property.ordinal()] = value;
203                 states[property.ordinal()] = State.SYSTEMPROPERTY;
204                 return;
205             }
206 
207             value = SecuritySupport.readJAXPProperty(systemProperty);
208             if (value != null) {
209                 values[property.ordinal()] = value;
210                 states[property.ordinal()] = State.JAXPDOTPROPERTIES;
211             }
212         } catch (NumberFormatException e) {
213             //invalid setting ignored
214         }
215     }
216 }
217