mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 06:02:11 +02:00
Bug 489553 - ConcurrentModificationException below
MapProblemPreference.clone Change-Id: If80417f386890495961745d13b3ad16040677e2e
This commit is contained in:
parent
6a7969bc85
commit
d8a5d3cc0e
2 changed files with 47 additions and 37 deletions
|
@ -12,9 +12,12 @@ package org.eclipse.cdt.codan.core.param;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StreamTokenizer;
|
import java.io.StreamTokenizer;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.core.model.AbstractCheckerWithProblemPreferences;
|
import org.eclipse.cdt.codan.core.model.AbstractCheckerWithProblemPreferences;
|
||||||
|
|
||||||
|
@ -30,9 +33,9 @@ import org.eclipse.cdt.codan.core.model.AbstractCheckerWithProblemPreferences;
|
||||||
*
|
*
|
||||||
* @noextend This class is not intended to be extended by clients.
|
* @noextend This class is not intended to be extended by clients.
|
||||||
*/
|
*/
|
||||||
public class MapProblemPreference extends AbstractProblemPreference implements IProblemPreferenceCompositeValue,
|
public class MapProblemPreference extends AbstractProblemPreference
|
||||||
IProblemPreferenceCompositeDescriptor {
|
implements IProblemPreferenceCompositeValue, IProblemPreferenceCompositeDescriptor {
|
||||||
protected LinkedHashMap<String, IProblemPreference> hash = new LinkedHashMap<String, IProblemPreference>();
|
private Map<String, IProblemPreference> hash = Collections.synchronizedMap(new LinkedHashMap<String, IProblemPreference>());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
|
@ -123,30 +126,34 @@ public class MapProblemPreference extends AbstractProblemPreference implements I
|
||||||
@Override
|
@Override
|
||||||
public Object clone() {
|
public Object clone() {
|
||||||
MapProblemPreference map = (MapProblemPreference) super.clone();
|
MapProblemPreference map = (MapProblemPreference) super.clone();
|
||||||
map.hash = new LinkedHashMap<String, IProblemPreference>();
|
synchronized (hash) {
|
||||||
for (Iterator<String> iterator = hash.keySet().iterator(); iterator.hasNext();) {
|
map.hash = Collections.synchronizedMap(new LinkedHashMap<String, IProblemPreference>(hash));
|
||||||
String key = iterator.next();
|
}
|
||||||
map.hash.put(key, (IProblemPreference) hash.get(key).clone());
|
// now we have to clone the values too
|
||||||
|
for (Entry<String, IProblemPreference> entry : map.hash.entrySet()) {
|
||||||
|
entry.setValue((IProblemPreference) entry.getValue().clone());
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String exportValue() {
|
public String exportValue() {
|
||||||
StringBuffer buf = new StringBuffer("{"); //$NON-NLS-1$
|
synchronized (hash) {
|
||||||
for (Iterator<String> iterator = hash.keySet().iterator(); iterator.hasNext();) {
|
StringBuffer buf = new StringBuffer("{"); //$NON-NLS-1$
|
||||||
String key = iterator.next();
|
for (Iterator<String> iterator = hash.keySet().iterator(); iterator.hasNext();) {
|
||||||
IProblemPreference d = hash.get(key);
|
String key = iterator.next();
|
||||||
if (d instanceof AbstractProblemPreference) {
|
IProblemPreference d = hash.get(key);
|
||||||
if (((AbstractProblemPreference) d).isDefault()) {
|
if (d instanceof AbstractProblemPreference) {
|
||||||
continue;
|
if (((AbstractProblemPreference) d).isDefault()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
buf.append(key + "=>" + d.exportValue()); //$NON-NLS-1$
|
||||||
|
if (iterator.hasNext())
|
||||||
|
buf.append(","); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
buf.append(key + "=>" + d.exportValue()); //$NON-NLS-1$
|
return buf.toString() + "}"; //$NON-NLS-1$
|
||||||
if (iterator.hasNext())
|
|
||||||
buf.append(","); //$NON-NLS-1$
|
|
||||||
}
|
}
|
||||||
return buf.toString() + "}"; //$NON-NLS-1$
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -243,12 +250,14 @@ public class MapProblemPreference extends AbstractProblemPreference implements I
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object getValue() {
|
public Object getValue() {
|
||||||
LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
|
synchronized (hash) {
|
||||||
for (Iterator<IProblemPreference> iterator = hash.values().iterator(); iterator.hasNext();) {
|
LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
|
||||||
IProblemPreference pref = iterator.next();
|
for (Iterator<IProblemPreference> iterator = hash.values().iterator(); iterator.hasNext();) {
|
||||||
map.put(pref.getKey(), pref.getValue());
|
IProblemPreference pref = iterator.next();
|
||||||
|
map.put(pref.getKey(), pref.getValue());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -263,19 +272,21 @@ public class MapProblemPreference extends AbstractProblemPreference implements I
|
||||||
@Override
|
@Override
|
||||||
public void setValue(Object value) {
|
public void setValue(Object value) {
|
||||||
Map<String, Object> map = (Map<String, Object>) value;
|
Map<String, Object> map = (Map<String, Object>) value;
|
||||||
LinkedHashMap<String, IProblemPreference> hash2 = (LinkedHashMap<String, IProblemPreference>) hash.clone();
|
synchronized (hash) {
|
||||||
hash.clear();
|
Map<String, IProblemPreference> hashCopy = new HashMap<>(hash);
|
||||||
for (Iterator<String> iterator = map.keySet().iterator(); iterator.hasNext();) {
|
hash.clear();
|
||||||
String key = iterator.next();
|
for (Iterator<String> iterator = map.keySet().iterator(); iterator.hasNext();) {
|
||||||
Object value2 = map.get(key);
|
String key = iterator.next();
|
||||||
if (value2 instanceof IProblemPreference) {
|
Object value2 = map.get(key);
|
||||||
hash.put(key, (IProblemPreference) value2);
|
if (value2 instanceof IProblemPreference) {
|
||||||
} else {
|
hash.put(key, (IProblemPreference) value2);
|
||||||
IProblemPreference pref = hash2.get(key);
|
} else {
|
||||||
addChildDescriptor(pref);
|
IProblemPreference pref = hashCopy.get(key);
|
||||||
//setChildValue(key, value2);
|
addChildDescriptor(pref);
|
||||||
pref.setValue(value2);
|
//setChildValue(key, value2);
|
||||||
hash.put(key, pref);
|
pref.setValue(value2);
|
||||||
|
hash.put(key, pref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ public class SharedRootProblemPreference extends RootProblemPreference {
|
||||||
public Object clone() {
|
public Object clone() {
|
||||||
SharedRootProblemPreference map = (SharedRootProblemPreference) super.clone();
|
SharedRootProblemPreference map = (SharedRootProblemPreference) super.clone();
|
||||||
// alruiz: sharing the internal hash is the only way I could make this work.
|
// alruiz: sharing the internal hash is the only way I could make this work.
|
||||||
map.hash = hash;
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue