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