mrglavas 2004/12/19 20:53:24 Modified: java/src/org/apache/xerces/impl/xs/opti SchemaDOMParser.java Log: Fixing a potential memory leak. Clear the stacks used to support the generate-synthetic annotations feature at the start of each document. If there was a failure on the previous usage, we might not be at depth 0. Also now using a specialized boolean stack for better performance. Revision Changes Path 1.16 +79 -16 xml-xerces/java/src/org/apache/xerces/impl/xs/opti/SchemaDOMParser.java Index: SchemaDOMParser.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/opti/SchemaDOMParser.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- SchemaDOMParser.java 20 Dec 2004 04:33:07 -0000 1.15 +++ SchemaDOMParser.java 20 Dec 2004 04:53:23 -0000 1.16 @@ -16,9 +16,6 @@ package org.apache.xerces.impl.xs.opti; - -import java.util.Stack; - import org.apache.xerces.impl.Constants; import org.apache.xerces.impl.XMLErrorReporter; import org.apache.xerces.impl.xs.SchemaSymbols; @@ -88,11 +85,11 @@ // Use to report the error when characters are not allowed. XMLErrorReporter fErrorReporter; + // fields for generate-synthetic annotations feature private boolean fGenerateSyntheticAnnotation = false; - private Stack fHasNonSchemaAttributes = new Stack(); - private XMLAttributes emptyAttr = new XMLAttributesImpl(); - private Stack fSawAnnotation = new Stack(); - + private BooleanStack fHasNonSchemaAttributes = new BooleanStack(); + private BooleanStack fSawAnnotation = new BooleanStack(); + private XMLAttributes fEmptyAttr = new XMLAttributesImpl(); // // XMLDocumentHandler methods @@ -103,6 +100,8 @@ throws XNIException { fErrorReporter = (XMLErrorReporter)config.getProperty(ERROR_REPORTER); fGenerateSyntheticAnnotation = config.getFeature(GENERATE_SYNTHETIC_ANNOTATION); + fHasNonSchemaAttributes.clear(); + fSawAnnotation.clear(); schemaDOM = new SchemaDOM(); fAnnotationDepth = -1; fInnerAnnotationDepth = -1; @@ -228,14 +227,14 @@ if (fSawAnnotation.size() > 0) { fSawAnnotation.pop(); } - fSawAnnotation.push(Boolean.TRUE); + fSawAnnotation.push(true); } fAnnotationDepth = fDepth; schemaDOM.startAnnotation(element, attributes, fNamespaceContext); } else if (fGenerateSyntheticAnnotation) { - fSawAnnotation.push(Boolean.FALSE); - fHasNonSchemaAttributes.push(hasNonSchemaAttributes(element, attributes) ? Boolean.TRUE : Boolean.FALSE); + fSawAnnotation.push(false); + fHasNonSchemaAttributes.push(hasNonSchemaAttributes(element, attributes)); } } else if(fDepth == fAnnotationDepth+1) { fInnerAnnotationDepth = fDepth; @@ -353,14 +352,14 @@ } } else { // not in an annotation at all if(fGenerateSyntheticAnnotation) { - boolean value = ((Boolean)fHasNonSchemaAttributes.pop()).booleanValue(); - boolean sawann = ((Boolean)fSawAnnotation.pop()).booleanValue(); - if(value && !sawann) { + boolean value = fHasNonSchemaAttributes.pop(); + boolean sawann = fSawAnnotation.pop(); + if (value && !sawann) { String schemaPrefix = fNamespaceContext.getPrefix(SchemaSymbols.URI_SCHEMAFORSCHEMA); QName annQName = new QName(schemaPrefix, SchemaSymbols.ELT_ANNOTATION, schemaPrefix + (schemaPrefix.length() == 0?"":":") + SchemaSymbols.ELT_ANNOTATION, SchemaSymbols.URI_SCHEMAFORSCHEMA); - schemaDOM.startAnnotation(annQName, emptyAttr, fNamespaceContext); + schemaDOM.startAnnotation(annQName, fEmptyAttr, fNamespaceContext); QName elemQName = new QName(schemaPrefix, SchemaSymbols.ELT_DOCUMENTATION, schemaPrefix + (schemaPrefix.length() == 0?"":":") + SchemaSymbols.ELT_DOCUMENTATION, SchemaSymbols.URI_SCHEMAFORSCHEMA); - schemaDOM.startAnnotationElement(elemQName, emptyAttr); + schemaDOM.startAnnotationElement(elemQName, fEmptyAttr); schemaDOM.characters(new XMLString("SYNTHETIC_ANNOTATION".toCharArray(), 0, 20 )); schemaDOM.endSyntheticAnnotationElement(elemQName, false); schemaDOM.endSyntheticAnnotationElement(annQName, true); @@ -453,4 +452,68 @@ return schemaDOM; } + /** + * A simple boolean based stack. + * + * @xerces.internal + */ + private static final class BooleanStack { + + // + // Data + // + + /** Stack depth. */ + private int fDepth; + + /** Stack data. */ + private boolean[] fData; + + // + // Constructor + // + + public BooleanStack () {} + + // + // Public methods + // + + /** Returns the size of the stack. */ + public int size() { + return fDepth; + } + + /** Pushes a value onto the stack. */ + public void push(boolean value) { + ensureCapacity(fDepth + 1); + fData[fDepth++] = value; + } + + /** Pops a value off of the stack. */ + public boolean pop() { + return fData[--fDepth]; + } + + /** Clears the stack. */ + public void clear() { + fDepth = 0; + } + + // + // Private methods + // + + /** Ensures capacity. */ + private void ensureCapacity(int size) { + if (fData == null) { + fData = new boolean[32]; + } + else if (fData.length <= size) { + boolean[] newdata = new boolean[fData.length * 2]; + System.arraycopy(fData, 0, newdata, 0, fData.length); + fData = newdata; + } + } + } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]