You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by mr...@apache.org on 2004/03/11 00:05:24 UTC
cvs commit: xml-xerces/java/src/org/apache/xerces/impl/xs/identity Field.java FieldActivator.java
mrglavas 2004/03/10 15:05:24
Modified: java/src/org/apache/xerces/impl/xs XMLSchemaValidator.java
java/src/org/apache/xerces/impl/xs/identity Field.java
FieldActivator.java
Log:
Fixing a thread-safety problem regarding identity constraints. Fields
which are contained in a SchemaGrammar were mutable; keeping the
state of whether a field is permitted to match a value in order to
detect whether there is more than one match for a field in a given
scope. This caused spurious errors about duplicate field matches
when a grammar with identity constraints was shared across
parsers on different threads. Applying a similar fix to the one
that Khaled made to Xerces-C++ to make this portion of the grammar
stateless.
Revision Changes Path
1.153 +47 -18 xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java
Index: XMLSchemaValidator.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java,v
retrieving revision 1.152
retrieving revision 1.153
diff -u -r1.152 -r1.153
--- XMLSchemaValidator.java 24 Feb 2004 22:59:11 -0000 1.152
+++ XMLSchemaValidator.java 10 Mar 2004 23:05:24 -0000 1.153
@@ -19,6 +19,7 @@
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.HashMap;
import java.util.Stack;
import java.util.Vector;
@@ -251,6 +252,12 @@
// If it is not present in calls that we're passing on, we *must*
// clear this before we introduce it into the pipeline.
protected final AugmentationsImpl fAugmentations = new AugmentationsImpl();
+
+ /**
+ * Map which is used to catch instance documents that try
+ * and match a field several times in the same scope.
+ */
+ protected final HashMap fMayMatchFieldMap = new HashMap();
// this is included for the convenience of handleEndElement
protected XMLString fDefaultValue;
@@ -1233,7 +1240,7 @@
fInCDATA = false;
fMatcherStack.clear();
-
+ fMayMatchFieldMap.clear();
// get error reporter
fXSIErrorReporter.reset((XMLErrorReporter) componentManager.getProperty(ERROR_REPORTER));
@@ -1380,21 +1387,21 @@
} // startValueScopeFor(IdentityConstraint identityConstraint)
- /**
- * Request to activate the specified field. This method returns the
- * matcher for the field.
- *
- * @param field The field to activate.
- */
- public XPathMatcher activateField(Field field, int initialDepth) {
- ValueStore valueStore =
- fValueStoreCache.getValueStoreFor(field.getIdentityConstraint(), initialDepth);
- field.setMayMatch(true);
- XPathMatcher matcher = field.createMatcher(valueStore);
- fMatcherStack.addMatcher(matcher);
- matcher.startDocumentFragment();
- return matcher;
- } // activateField(Field):XPathMatcher
+ /**
+ * Request to activate the specified field. This method returns the
+ * matcher for the field.
+ *
+ * @param field The field to activate.
+ */
+ public XPathMatcher activateField(Field field, int initialDepth) {
+ ValueStore valueStore =
+ fValueStoreCache.getValueStoreFor(field.getIdentityConstraint(), initialDepth);
+ setMayMatch(field, Boolean.TRUE);
+ XPathMatcher matcher = field.createMatcher(this, valueStore);
+ fMatcherStack.addMatcher(matcher);
+ matcher.startDocumentFragment();
+ return matcher;
+ } // activateField(Field):XPathMatcher
/**
* Ends the value scope for the specified identity constraint.
@@ -1408,6 +1415,28 @@
valueStore.endValueScope();
} // endValueScopeFor(IdentityConstraint)
+
+ /**
+ * Sets whether the given field is permitted to match a value.
+ * This should be used to catch instance documents that try
+ * and match a field several times in the same scope.
+ *
+ * @param field The field that may be permitted to be matched.
+ * @param state Boolean indiciating whether the field may be matched.
+ */
+ public void setMayMatch(Field field, Boolean state) {
+ fMayMatchFieldMap.put(field, state);
+ } // setMayMatch(Field, Boolean)
+
+ /**
+ * Returns whether the given field is permitted to match a value.
+ *
+ * @param field The field that may be permitted to be matched.
+ * @return Boolean indicating whether the field may be matched.
+ */
+ public Boolean mayMatch(Field field) {
+ return (Boolean) fMayMatchFieldMap.get(field);
+ } // mayMatch(Field):Boolean
// a utility method for Identity constraints
private void activateSelectorFor(IdentityConstraint ic) {
@@ -3345,7 +3374,7 @@
reportSchemaError(code, new Object[] { field.toString()});
return;
}
- if (!field.mayMatch()) {
+ if (Boolean.TRUE != mayMatch(field)) {
String code = "FieldMultipleMatch";
reportSchemaError(code, new Object[] { field.toString()});
} else {
1.16 +12 -8 xml-xerces/java/src/org/apache/xerces/impl/xs/identity/Field.java
Index: Field.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/identity/Field.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- Field.java 24 Feb 2004 22:59:14 -0000 1.15
+++ Field.java 10 Mar 2004 23:05:24 -0000 1.16
@@ -43,7 +43,7 @@
// whether this field can be matched; used to catch instance documents
// that try and match a field several times in the same scope.
- protected boolean mayMatch = true;
+ // protected boolean mayMatch = true;
//
// Constructors
@@ -60,7 +60,7 @@
// Public methods
//
- // sets mayMatch
+ /** // sets mayMatch
public void setMayMatch(boolean b) {
mayMatch = b;
} // setMayMatch(boolean);
@@ -68,7 +68,7 @@
// returns mayMatch
public boolean mayMatch() {
return mayMatch;
- } // mayMatch():boolean
+ } // mayMatch():boolean **/
/** Returns the field XPath. */
public org.apache.xerces.impl.xpath.XPath getXPath() {
@@ -83,8 +83,8 @@
// factory method
/** Creates a field matcher. */
- public XPathMatcher createMatcher(ValueStore store) {
- return new Field.Matcher(fXPath, store);
+ public XPathMatcher createMatcher(FieldActivator activator, ValueStore store) {
+ return new Field.Matcher(fXPath, activator, store);
} // createMatcher(ValueStore):XPathMatcher
//
@@ -153,6 +153,9 @@
// Data
//
+ /** Field activator. */
+ protected FieldActivator fFieldActivator;
+
/** Value store for data values. */
protected ValueStore fStore;
@@ -161,8 +164,9 @@
//
/** Constructs a field matcher. */
- public Matcher(Field.XPath xpath, ValueStore store) {
+ public Matcher(Field.XPath xpath, FieldActivator activator, ValueStore store) {
super(xpath);
+ fFieldActivator = activator;
fStore = store;
} // <init>(Field.XPath,ValueStore)
@@ -184,7 +188,7 @@
// once we've stored the value for this field, we set the mayMatch
// member to false so that, in the same scope, we don't match any more
// values (and throw an error instead).
- mayMatch = false;
+ fFieldActivator.setMayMatch(Field.this, Boolean.FALSE);
} // matched(String)
protected void handleContent(XSTypeDefinition type, boolean nillable, Object actualValue) {
1.6 +23 -5 xml-xerces/java/src/org/apache/xerces/impl/xs/identity/FieldActivator.java
Index: FieldActivator.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/identity/FieldActivator.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- FieldActivator.java 24 Feb 2004 22:59:14 -0000 1.5
+++ FieldActivator.java 10 Mar 2004 23:05:24 -0000 1.6
@@ -1,5 +1,5 @@
/*
- * Copyright 2001, 2002,2004 The Apache Software Foundation.
+ * Copyright 2001,2002,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,13 +46,31 @@
/**
* Request to activate the specified field. This method returns the
* matcher for the field.
- * It's also important for the implementor to ensure that the Field realizes that
- * it is permitted to match a value--that is, to call the field's setMayMatch(boolean) method.
+ * It's also important for the implementor to ensure that it marks whether a Field
+ * is permitted to match a value--that is, to call the setMayMatch(Field, Boolean) method.
*
* @param field The field to activate.
- * @param initialDepth the 0-indexed depth in the instance document at which the Selector began to match.
+ * @param initialDepth the 0-indexed depth in the instance document at which the Selector began to match.
*/
public XPathMatcher activateField(Field field, int initialDepth);
+
+ /**
+ * Sets whether the given field is permitted to match a value.
+ * This should be used to catch instance documents that try
+ * and match a field several times in the same scope.
+ *
+ * @param field The field that may be permitted to be matched.
+ * @param state Boolean indiciating whether the field may be matched.
+ */
+ public void setMayMatch(Field field, Boolean state);
+
+ /**
+ * Returns whether the given field is permitted to match a value.
+ *
+ * @param field The field that may be permitted to be matched.
+ * @return Boolean indicating whether the field may be matched.
+ */
+ public Boolean mayMatch(Field field);
/**
* Ends the value scope for the specified identity constraint.
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org