View Javadoc
1   /*
2    * Copyright (c) 2005, 2013, 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.xerces.internal.impl;
27  
28  import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
29  import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
30  import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
31  import java.util.HashMap;
32  import javax.xml.stream.XMLInputFactory;
33  import javax.xml.stream.XMLOutputFactory;
34  import javax.xml.stream.XMLResolver;
35  
36  /**
37   *  This class manages different properties related to Stax specification and its implementation.
38   * This class constructor also takes itself (PropertyManager object) as parameter and initializes the
39   * object with the property taken from the object passed.
40   *
41   * @author  Neeraj Bajaj, neeraj.bajaj@sun.com
42   * @author K.Venugopal@sun.com
43   * @author Sunitha Reddy, sunitha.reddy@sun.com
44   */
45  
46  public class PropertyManager {
47  
48  
49      public static final String STAX_NOTATIONS = "javax.xml.stream.notations";
50      public static final String STAX_ENTITIES = "javax.xml.stream.entities";
51  
52      private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning";
53  
54      /** Property identifier: Security manager. */
55      private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER;
56  
57      /** Property identifier: Security property manager. */
58      private static final String XML_SECURITY_PROPERTY_MANAGER =
59              Constants.XML_SECURITY_PROPERTY_MANAGER;
60  
61      HashMap supportedProps = new HashMap();
62  
63      private XMLSecurityManager fSecurityManager;
64      private XMLSecurityPropertyManager fSecurityPropertyMgr;
65  
66      public static final int CONTEXT_READER = 1;
67      public static final int CONTEXT_WRITER = 2;
68  
69      /** Creates a new instance of PropertyManager */
70      public PropertyManager(int context) {
71          switch(context){
72              case CONTEXT_READER:{
73                  initConfigurableReaderProperties();
74                  break;
75              }
76              case CONTEXT_WRITER:{
77                  initWriterProps();
78                  break;
79              }
80          }
81      }
82  
83      /**
84       * Initialize this object with the properties taken from passed PropertyManager object.
85       */
86      public PropertyManager(PropertyManager propertyManager){
87  
88          HashMap properties = propertyManager.getProperties();
89          supportedProps.putAll(properties);
90          fSecurityManager = (XMLSecurityManager)getProperty(SECURITY_MANAGER);
91          fSecurityPropertyMgr = (XMLSecurityPropertyManager)getProperty(XML_SECURITY_PROPERTY_MANAGER);
92      }
93  
94      private HashMap getProperties(){
95          return supportedProps ;
96      }
97  
98  
99      /**
100      * Important point:
101      * 1. We are not exposing Xerces namespace property. Application should configure namespace through
102      * Stax specific property.
103      *
104      */
105     private void initConfigurableReaderProperties(){
106         //spec default values
107         supportedProps.put(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);
108         supportedProps.put(XMLInputFactory.IS_VALIDATING, Boolean.FALSE);
109         supportedProps.put(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.TRUE);
110         supportedProps.put(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.TRUE);
111         supportedProps.put(XMLInputFactory.IS_COALESCING, Boolean.FALSE);
112         supportedProps.put(XMLInputFactory.SUPPORT_DTD, Boolean.TRUE);
113         supportedProps.put(XMLInputFactory.REPORTER, null);
114         supportedProps.put(XMLInputFactory.RESOLVER, null);
115         supportedProps.put(XMLInputFactory.ALLOCATOR, null);
116         supportedProps.put(STAX_NOTATIONS,null );
117 
118         //zephyr (implementation) specific properties which can be set by the application.
119         //interning is always done
120         supportedProps.put(Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE , new Boolean(true));
121         //recognizing java encoding names by default
122         supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE,  new Boolean(true)) ;
123         //in stax mode, namespace declarations are not added as attributes
124         supportedProps.put(Constants.ADD_NAMESPACE_DECL_AS_ATTRIBUTE ,  Boolean.FALSE) ;
125         supportedProps.put(Constants.READER_IN_DEFINED_STATE, new Boolean(true));
126         supportedProps.put(Constants.REUSE_INSTANCE, new Boolean(true));
127         supportedProps.put(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.STAX_REPORT_CDATA_EVENT , new Boolean(false));
128         supportedProps.put(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD, Boolean.FALSE);
129         supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE, new Boolean(false));
130         supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, new Boolean(false));
131         supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE, new Boolean(false));
132 
133         fSecurityManager = new XMLSecurityManager(true);
134         supportedProps.put(SECURITY_MANAGER, fSecurityManager);
135         fSecurityPropertyMgr = new XMLSecurityPropertyManager();
136         supportedProps.put(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
137     }
138 
139     private void initWriterProps(){
140         supportedProps.put(XMLOutputFactory.IS_REPAIRING_NAMESPACES , Boolean.FALSE);
141         //default value of escaping characters is 'true'
142         supportedProps.put(Constants.ESCAPE_CHARACTERS , Boolean.TRUE);
143         supportedProps.put(Constants.REUSE_INSTANCE, new Boolean(true));
144     }
145 
146     /**
147      * public void reset(){
148      * supportedProps.clear() ;
149      * }
150      */
151     public boolean containsProperty(String property){
152         return supportedProps.containsKey(property) ||
153                 (fSecurityManager != null && fSecurityManager.getIndex(property) > -1) ||
154                 (fSecurityPropertyMgr!=null && fSecurityPropertyMgr.getIndex(property) > -1) ;
155     }
156 
157     public Object getProperty(String property){
158         return supportedProps.get(property);
159     }
160 
161     public void setProperty(String property, Object value){
162         String equivalentProperty = null ;
163         if(property == XMLInputFactory.IS_NAMESPACE_AWARE || property.equals(XMLInputFactory.IS_NAMESPACE_AWARE)){
164             equivalentProperty = Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE ;
165         }
166         else if(property == XMLInputFactory.IS_VALIDATING || property.equals(XMLInputFactory.IS_VALIDATING)){
167             if( (value instanceof Boolean) && ((Boolean)value).booleanValue()){
168                 throw new java.lang.IllegalArgumentException("true value of isValidating not supported") ;
169             }
170         }
171         else if(property == STRING_INTERNING || property.equals(STRING_INTERNING)){
172             if( (value instanceof Boolean) && !((Boolean)value).booleanValue()){
173                 throw new java.lang.IllegalArgumentException("false value of " + STRING_INTERNING + "feature is not supported") ;
174             }
175         }
176         else if(property == XMLInputFactory.RESOLVER || property.equals(XMLInputFactory.RESOLVER)){
177             //add internal stax property
178             supportedProps.put( Constants.XERCES_PROPERTY_PREFIX + Constants.STAX_ENTITY_RESOLVER_PROPERTY , new StaxEntityResolverWrapper((XMLResolver)value)) ;
179         }
180 
181         /**
182          * It's possible for users to set a security manager through the interface.
183          * If it's the old SecurityManager, convert it to the new XMLSecurityManager
184          */
185         if (property.equals(Constants.SECURITY_MANAGER)) {
186             fSecurityManager = XMLSecurityManager.convert(value, fSecurityManager);
187             supportedProps.put(Constants.SECURITY_MANAGER, fSecurityManager);
188             return;
189         }
190         if (property.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) {
191             if (value == null) {
192                 fSecurityPropertyMgr = new XMLSecurityPropertyManager();
193             } else {
194                 fSecurityPropertyMgr = (XMLSecurityPropertyManager)value;
195             }
196             supportedProps.put(Constants.XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
197             return;
198         }
199 
200         //check if the property is managed by security manager
201         if (fSecurityManager == null ||
202                 !fSecurityManager.setLimit(property, XMLSecurityManager.State.APIPROPERTY, value)) {
203             //check if the property is managed by security property manager
204             if (fSecurityPropertyMgr == null ||
205                     !fSecurityPropertyMgr.setValue(property, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
206                 //fall back to the existing property manager
207                 supportedProps.put(property, value);
208             }
209         }
210 
211         if(equivalentProperty != null){
212             supportedProps.put(equivalentProperty, value ) ;
213         }
214     }
215 
216     public String toString(){
217         return supportedProps.toString();
218     }
219 
220 }//PropertyManager