Author: bimargulies
Date: Fri Oct 15 00:00:18 2010
New Revision: 1022772

URL: http://svn.apache.org/viewvc?rev=1022772&view=rev
Log:
add a mechanism for catching invalid mods to some of the global collections

Modified:
    webservices/commons/trunk/modules/XmlSchema/pom.xml
    
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchema.java
    
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaAttribute.java
    
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaAttributeGroup.java
    
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaElement.java
    
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaExternal.java
    
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaGroup.java
    
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaNotation.java
    
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaType.java
    
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/utils/CollectionFactory.java

Modified: webservices/commons/trunk/modules/XmlSchema/pom.xml
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/pom.xml?rev=1022772&r1=1022771&r2=1022772&view=diff
==============================================================================
--- webservices/commons/trunk/modules/XmlSchema/pom.xml (original)
+++ webservices/commons/trunk/modules/XmlSchema/pom.xml Fri Oct 15 00:00:18 2010
@@ -214,11 +214,15 @@
         </plugin>
         <plugin>
           <artifactId>maven-surefire-plugin</artifactId>
+         <version>2.6</version>
           <configuration>
            <forkMode>never</forkMode>
            <additionalClasspathElements>
              
<additionalClasspathElement>w3c-testcases</additionalClasspathElement>
            </additionalClasspathElements>
+           <systemPropertyVariables>
+             
<org.apache.ws.commons.schema.protectReadOnlyCollections>true</org.apache.ws.commons.schema.protectReadOnlyCollections>
+           </systemPropertyVariables>
           </configuration>
         </plugin>
         <plugin>
@@ -386,7 +390,7 @@
         <dependency>
           <groupId>xalan</groupId>
           <artifactId>xalan</artifactId>
-          <version>2.7.0</version>
+          <version>2.7.1</version>
         </dependency>
       </dependencies>
       <build>
@@ -394,23 +398,15 @@
           <plugin>
             <artifactId>maven-surefire-plugin</artifactId>
             <configuration>
-              <systemProperties>
-<!--
-                                                                       The 
default xalan TransformerFactory on the ibm jdk is
-                                                                       
org.apache.xalan.processor.TransformerFactoryImpl which has a
-                                                                       known 
issue with implicit namespaces. Set this property to use
-                                                                       the 
xsltc TransformerFactory (which the sun jdk seems to
-                                                                       default 
to).
-                                                               -->
-                <property>
-                  <name>
-                                                                               
javax.xml.transform.TransformerFactory
-                                                               </name>
-                  <value>
-                                                                               
org.apache.xalan.xsltc.trax.TransformerFactoryImpl
-                                                               </value>
-                </property>
-              </systemProperties>
+              <systemPropertyVariables>
+               <!--
+                   The default xalan TransformerFactory on the ibm jdk is
+                   org.apache.xalan.processor.TransformerFactoryImpl which has 
a
+                   known issue with implicit namespaces. Set this property to 
use
+                   the xsltc TransformerFactory (which the sun jdk seems to
+                   default to). -->
+               
<javax.xml.transform.TransformerFactory>org.apache.xalan.xsltc.trax.TransformerFactoryImpl</javax.xml.transform.TransformerFactory>
+              </systemPropertyVariables>
             </configuration>
           </plugin>
         </plugins>

Modified: 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchema.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchema.java?rev=1022772&r1=1022771&r2=1022772&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchema.java
 (original)
+++ 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchema.java
 Fri Oct 15 00:00:18 2010
@@ -45,6 +45,7 @@ import javax.xml.transform.stream.Stream
 import org.w3c.dom.Document;
 
 import 
org.apache.ws.commons.schema.XmlSchemaSerializer.XmlSchemaSerializerException;
+import org.apache.ws.commons.schema.utils.CollectionFactory;
 import org.apache.ws.commons.schema.utils.NamespaceContextOwner;
 import org.apache.ws.commons.schema.utils.NamespacePrefixList;
 
@@ -201,22 +202,28 @@ public class XmlSchema extends XmlSchema
      * Return a map containing all the defined attribute groups of this 
schema. The keys are QNames, where the
      * namespace will always be the target namespace of this schema. This 
