CMNodeFactory.java revision 649:507d4f7efba6
1/*
2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
3 */
4/*
5 * Copyright 2003-2004 The Apache Software Foundation.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20
21package com.sun.org.apache.xerces.internal.impl.xs.models;
22
23import com.sun.org.apache.xerces.internal.impl.Constants;
24import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
25import com.sun.org.apache.xerces.internal.impl.dtd.models.CMNode;
26import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter;
27import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
28import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
29import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
30
31/**
32 *
33 * @xerces.internal
34 *
35 * @author  Neeraj Bajaj
36 *
37 */
38public class CMNodeFactory {
39
40
41    /** Property identifier: error reporter. */
42    private static final String ERROR_REPORTER =
43        Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
44
45    /** property identifier: security manager. */
46    private static final String SECURITY_MANAGER =
47        Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
48
49    private static final boolean DEBUG = false ;
50
51    //
52    private static final int MULTIPLICITY = 1 ;
53
54    //count of number of nodes created
55    private int nodeCount = 0;
56
57    //No. of nodes allowed.
58    private int maxNodeLimit ;
59
60
61    /**
62     * Error reporter. This property identifier is:
63     * http://apache.org/xml/properties/internal/error-reporter
64     */
65    private XMLErrorReporter fErrorReporter;
66
67    // stores defaults for different security holes (maxOccurLimit in current context) if it has
68    // been set on the configuration.
69    private XMLSecurityManager fSecurityManager = null;
70
71    /** default constructor */
72    public CMNodeFactory() {
73    }
74
75    public void reset(XMLComponentManager componentManager) {
76        fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
77        try {
78            fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER);
79            reset();
80        }
81        catch (XMLConfigurationException e) {
82            fSecurityManager = null;
83        }
84
85    }//reset()
86
87    public void reset() {
88        // we are setting the limit of number of nodes to 3 times the maxOccurs value.
89        if (fSecurityManager != null) {
90            maxNodeLimit = fSecurityManager.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT) * MULTIPLICITY ;
91        }
92    }
93
94    public CMNode getCMLeafNode(int type, Object leaf, int id, int position) {
95        return new XSCMLeaf(type, leaf, id, position) ;
96    }
97
98    public CMNode getCMRepeatingLeafNode(int type, Object leaf,
99            int minOccurs, int maxOccurs, int id, int position) {
100        nodeCountCheck();
101        return new XSCMRepeatingLeaf(type, leaf, minOccurs, maxOccurs, id, position);
102    }
103
104    public CMNode getCMUniOpNode(int type, CMNode childNode) {
105        nodeCountCheck();
106        return new XSCMUniOp(type, childNode) ;
107    }
108
109    public CMNode getCMBinOpNode(int type, CMNode leftNode, CMNode rightNode) {
110        return new XSCMBinOp(type, leftNode, rightNode) ;
111    }
112
113    public void nodeCountCheck(){
114        if( fSecurityManager != null && !fSecurityManager.isNoLimit(maxNodeLimit) &&
115                nodeCount++ > maxNodeLimit){
116            if(DEBUG){
117                System.out.println("nodeCount = " + nodeCount ) ;
118                System.out.println("nodeLimit = " + maxNodeLimit ) ;
119            }
120            fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, "maxOccurLimit", new Object[]{ new Integer(maxNodeLimit) }, XMLErrorReporter.SEVERITY_FATAL_ERROR);
121            // similarly to entity manager behaviour, take into accont
122            // behaviour if continue-after-fatal-error is set.
123            nodeCount = 0;
124        }
125
126    }//nodeCountCheck()
127
128    //reset the node count
129    public void resetNodeCount(){
130        nodeCount = 0 ;
131    }
132        /**
133     * Sets the value of a property. This method is called by the component
134     * manager any time after reset when a property changes value.
135     * <p>
136     * <strong>Note:</strong> Components should silently ignore properties
137     * that do not affect the operation of the component.
138     *
139     * @param propertyId The property identifier.
140     * @param value      The value of the property.
141     *
142     * @throws SAXNotRecognizedException The component should not throw
143     *                                   this exception.
144     * @throws SAXNotSupportedException The component should not throw
145     *                                  this exception.
146     */
147    public void setProperty(String propertyId, Object value)
148        throws XMLConfigurationException {
149
150        // Xerces properties
151        if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
152                final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
153
154            if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() &&
155                propertyId.endsWith(Constants.SECURITY_MANAGER_PROPERTY)) {
156                fSecurityManager = (XMLSecurityManager)value;
157                maxNodeLimit = (fSecurityManager != null) ?
158                        fSecurityManager.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT) * MULTIPLICITY : 0 ;
159                return;
160            }
161            if (suffixLength == Constants.ERROR_REPORTER_PROPERTY.length() &&
162                propertyId.endsWith(Constants.ERROR_REPORTER_PROPERTY)) {
163                fErrorReporter = (XMLErrorReporter)value;
164                return;
165            }
166        }
167
168    } // setProperty(String,Object)
169
170}//CMNodeFactory()
171