Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 361278 - DocumentRoot.getXMLNSPrefixMap().entrySet().iterator() remove fails under certain conditions.
Summary: DocumentRoot.getXMLNSPrefixMap().entrySet().iterator() remove fails under cer...
Status: CLOSED FIXED
Alias: None
Product: EMF
Classification: Modeling
Component: Core (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Ed Merks CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-10-18 12:49 EDT by John T.E. Timm CLA
Modified: 2011-11-22 05:26 EST (History)
0 users

See Also:


Attachments
Patches to address the issue. (770 bytes, patch)
2011-10-18 13:40 EDT, Ed Merks CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description John T.E. Timm CLA 2011-10-18 12:49:09 EDT
Build Identifier: M20110210-1200

When using the XMLNSPrefixMap that is created in some XML Schema based Ecore models, I would like to selectively remove certain entries from the map by first getting an iterator on the entrySet and then using Iterator.remove(). Under certain circumstances, the entry returned by iterator.next() is null.

Reproducible: Always

Steps to Reproduce:
1. Create a new XMLTypeDocumentRoot instance using XMLTypeFactory
2. Add entries to its XMLNSPrefixMap
3. Get an iterator on entrySet
4. Iterate over entries and selectively remove using iterator.remove()

		XMLTypeDocumentRoot root = XMLTypeFactory.eINSTANCE.createXMLTypeDocumentRoot();
		EMap<String, String> map = root.getXMLNSPrefixMap();

		map.put("_1", "urn:hl7-org:v3");
		map.put("ns0", "http://www.openhealthtools.org/mdht/uml/cda/toc");
		map.put("ns1", "http://www.openhealthtools.org/mdht/uml/cda/hitsp");
		map.put("ns2", "http://www.openhealthtools.org/mdht/uml/cda/ccd");
		map.put("ns3", "http://www.openhealthtools.org/mdht/uml/cda/ihe");
		map.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
		map.put("ns4", "http://www.openhealthtools.org/mdht/uml/hl7/datatypes");

		System.out.println("entrySet size before: " + map.entrySet().size());
		System.out.println("entrySet before: " + map.entrySet());
		Iterator<Entry<String, String>> iterator = map.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, String> entry = iterator.next();
			if (entry.getKey().equals("ns3")) {
				System.out.println("Attempting to remove: " + entry);
				iterator.remove();
				System.out.println("Successfully removed: " + entry);
			}
		}
		System.out.println("entrySet size after: " + map.entrySet().size());
		System.out.println("entrySet after: " + map.entrySet());

In this example, I add 7 entries to the prefix map. I would expect that when iterating over the entry set that every entry would be non-null but depending on what I select to remove, I sometimes get an NPE. The behavior also seems to depend on the cardinality of the entrySet. Odd cardinality fails, even cardinality succeeds.
Comment 1 John T.E. Timm CLA 2011-10-18 13:05:57 EDT
One possible workaround is to collect the keys for removal and then remove them afterwards with removeKey:

		System.out.println("entrySet size before: " + map.entrySet().size());
		System.out.println("entrySet before: " + map.entrySet());
		List<String> keys = new ArrayList<String>();
		for (Map.Entry<String, String> entry : map.entrySet()) {
			if (entry.getKey().equals("ns3")) {
				keys.add(entry.getKey());
			}
		}
		for (String key : keys) {
			System.out.println("Attempting to remove entry with key: " + key);
			map.removeKey(key);
			System.out.println("Successfully removed entry with key: " + key);
		}
		System.out.println("entrySet size after: " + map.entrySet().size());
		System.out.println("entrySet after: " + map.entrySet());
Comment 2 Ed Merks CLA 2011-10-18 13:40:20 EDT
Created attachment 205443 [details]
Patches to address the issue.

After the remove, if the next entry is in the same slot's list, the index into that slot needs to be reduced...
Comment 3 John T.E. Timm CLA 2011-10-18 13:56:49 EDT
Ed:

Thanks for the quick response!

JT
Comment 4 Ed Merks CLA 2011-10-25 13:35:44 EDT
The fixes are committed to CVS for 2.8.
Comment 5 Ed Merks CLA 2011-11-22 05:26:27 EST
The changes are available in builds.