makes it easier to look up items for
      * cross-schema references.
+     * <br/>
+     * If org.apache.ws.commons.schema.protectReadOnlyCollections
+     * is 'true', this will return a map that checks at runtime.
      *
      * @return the map of attribute groups.
      */
     public Map<QName, XmlSchemaAttributeGroup> getAttributeGroups() {
-        return attributeGroups;
+        return CollectionFactory.getProtectedMap(attributeGroups);
     }
 
     /**
      * Return a map containing all the defined attributes of this schema. The 
keys are QNames, where the
      * namespace will always be the target namespace of this schema. This 
makes it easier to look up items for
      * cross-schema references.
+     * <br/>
+     * If org.apache.ws.commons.schema.protectReadOnlyCollections
+     * is 'true', this will return a map that checks at runtime.
      *
      * @return the map of attributes.
      */
     public Map<QName, XmlSchemaAttribute> getAttributes() {
-        return attributes;
+        return CollectionFactory.getProtectedMap(attributes);
     }
 
     /**
@@ -260,20 +267,26 @@ public class XmlSchema extends XmlSchema
      * Return a map containing all the defined elements of this schema. The 
keys are QNames, where the
      * namespace will always be the target namespace of this schema. This 
makes it easier to look up items for
      * cross-schema references.
+     * <br/>
+     * If org.apache.ws.commons.schema.protectReadOnlyCollections
+     * is 'true', this will return a map that checks at runtime
      *
      * @return the map of elements.
      */
     public Map<QName, XmlSchemaElement> getElements() {
-        return elements;
+        return CollectionFactory.getProtectedMap(elements);
     }
 
     /**
      * Return all of the includes, imports, and redefines for this schema.
+     * <br/>
+     * If org.apache.ws.commons.schema.protectReadOnlyCollections
+     * is 'true', this will return a list that checks at runtime
      *
      * @return a list of the objects representing includes, imports, and 
redefines.
      */
     public List<XmlSchemaExternal> getExternals() {
-        return externals;
+        return CollectionFactory.getProtectedList(externals);
     }
 
     /**
@@ -296,12 +309,14 @@ public class XmlSchema extends XmlSchema
     /**
      * Return a map containing all the defined groups of this schema. The keys 
are QNames, where the namespace
      * will always be the target namespace of this schema. This makes it 
easier to look up items for
-     * cross-schema references.
+     * cross-schema references.<br/>
+     * If org.apache.ws.commons.schema.protectReadOnlyCollections
+     * is 'true', this will return a map that checks at runtime
      *
      * @return the map of groups.
      */
     public Map<QName, XmlSchemaGroup> getGroups() {
-        return groups;
+        return CollectionFactory.getProtectedMap(groups);
     }
 
     /**
@@ -315,10 +330,14 @@ public class XmlSchema extends XmlSchema
     }
 
     /**
+     * Return all of the global items in this schema.<br/>
+     * If org.apache.ws.commons.schema.protectReadOnlyCollections
+     * is 'true', this will return a map that checks at runtime.
      * @return <strong>all</strong> of the global items from this schema.
+     *
      */
     public List<XmlSchemaObject> getItems() {
-        return items;
+        return CollectionFactory.getProtectedList(items);
     }
 
     /**
@@ -353,11 +372,14 @@ public class XmlSchema extends XmlSchema
      * Return a map containing all the defined notations of this schema. The 
keys are QNames, where the
      * namespace will always be the target namespace of this schema. This 
makes it easier to look up items for
      * cross-schema references.
+     * <br/>
+     * If org.apache.ws.commons.schema.protectReadOnlyCollections
+     * is 'true', this will return a map that checks at runtime.
      *
      * @return the map of notations.
      */
     public Map<QName, XmlSchemaNotation> getNotations() {
-        return notations;
+        return CollectionFactory.getProtectedMap(notations);
     }
 
     /**

Modified: 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaAttribute.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaAttribute.java?rev=1022772&r1=1022771&r2=1022772&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaAttribute.java
 (original)
+++ 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaAttribute.java
 Fri Oct 15 00:00:18 2010
@@ -21,6 +21,7 @@ package org.apache.ws.commons.schema;
 
 import javax.xml.namespace.QName;
 
+import org.apache.ws.commons.schema.utils.CollectionFactory;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamedWithForm;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamedWithFormImpl;
 import org.apache.ws.commons.schema.utils.XmlSchemaRef;
@@ -53,8 +54,13 @@ public class XmlSchemaAttribute extends 
         namedDelegate.setRefObject(ref);
         ref.setNamedObject(namedDelegate);
         use = XmlSchemaUse.NONE;
+        final XmlSchema fSchema = schema;
         if (topLevel) {
-            schema.getItems().add(this);
+            CollectionFactory.withSchemaModifiable(new Runnable() {
+                public void run() {
+                    fSchema.getItems().add(XmlSchemaAttribute.this);
+                }
+            });
         }
     }
 
@@ -130,17 +136,23 @@ public class XmlSchemaAttribute extends 
     }
 
     public void setName(String name) {
+        final String fName = name;
+        CollectionFactory.withSchemaModifiable(new Runnable() {
 
-        if (namedDelegate.isTopLevel() && namedDelegate.getName() != null) {
-            namedDelegate.getParent().getAttributes().remove(getQName());
-        }
-        namedDelegate.setName(name);
-        if (namedDelegate.isTopLevel()) {
-            if (name == null) {
-                throw new XmlSchemaException("Top-level attributes may not be 
anonymous");
+            public void run() {
+                if (namedDelegate.isTopLevel() && namedDelegate.getName() != 
null) {
+                    
namedDelegate.getParent().getAttributes().remove(getQName());
+                }
+                namedDelegate.setName(fName);
+                if (namedDelegate.isTopLevel()) {
+                    if (fName == null) {
+                        throw new XmlSchemaException("Top-level attributes may 
not be anonymous");
+                    }
+                    namedDelegate.getParent().getAttributes().put(getQName(), 
XmlSchemaAttribute.this);
+                }
             }
-            namedDelegate.getParent().getAttributes().put(getQName(), this);
-        }
+
+        });
     }
 
     public boolean isFormSpecified() {

Modified: 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaAttributeGroup.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaAttributeGroup.java?rev=1022772&r1=1022771&r2=1022772&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaAttributeGroup.java
 (original)
+++ 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaAttributeGroup.java
 Fri Oct 15 00:00:18 2010
@@ -19,20 +19,20 @@
 
 package org.apache.ws.commons.schema;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import javax.xml.namespace.QName;
 
+import org.apache.ws.commons.schema.utils.CollectionFactory;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamed;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamedImpl;
 
 /**
- * Class for attribute groups. Groups a set of attribute declarations so that 
+ * Class for attribute groups. Groups a set of attribute declarations so that
  * they can be incorporated as a
- * group into complex type definitions. Represents the World Wide Web 
+ * group into complex type definitions. Represents the World Wide Web
  * consortium (W3C) attributeGroup element when it does <i>not</i> have a 
'ref='
- * attribute. 
+ * attribute.
  */
 
 public class XmlSchemaAttributeGroup extends XmlSchemaAnnotated implements 
