Skip to content
Snippets Groups Projects
Commit e817ac31 authored by David Trachtenherz's avatar David Trachtenherz
Browse files

Bugfix: ConcurrentHashMap instead of HashMap in...

Bugfix: ConcurrentHashMap instead of HashMap in org.fortiss.tooling.kernel.ui.internal.MarkerService$CacheEntry
refs 750
parent 574d89d8
No related branches found
No related tags found
No related merge requests found
......@@ -27,6 +27,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.conqat.lib.commons.collections.IdentityHashSet;
import org.eclipse.core.runtime.IProgressMonitor;
......@@ -59,28 +60,30 @@ import org.fortiss.tooling.kernel.ui.service.IMarkerService;
* @version $Rev$
* @ConQAT.Rating GREEN Hash: 97406556E23ADA709853030640FB078F
*/
public class MarkerService implements IMarkerService,
IPersistencyServiceListener, ILightweightLabelDecorator {
public class MarkerService implements IMarkerService, IPersistencyServiceListener,
ILightweightLabelDecorator {
/** ID of this decorator. */
public static final String ID = "org.fortiss.tooling.kernel.ui.internal.MarkerService";
/** Stores the violations for each {@link ITopLevelElement}. */
private final HashMap<ITopLevelElement, CacheEntry> violationCache = new HashMap<ITopLevelElement, CacheEntry>();
private final HashMap<ITopLevelElement, CacheEntry> violationCache =
new HashMap<ITopLevelElement, CacheEntry>();
/** List of listeners. */
private final Set<ILabelProviderListener> labelProviderListeners = new IdentityHashSet<ILabelProviderListener>();
private final Set<ILabelProviderListener> labelProviderListeners =
new IdentityHashSet<ILabelProviderListener>();
/** Stores the UI update job. */
private final UIJob updateUI = new UIJob("Update Model Decorators") {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
LabelProviderChangedEvent changedEvent = new LabelProviderChangedEvent(
MarkerService.this);
for (ILabelProviderListener listener : labelProviderListeners) {
LabelProviderChangedEvent changedEvent =
new LabelProviderChangedEvent(MarkerService.this);
for(ILabelProviderListener listener : labelProviderListeners) {
listener.labelProviderChanged(changedEvent);
}
if (markerView != null) {
if(markerView != null) {
markerView.refresh();
}
return Status.OK_STATUS;
......@@ -97,24 +100,23 @@ public class MarkerService implements IMarkerService,
private MarkerViewPart markerView;
/** Stores the constraint checking job. */
private final Job constraintCheckerJob = new Job(
"Model Constraint Checker Job") {
private final Job constraintCheckerJob = new Job("Model Constraint Checker Job") {
@Override
protected IStatus run(IProgressMonitor monitor) {
ITopLevelElement toBeRefreshed;
// get next element to be refreshed
synchronized (invalidElements) {
if (invalidElements.isEmpty()) {
synchronized(invalidElements) {
if(invalidElements.isEmpty()) {
return Status.OK_STATUS;
}
toBeRefreshed = invalidElements.remove(0);
}
while (toBeRefreshed != null) {
while(toBeRefreshed != null) {
refreshMarkers(toBeRefreshed);
// get next element to be refreshed
synchronized (invalidElements) {
if (invalidElements.isEmpty()) {
synchronized(invalidElements) {
if(invalidElements.isEmpty()) {
toBeRefreshed = null;
} else {
toBeRefreshed = invalidElements.remove(0);
......@@ -127,8 +129,7 @@ public class MarkerService implements IMarkerService,
/** Constructor. */
public MarkerService() {
for (ITopLevelElement element : IPersistencyService.INSTANCE
.getTopLevelElements()) {
for(ITopLevelElement element : IPersistencyService.INSTANCE.getTopLevelElements()) {
invalidElements.add(element);
}
constraintCheckerJob.schedule();
......@@ -142,11 +143,9 @@ public class MarkerService implements IMarkerService,
/** {@inheritDoc} */
@Override
public Collection<IConstraintViolation<? extends EObject>> getViolations(
EObject element) {
ITopLevelElement top = IPersistencyService.INSTANCE
.getTopLevelElementFor(element);
if (top == null) {
public Collection<IConstraintViolation<? extends EObject>> getViolations(EObject element) {
ITopLevelElement top = IPersistencyService.INSTANCE.getTopLevelElementFor(element);
if(top == null) {
return Collections.emptyList();
}
return getCacheEntry(top).getCachedList(element);
......@@ -155,9 +154,8 @@ public class MarkerService implements IMarkerService,
/** {@inheritDoc} */
@Override
public ESeverity getHighestViolationSeverity(EObject element) {
ITopLevelElement top = IPersistencyService.INSTANCE
.getTopLevelElementFor(element);
if (top == null) {
ITopLevelElement top = IPersistencyService.INSTANCE.getTopLevelElementFor(element);
if(top == null) {
return ESeverity.lowest();
}
return getCacheEntry(top).getHighestSeverity(element);
......@@ -165,9 +163,9 @@ public class MarkerService implements IMarkerService,
/** Accesses cache. */
private CacheEntry getCacheEntry(ITopLevelElement element) {
synchronized (violationCache) {
synchronized(violationCache) {
CacheEntry result = violationCache.get(element);
if (result == null) {
if(result == null) {
result = new CacheEntry(element);
violationCache.put(element, result);
}
......@@ -179,10 +177,10 @@ public class MarkerService implements IMarkerService,
@Override
public void refreshMarkers(ITopLevelElement element) {
List<IConstraintViolation<? extends EObject>> checkResult = IConstraintCheckerService.INSTANCE
.performAllConstraintChecksRecursively(element
List<IConstraintViolation<? extends EObject>> checkResult =
IConstraintCheckerService.INSTANCE.performAllConstraintChecksRecursively(element
.getRootModelElement());
synchronized (violationCache) {
synchronized(violationCache) {
CacheEntry entry = getCacheEntry(element);
entry.updateCacheEntries(checkResult);
}
......@@ -211,26 +209,23 @@ public class MarkerService implements IMarkerService,
/** {@inheritDoc} */
@Override
public void decorate(Object element, IDecoration decoration) {
if (element instanceof EObject) {
EObject modelElement = (EObject) element;
if(element instanceof EObject) {
EObject modelElement = (EObject)element;
ESeverity highest = getHighestViolationSeverity(modelElement);
// TODO (FH): https://af3.fortiss.org/issues/388
// use preferences settings here
switch (highest) {
case FATAL:
decoration.addOverlay(ESharedImages.FATAL_OVERLAY
.getImageDescriptor());
break;
case ERROR:
decoration.addOverlay(ESharedImages.ERROR_OVERLAY
.getImageDescriptor());
break;
case WARNING:
decoration.addOverlay(ESharedImages.WARNING_OVERLAY
.getImageDescriptor());
break;
default:
// ignore info and debug
switch(highest) {
case FATAL:
decoration.addOverlay(ESharedImages.FATAL_OVERLAY.getImageDescriptor());
break;
case ERROR:
decoration.addOverlay(ESharedImages.ERROR_OVERLAY.getImageDescriptor());
break;
case WARNING:
decoration.addOverlay(ESharedImages.WARNING_OVERLAY.getImageDescriptor());
break;
default:
// ignore info and debug
}
}
}
......@@ -261,7 +256,7 @@ public class MarkerService implements IMarkerService,
/** Schedules the given element for constraint checking. */
private void doConstraintCheck(ITopLevelElement element) {
synchronized (invalidElements) {
synchronized(invalidElements) {
invalidElements.add(element);
}
constraintCheckerJob.schedule();
......@@ -272,7 +267,7 @@ public class MarkerService implements IMarkerService,
* element.
*/
private void clearViolationCache(ITopLevelElement element) {
synchronized (violationCache) {
synchronized(violationCache) {
violationCache.remove(element);
updateUI.schedule();
}
......@@ -284,10 +279,12 @@ public class MarkerService implements IMarkerService,
private static class CacheEntry {
/** Stores the mapping from model elements to violation lists. */
private final Map<EObject, List<IConstraintViolation<? extends EObject>>> violationsMap = new HashMap<EObject, List<IConstraintViolation<? extends EObject>>>();
private final Map<EObject, List<IConstraintViolation<? extends EObject>>> violationsMap =
new ConcurrentHashMap<EObject, List<IConstraintViolation<? extends EObject>>>();
/** Stores the highest severity value for each cached element. */
private final Map<EObject, ESeverity> highestSeverityMap = new HashMap<EObject, ESeverity>();
private final Map<EObject, ESeverity> highestSeverityMap =
new ConcurrentHashMap<EObject, ESeverity>();
/** Stores the top-level element. */
private ITopLevelElement topElement;
......@@ -297,10 +294,9 @@ public class MarkerService implements IMarkerService,
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
for (EObject eo : violationsMap.keySet()) {
for(EObject eo : violationsMap.keySet()) {
postRefreshNotification(eo);
for (IConstraintViolation<? extends EObject> viol : violationsMap
.get(eo)) {
for(IConstraintViolation<? extends EObject> viol : violationsMap.get(eo)) {
postRefreshNotification(viol.getSource());
}
}
......@@ -316,7 +312,7 @@ public class MarkerService implements IMarkerService,
/** Returns the highest severity for the given element. */
public ESeverity getHighestSeverity(EObject element) {
ESeverity sev = highestSeverityMap.get(element);
if (sev == null) {
if(sev == null) {
return ESeverity.lowest();
}
return sev;
......@@ -327,18 +323,16 @@ public class MarkerService implements IMarkerService,
List<IConstraintViolation<? extends EObject>> newViolations) {
clearCachedLists();
// update cache entries
for (IConstraintViolation<? extends EObject> violation : newViolations) {
for(IConstraintViolation<? extends EObject> violation : newViolations) {
getCachedList(violation.getSource()).add(violation);
}
// fix cached list order
for (EObject eo : violationsMap.keySet()) {
List<IConstraintViolation<? extends EObject>> list = violationsMap
.get(eo);
if (list.isEmpty()) {
for(EObject eo : violationsMap.keySet()) {
List<IConstraintViolation<? extends EObject>> list = violationsMap.get(eo);
if(list.isEmpty()) {
highestSeverityMap.put(eo, ESeverity.lowest());
} else {
Collections.sort(list,
IConstraintViolation.SEVERITY_COMPARATOR);
Collections.sort(list, IConstraintViolation.SEVERITY_COMPARATOR);
highestSeverityMap.put(eo, list.get(0).getSeverity());
}
}
......@@ -351,10 +345,9 @@ public class MarkerService implements IMarkerService,
/** Recursively projects highest severity from children to parents. */
private ESeverity computeHighestSeverity(EObject element) {
ESeverity severity = getHighestSeverity(element);
for (EObject child : element.eContents()) {
for(EObject child : element.eContents()) {
ESeverity childSeverity = computeHighestSeverity(child);
if (ESeverity.getIntSeverity(severity) > ESeverity
.getIntSeverity(childSeverity)) {
if(ESeverity.getIntSeverity(severity) > ESeverity.getIntSeverity(childSeverity)) {
severity = childSeverity;
}
}
......@@ -363,11 +356,9 @@ public class MarkerService implements IMarkerService,
}
/** Returns the cached list instance creating it if necessary. */
private List<IConstraintViolation<? extends EObject>> getCachedList(
EObject element) {
List<IConstraintViolation<? extends EObject>> list = violationsMap
.get(element);
if (list == null) {
private List<IConstraintViolation<? extends EObject>> getCachedList(EObject element) {
List<IConstraintViolation<? extends EObject>> list = violationsMap.get(element);
if(list == null) {
list = new ArrayList<IConstraintViolation<? extends EObject>>();
violationsMap.put(element, list);
}
......@@ -377,11 +368,11 @@ public class MarkerService implements IMarkerService,
/** Returns all violations of the given severity. */
public List<IConstraintViolation<? extends EObject>> getAllViolationsWithSeverity(
ESeverity severity) {
List<IConstraintViolation<? extends EObject>> list = new ArrayList<IConstraintViolation<? extends EObject>>();
for (EObject element : violationsMap.keySet()) {
for (IConstraintViolation<? extends EObject> violation : violationsMap
.get(element)) {
if (violation.getSeverity() == severity) {
List<IConstraintViolation<? extends EObject>> list =
new ArrayList<IConstraintViolation<? extends EObject>>();
for(EObject element : violationsMap.keySet()) {
for(IConstraintViolation<? extends EObject> violation : violationsMap.get(element)) {
if(violation.getSeverity() == severity) {
list.add(violation);
}
}
......@@ -391,11 +382,10 @@ public class MarkerService implements IMarkerService,
/** Clears all cached lists. */
private void clearCachedLists() {
for (List<IConstraintViolation<? extends EObject>> list : violationsMap
.values()) {
for(List<IConstraintViolation<? extends EObject>> list : violationsMap.values()) {
list.clear();
}
for (EObject eo : highestSeverityMap.keySet()) {
for(EObject eo : highestSeverityMap.keySet()) {
highestSeverityMap.put(eo, ESeverity.lowest());
}
}
......@@ -405,43 +395,34 @@ public class MarkerService implements IMarkerService,
@Override
public Collection<IConstraintViolation<? extends EObject>> getAllViolationsWithSeverity(
ESeverity severity) {
List<IConstraintViolation<? extends EObject>> list = new ArrayList<IConstraintViolation<? extends EObject>>();
for (ITopLevelElement top : IPersistencyService.INSTANCE
.getTopLevelElements()) {
list.addAll(getCacheEntry(top).getAllViolationsWithSeverity(
severity));
List<IConstraintViolation<? extends EObject>> list =
new ArrayList<IConstraintViolation<? extends EObject>>();
for(ITopLevelElement top : IPersistencyService.INSTANCE.getTopLevelElements()) {
list.addAll(getCacheEntry(top).getAllViolationsWithSeverity(severity));
}
return list;
}
/** {@inheritDoc} */
@Override
public ImageDescriptor getImageFor(ESeverity severity,
boolean smallDecoration) {
switch (severity) {
case FATAL:
return ToolingKernelUIActivator
.getImageDescriptor("icons/fatal.gif");
case ERROR:
if (smallDecoration) {
return ToolingKernelUIActivator
.getImageDescriptor("icons/error_small.gif");
}
return ToolingKernelUIActivator
.getImageDescriptor("icons/error.gif");
case WARNING:
if (smallDecoration) {
return ToolingKernelUIActivator
.getImageDescriptor("icons/warning_small.gif");
}
return ToolingKernelUIActivator
.getImageDescriptor("icons/warning.gif");
case INFO:
return ToolingKernelUIActivator
.getImageDescriptor("icons/info.gif");
case DEBUG:
return ToolingKernelUIActivator
.getImageDescriptor("icons/debug.gif");
public ImageDescriptor getImageFor(ESeverity severity, boolean smallDecoration) {
switch(severity) {
case FATAL:
return ToolingKernelUIActivator.getImageDescriptor("icons/fatal.gif");
case ERROR:
if(smallDecoration) {
return ToolingKernelUIActivator.getImageDescriptor("icons/error_small.gif");
}
return ToolingKernelUIActivator.getImageDescriptor("icons/error.gif");
case WARNING:
if(smallDecoration) {
return ToolingKernelUIActivator.getImageDescriptor("icons/warning_small.gif");
}
return ToolingKernelUIActivator.getImageDescriptor("icons/warning.gif");
case INFO:
return ToolingKernelUIActivator.getImageDescriptor("icons/info.gif");
case DEBUG:
return ToolingKernelUIActivator.getImageDescriptor("icons/debug.gif");
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment