1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2001, 2002,2004 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xerces.internal.util; 22 23 import java.util.Arrays; 24 import java.util.HashMap; 25 import java.util.HashSet; 26 import java.util.Map; 27 import java.util.Set; 28 29 import com.sun.org.apache.xerces.internal.impl.Constants; 30 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; 31 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 32 33 /** 34 * This class implements the basic operations for managing parser 35 * configuration features and properties. This utility class can 36 * be used as a base class for parser configurations or separately 37 * to encapsulate a number of parser settings as a component 38 * manager. 39 * <p> 40 * This class can be constructed with a "parent" settings object 41 * (in the form of an <code>XMLComponentManager</code>) that allows 42 * parser configuration settings to be "chained" together. 43 * 44 * @author Andy Clark, IBM 45 * 46 * @version $Id: ParserConfigurationSettings.java,v 1.6 2010-11-01 04:40:14 joehw Exp $ 47 */ 48 public class ParserConfigurationSettings 49 implements XMLComponentManager { 50 51 protected static final String PARSER_SETTINGS = 52 Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; 53 54 // 55 // Data 56 // 57 58 // data 59 60 /** Recognized properties. */ 61 protected Set<String> fRecognizedProperties; 62 63 /** Properties. */ 64 protected Map<String, Object> fProperties; 65 66 /** Recognized features. */ 67 protected Set<String> fRecognizedFeatures; 68 69 /** Features. */ 70 protected Map<String, Boolean> fFeatures; 71 72 /** Parent parser configuration settings. */ 73 protected XMLComponentManager fParentSettings; 74 75 // 76 // Constructors 77 // 78 79 /** Default Constructor. */ 80 public ParserConfigurationSettings() { 81 this(null); 82 } // <init>() 83 84 /** 85 * Constructs a parser configuration settings object with a 86 * parent settings object. 87 */ 88 public ParserConfigurationSettings(XMLComponentManager parent) { 89 90 // create storage for recognized features and properties 91 fRecognizedFeatures = new HashSet<String>(); 92 fRecognizedProperties = new HashSet<String>(); 93 94 // create table for features and properties 95 fFeatures = new HashMap<String, Boolean>(); 96 fProperties = new HashMap<String, Object>(); 97 98 // save parent 99 fParentSettings = parent; 100 101 } // <init>(XMLComponentManager) 102 103 // 104 // XMLParserConfiguration methods 105 // 106 107 /** 108 * Allows a parser to add parser specific features to be recognized 109 * and managed by the parser configuration. 110 * 111 * @param featureIds An array of the additional feature identifiers 112 * to be recognized. 113 */ 114 public void addRecognizedFeatures(String[] featureIds) { 115 116 // add recognized features 117 int featureIdsCount = featureIds != null ? featureIds.length : 0; 118 for (int i = 0; i < featureIdsCount; i++) { 119 String featureId = featureIds[i]; 120 if (!fRecognizedFeatures.contains(featureId)) { 121 fRecognizedFeatures.add(featureId); 122 } 123 } 124 125 } // addRecognizedFeatures(String[]) 126 127 /** 128 * Set the state of a feature. 129 * 130 * Set the state of any feature in a SAX2 parser. The parser 131 * might not recognize the feature, and if it does recognize 132 * it, it might not be able to fulfill the request. 133 * 134 * @param featureId The unique identifier (URI) of the feature. 135 * @param state The requested state of the feature (true or false). 136 * 137 * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the 138 * requested feature is not known. 139 */ 140 public void setFeature(String featureId, boolean state) 141 throws XMLConfigurationException { 142 143 // check and store 144 FeatureState checkState = checkFeature(featureId); 145 if (checkState.isExceptional()) { 146 throw new XMLConfigurationException(checkState.status, featureId); 147 } 148 149 fFeatures.put(featureId, state); 150 } // setFeature(String,boolean) 151 152 /** 153 * Allows a parser to add parser specific properties to be recognized 154 * and managed by the parser configuration. 155 * 156 * @param propertyIds An array of the additional property identifiers 157 * to be recognized. 158 */ 159 public void addRecognizedProperties(String[] propertyIds) { 160 fRecognizedProperties.addAll(Arrays.asList(propertyIds)); 161 } // addRecognizedProperties(String[]) 162 163 /** 164 * setProperty 165 * 166 * @param propertyId 167 * @param value 168 * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the 169 * requested feature is not known. 170 */ 171 public void setProperty(String propertyId, Object value) 172 throws XMLConfigurationException { 173 174 // check and store 175 PropertyState checkState = checkProperty(propertyId); 176 if (checkState.isExceptional()) { 177 throw new XMLConfigurationException(checkState.status, propertyId); 178 } 179 fProperties.put(propertyId, value); 180 181 } // setProperty(String,Object) 182 183 // 184 // XMLComponentManager methods 185 // 186 187 /** 188 * Returns the state of a feature. 189 * 190 * @param featureId The feature identifier. 191 * @return true if the feature is supported 192 * 193 * @throws XMLConfigurationException Thrown for configuration error. 194 * In general, components should 195 * only throw this exception if 196 * it is <strong>really</strong> 197 * a critical error. 198 */ 199 public final boolean getFeature(String featureId) 200 throws XMLConfigurationException { 201 202 FeatureState state = getFeatureState(featureId); 203 if (state.isExceptional()) { 204 throw new XMLConfigurationException(state.status, featureId); 205 } 206 return state.state; 207 } // getFeature(String):boolean 208 209 public final boolean getFeature(String featureId, boolean defaultValue) { 210 FeatureState state = getFeatureState(featureId); 211 if (state.isExceptional()) { 212 return defaultValue; 213 } 214 return state.state; 215 } 216 217 public FeatureState getFeatureState(String featureId) { 218 Boolean state = (Boolean) fFeatures.get(featureId); 219 220 if (state == null) { 221 FeatureState checkState = checkFeature(featureId); 222 if (checkState.isExceptional()) { 223 return checkState; 224 } 225 return FeatureState.is(false); 226 } 227 return FeatureState.is(state); 228 } 229 230 /** 231 * Returns the value of a property. 232 * 233 * @param propertyId The property identifier. 234 * @return the value of the property 235 * 236 * @throws XMLConfigurationException Thrown for configuration error. 237 * In general, components should 238 * only throw this exception if 239 * it is <strong>really</strong> 240 * a critical error. 241 */ 242 public final Object getProperty(String propertyId) 243 throws XMLConfigurationException { 244 245 PropertyState state = getPropertyState(propertyId); 246 if (state.isExceptional()) { 247 throw new XMLConfigurationException(state.status, propertyId); 248 } 249 250 return state.state; 251 } // getProperty(String):Object 252 253 public final Object getProperty(String propertyId, Object defaultValue) { 254 PropertyState state = getPropertyState(propertyId); 255 if (state.isExceptional()) { 256 return defaultValue; 257 } 258 259 return state.state; 260 } 261 262 public PropertyState getPropertyState(String propertyId) { 263 Object propertyValue = fProperties.get(propertyId); 264 265 if (propertyValue == null) { 266 PropertyState state = checkProperty(propertyId); 267 if (state.isExceptional()) { 268 return state; 269 } 270 } 271 272 return PropertyState.is(propertyValue); 273 } 274 275 // 276 // Protected methods 277 // 278 279 /** 280 * Check a feature. If feature is known and supported, this method simply 281 * returns. Otherwise, the appropriate exception is thrown. 282 * 283 * @param featureId The unique identifier (URI) of the feature. 284 * 285 * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the 286 * requested feature is not known. 287 */ 288 protected FeatureState checkFeature(String featureId) 289 throws XMLConfigurationException { 290 291 // check feature 292 if (!fRecognizedFeatures.contains(featureId)) { 293 if (fParentSettings != null) { 294 return fParentSettings.getFeatureState(featureId); 295 } 296 else { 297 return FeatureState.NOT_RECOGNIZED; 298 } 299 } 300 301 // TODO: reasonable default? 302 return FeatureState.RECOGNIZED; 303 } // checkFeature(String) 304 305 /** 306 * Check a property. If the property is known and supported, this method 307 * simply returns. Otherwise, the appropriate exception is thrown. 308 * 309 * @param propertyId The unique identifier (URI) of the property 310 * being set. 311 * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the 312 * requested feature is not known. 313 */ 314 protected PropertyState checkProperty(String propertyId) 315 throws XMLConfigurationException { 316 317 // check property 318 if (!fRecognizedProperties.contains(propertyId)) { 319 if (fParentSettings != null) { 320 PropertyState state = fParentSettings.getPropertyState(propertyId); 321 if (state.isExceptional()) { 322 return state; 323 } 324 } 325 else { 326 return PropertyState.NOT_RECOGNIZED; 327 } 328 } 329 return PropertyState.RECOGNIZED; 330 } // checkProperty(String) 331 332 } // class ParserConfigurationSettings