XmlSchemaNamed,
@@ -45,10 +45,16 @@ public class XmlSchemaAttributeGroup ext
      * Creates new XmlSchemaAttributeGroup
      */
     public XmlSchemaAttributeGroup(XmlSchema parent) {
+        final XmlSchema fParent = parent;
         namedDelegate = new XmlSchemaNamedImpl(parent, true);
-        parent.getItems().add(this);
+        CollectionFactory.withSchemaModifiable(new Runnable() {
+            public void run() {
+                fParent.getItems().add(XmlSchemaAttributeGroup.this);
+            }
+        });
+
         // we can't be put in the map until we have a name. Perhaps we should 
be forced to have a name ?
-        attributes = new ArrayList<XmlSchemaAttributeGroupMember>();
+        attributes = 
CollectionFactory.getList(XmlSchemaAttributeGroupMember.class);
     }
 
     public XmlSchemaAnyAttribute getAnyAttribute() {
@@ -84,10 +90,15 @@ public class XmlSchemaAttributeGroup ext
     }
 
     public void setName(String name) {
-        if (name != null) {
-            namedDelegate.getParent().getAttributeGroups().remove(getQName());
-        }
-        namedDelegate.setName(name);
-        namedDelegate.getParent().getAttributeGroups().put(getQName(), this);
+        final String fName = name;
+        CollectionFactory.withSchemaModifiable(new Runnable() {
+            public void run() {
+                if (fName != null) {
+                    
namedDelegate.getParent().getAttributeGroups().remove(getQName());
+                }
+                namedDelegate.setName(fName);
+                namedDelegate.getParent().getAttributeGroups().put(getQName(), 
XmlSchemaAttributeGroup.this);
+            }
+        });
     }
 }

Modified: 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaElement.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaElement.java?rev=1022772&r1=1022771&r2=1022772&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaElement.java
 (original)
+++ 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaElement.java
 Fri Oct 15 00:00:18 2010
@@ -25,6 +25,7 @@ import java.util.List;
 
 import javax.xml.namespace.QName;
 
+import org.apache.ws.commons.schema.utils.CollectionFactory;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamedWithForm;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamedWithFormImpl;
 import org.apache.ws.commons.schema.utils.XmlSchemaRef;
@@ -93,8 +94,13 @@ public class XmlSchemaElement extends Xm
         nillable = false;
         finalDerivation = XmlSchemaDerivationMethod.NONE;
         block = XmlSchemaDerivationMethod.NONE;
+        final XmlSchema fParentSchema = parentSchema;
         if (topLevel) {
-            parentSchema.getItems().add(this);
+            CollectionFactory.withSchemaModifiable(new Runnable() {
+                public void run() {
+                    fParentSchema.getItems().add(XmlSchemaElement.this);
+                }
+            });
         }
     }
 
@@ -215,13 +221,18 @@ public class XmlSchemaElement extends Xm
     }
 
     public void setName(String name) {
-        if (namedDelegate.isTopLevel() && namedDelegate.getName() != null) {
-            namedDelegate.getParent().getElements().remove(getQName());
-        }
-        namedDelegate.setName(name);
-        if (namedDelegate.isTopLevel()) {
-            namedDelegate.getParent().getElements().put(getQName(), this);
-        }
+        final String fName = name;
+        CollectionFactory.withSchemaModifiable(new Runnable() {
+            public void run() {
+                if (namedDelegate.isTopLevel() && namedDelegate.getName() != 
null) {
+                    namedDelegate.getParent().getElements().remove(getQName());
+                }
+                namedDelegate.setName(fName);
+                if (namedDelegate.isTopLevel()) {
+                    namedDelegate.getParent().getElements().put(getQName(), 
XmlSchemaElement.this);
+                }
+            }
+        });
     }
 
     public XmlSchemaForm getForm() {

Modified: 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaExternal.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaExternal.java?rev=1022772&r1=1022771&r2=1022772&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaExternal.java
 (original)
+++ 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaExternal.java
 Fri Oct 15 00:00:18 2010
@@ -19,6 +19,8 @@
 
 package org.apache.ws.commons.schema;
 
+import org.apache.ws.commons.schema.utils.CollectionFactory;
+
 /**
  * Common class for include, import, and redefine. All have in common two 
items:
  * the location of the referenced schema (required) and an optional
@@ -33,8 +35,14 @@ public abstract class XmlSchemaExternal 
      * Creates new XmlSchemaExternal
      */
     protected XmlSchemaExternal(XmlSchema parent) {
-        parent.getExternals().add(this);
-        parent.getItems().add(this);
+        final XmlSchema fParent = parent;
+        CollectionFactory.withSchemaModifiable(new Runnable() {
+
+            public void run() {
+                fParent.getExternals().add(XmlSchemaExternal.this);
+                fParent.getItems().add(XmlSchemaExternal.this);
+            }
+        });
     }
 
     public XmlSchema getSchema() {

Modified: 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaGroup.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaGroup.java?rev=1022772&r1=1022771&r2=1022772&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaGroup.java
 (original)
+++ 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaGroup.java
 Fri Oct 15 00:00:18 2010
@@ -22,6 +22,7 @@ package org.apache.ws.commons.schema;
 
 import javax.xml.namespace.QName;
 
+import org.apache.ws.commons.schema.utils.CollectionFactory;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamed;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamedImpl;
 
@@ -31,17 +32,22 @@ import org.apache.ws.commons.schema.util
  * the World Wide Web Consortium (W3C) group element.
  */
 
-public class XmlSchemaGroup extends XmlSchemaAnnotated implements 
XmlSchemaNamed, 
+public class XmlSchemaGroup extends XmlSchemaAnnotated implements 
XmlSchemaNamed,
     XmlSchemaChoiceMember, XmlSchemaSequenceMember {
 
     private XmlSchemaGroupParticle particle;
     private XmlSchemaNamedImpl namedDelegate;
-    
+
     public XmlSchemaGroup(XmlSchema parent) {
         namedDelegate = new XmlSchemaNamedImpl(parent, true);
-        parent.getItems().add(this);
+        final XmlSchema fParent = parent;
+        CollectionFactory.withSchemaModifiable(new Runnable() {
+            public void run() {
+                fParent.getItems().add(XmlSchemaGroup.this);
+            }
+        });
     }
-    
+
 
     public XmlSchemaGroupParticle getParticle() {
         return particle;
@@ -72,13 +78,17 @@ public class XmlSchemaGroup extends XmlS
     }
 
     public void setName(String name) {
-        if (namedDelegate.getQName() != null) {
-            
namedDelegate.getParent().getGroups().remove(namedDelegate.getQName());
-        }
-        namedDelegate.setName(name);
-        if (name != null) {
-            
namedDelegate.getParent().getGroups().put(namedDelegate.getQName(), this);
-        }
+        final String fName = name;
+        CollectionFactory.withSchemaModifiable(new Runnable() {
+            public void run() {
+                if (namedDelegate.getQName() != null) {
+                    
namedDelegate.getParent().getGroups().remove(namedDelegate.getQName());
+                }
+                namedDelegate.setName(fName);
+                if (fName != null) {
+                    
namedDelegate.getParent().getGroups().put(namedDelegate.getQName(), 
XmlSchemaGroup.this);
+                }
+            }
+        });
     }
-
 }

Modified: 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaNotation.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaNotation.java?rev=1022772&r1=1022771&r2=1022772&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaNotation.java
 (original)
+++ 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaNotation.java
 Fri Oct 15 00:00:18 2010
@@ -21,6 +21,7 @@ package org.apache.ws.commons.schema;
 
 import javax.xml.namespace.QName;
 
+import org.apache.ws.commons.schema.utils.CollectionFactory;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamed;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamedImpl;
 
@@ -41,7 +42,12 @@ public class XmlSchemaNotation extends X
      */
     public XmlSchemaNotation(XmlSchema parent) {
         namedDelegate = new XmlSchemaNamedImpl(parent, true);
-        parent.getItems().add(this);
+        final XmlSchema fParent = parent;
+        CollectionFactory.withSchemaModifiable(new Runnable() {
+            public void run() {
+                fParent.getItems().add(XmlSchemaNotation.this);
+            }
+        });
     }
 
     public String getPublic() {
@@ -93,10 +99,15 @@ public class XmlSchemaNotation extends X
     }
 
     public void setName(String name) {
-        if (namedDelegate.getName() != null) {
-            namedDelegate.getParent().getNotations().remove(getQName());
-        }
-        namedDelegate.setName(name);
-        namedDelegate.getParent().getNotations().put(getQName(), this);
+        final String fName = name;
+        CollectionFactory.withSchemaModifiable(new Runnable() {
+            public void run() {
+                if (namedDelegate.getName() != null) {
+                    
namedDelegate.getParent().getNotations().remove(getQName());
+                }
+                namedDelegate.setName(fName);
+                namedDelegate.getParent().getNotations().put(getQName(), 
XmlSchemaNotation.this);
+            }
+        });
     }
 }

Modified: 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaType.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaType.java?rev=1022772&r1=1022771&r2=1022772&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaType.java
 (original)
+++ 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/XmlSchemaType.java
 Fri Oct 15 00:00:18 2010
@@ -21,6 +21,7 @@ package org.apache.ws.commons.schema;
 
 import javax.xml.namespace.QName;
 
+import org.apache.ws.commons.schema.utils.CollectionFactory;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamed;
 import org.apache.ws.commons.schema.utils.XmlSchemaNamedImpl;
 
@@ -42,10 +43,16 @@ public abstract class XmlSchemaType exte
      * Creates new XmlSchemaType
      */
     protected XmlSchemaType(XmlSchema schema, boolean topLevel) {
+        final XmlSchema fSchema = schema;
         namedDelegate = new XmlSchemaNamedImpl(schema, topLevel);
         finalDerivation = XmlSchemaDerivationMethod.NONE;
         if (topLevel) {
-            schema.getItems().add(this);
+            CollectionFactory.withSchemaModifiable(new Runnable() {
+
+                public void run() {
+                    fSchema.getItems().add(XmlSchemaType.this);
+                }
+            });
         }
     }
 

Modified: 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/utils/CollectionFactory.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/utils/CollectionFactory.java?rev=1022772&r1=1022771&r2=1022772&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/utils/CollectionFactory.java
 (original)
+++ 
webservices/commons/trunk/modules/XmlSchema/src/main/java/org/apache/ws/commons/schema/utils/CollectionFactory.java
 Fri Oct 15 00:00:18 2010
@@ -23,24 +23,79 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
- * There are many collections of XML Schema objects inside XmlSchema.
- * This class provides consistent construction to centralize policy
- * for thread synchronization and the like.
+ * There are many collections of XML Schema objects inside XmlSchema. This 
class provides consistent
+ * construction to centralize policy for thread synchronization and the like.
  */
 public final class CollectionFactory {
-    
+
+    private static final String PROTECT_READ_ONLY_COLLECTIONS_PROP =
+        "org.apache.ws.commons.schema.protectReadOnlyCollections";
+
+    private static final ThreadLocal<Boolean> PROTECT_READ_ONLY_COLLECTIONS = 
new ThreadLocal<Boolean>() {
+
+        @Override
+        protected Boolean initialValue() {
+            return 
Boolean.parseBoolean(System.getProperty(PROTECT_READ_ONLY_COLLECTIONS_PROP));
+        }
+    };
+
     private CollectionFactory() {
     }
-    
+
     public static <T> List<T> getList(Class<T> type) {
         return Collections.synchronizedList(new ArrayList<T>());
     }
-    
+
     public static <T> Set<T> getSet(Class<T> type) {
         return Collections.synchronizedSet(new HashSet<T>());
     }
 
+    /**
+     * Call this to obtain a list to return from a public API where the caller 
is not supposed to modify the
+     * list. If org.apache.ws.commons.schema.protectReadOnlyCollections is 
'true', this will return a list
+     * that checks at runtime.
+     *
+     * @param <T> Generic parameter type of the list.
+     * @param list the list.
+     * @return
+     */
+    public static <T> List<T> getProtectedList(List<T> list) {
+        if (PROTECT_READ_ONLY_COLLECTIONS.get().booleanValue()) {
+            return Collections.unmodifiableList(list);
+        } else {
+            return list;
+        }
+    }
+
+    /**
+     * Call this to obtain a map to return from a public API where the caller 
is not supposed to modify the
+     * map. If org.apache.ws.commons.schema.protectReadOnlyCollections is 
'true', this will return a map that
+     * checks at runtime.
+     *
+     * @param <K> key type
+     * @param <V> value type
+     * @param map the map.
+     * @return
+     */
+    public static <K, V> Map<K, V> getProtectedMap(Map<K, V> map) {
+        if (PROTECT_READ_ONLY_COLLECTIONS.get().booleanValue()) {
+            return Collections.unmodifiableMap(map);
+        } else {
+            return map;
+        }
+    }
+
+    public static void withSchemaModifiable(Runnable action) {
+        Boolean saved = PROTECT_READ_ONLY_COLLECTIONS.get();
+        try {
+            PROTECT_READ_ONLY_COLLECTIONS.set(Boolean.FALSE);
+            action.run();
+        } finally {
+            PROTECT_READ_ONLY_COLLECTIONS.set(saved);
+        }
+    }
 }


Reply via email to