| /******************************************************************************* |
| * Copyright (c) 2000, 2015 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * James Blackburn (Broadcom Corp.) - ongoing development |
| *******************************************************************************/ |
| package org.eclipse.core.internal.resources; |
| |
| import java.util.Map; |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.IPath; |
| |
| /** |
| * @see IMarkerDelta |
| */ |
| public class MarkerDelta implements IMarkerDelta, IMarkerSetElement { |
| protected int kind; |
| protected IResource resource; |
| protected MarkerInfo info; |
| |
| /** |
| * Creates a new marker delta. |
| */ |
| public MarkerDelta(int kind, IResource resource, MarkerInfo info) { |
| this.kind = kind; |
| this.resource = resource; |
| this.info = info; |
| } |
| |
| @Override |
| public Object getAttribute(String attributeName) { |
| return info.getAttribute(attributeName); |
| } |
| |
| @Override |
| public int getAttribute(String attributeName, int defaultValue) { |
| Object value = info.getAttribute(attributeName); |
| if (value instanceof Integer) |
| return ((Integer) value).intValue(); |
| return defaultValue; |
| } |
| |
| @Override |
| public String getAttribute(String attributeName, String defaultValue) { |
| Object value = info.getAttribute(attributeName); |
| if (value instanceof String) |
| return (String) value; |
| return defaultValue; |
| } |
| |
| @Override |
| public boolean getAttribute(String attributeName, boolean defaultValue) { |
| Object value = info.getAttribute(attributeName); |
| if (value instanceof Boolean) |
| return ((Boolean) value).booleanValue(); |
| return defaultValue; |
| } |
| |
| @Override |
| public Map<String, Object> getAttributes() { |
| return info.getAttributes(); |
| } |
| |
| @Override |
| public Object[] getAttributes(String[] attributeNames) { |
| return info.getAttributes(attributeNames); |
| } |
| |
| @Override |
| public long getId() { |
| return info.getId(); |
| } |
| |
| @Override |
| public int getKind() { |
| return kind; |
| } |
| |
| @Override |
| public IMarker getMarker() { |
| return new Marker(resource, getId()); |
| } |
| |
| @Override |
| public IResource getResource() { |
| return resource; |
| } |
| |
| @Override |
| public String getType() { |
| return info.getType(); |
| } |
| |
| @Override |
| public boolean isSubtypeOf(String superType) { |
| return ((Workspace) getResource().getWorkspace()).getMarkerManager().isSubtype(getType(), superType); |
| } |
| |
| /** |
| * Merge two Maps of (IPath->MarkerSet) representing changes. Use the old map |
| * to store the result so we don't have to build a new map to return. |
| */ |
| public static Map<IPath, MarkerSet> merge(Map<IPath, MarkerSet> oldChanges, Map<IPath, MarkerSet> newChanges) { |
| if (oldChanges == null) |
| //don't worry about copying since the new changes are no longer used |
| return newChanges; |
| if (newChanges == null) |
| return oldChanges; |
| for (Map.Entry<IPath, MarkerSet> newEntry : newChanges.entrySet()) { |
| IPath key = newEntry.getKey(); |
| MarkerSet oldSet = oldChanges.get(key); |
| MarkerSet newSet = newEntry.getValue(); |
| if (oldSet == null) |
| oldChanges.put(key, newSet); |
| else |
| merge(oldSet, newSet.elements()); |
| } |
| return oldChanges; |
| } |
| |
| /** |
| * Merge two sets of marker changes. Both sets must be on the same resource. Use the original set |
| * of changes to store the result so we don't have to build a completely different set to return. |
| * |
| * <pre> |
| * add + add = N/A |
| * add + remove = nothing (no delta) |
| * add + change = add |
| * remove + add = N/A |
| * remove + remove = N/A |
| * remove + change = N/A |
| * change + add = N/A |
| * change + change = change (note: info held onto by the marker delta should be that of the oldest change, and not replaced when composed) |
| * change + remove = remove (note: info held onto by the marker delta should be that of the oldest change, and not replaced when changed to a remove) |
| * </pre> |
| */ |
| protected static MarkerSet merge(MarkerSet oldChanges, IMarkerSetElement[] newChanges) { |
| if (oldChanges == null) { |
| MarkerSet result = new MarkerSet(newChanges.length); |
| for (IMarkerSetElement newChange : newChanges) |
| result.add(newChange); |
| return result; |
| } |
| if (newChanges == null) |
| return oldChanges; |
| |
| for (IMarkerSetElement newChange : newChanges) { |
| MarkerDelta newDelta = (MarkerDelta) newChange; |
| MarkerDelta oldDelta = (MarkerDelta) oldChanges.get(newDelta.getId()); |
| if (oldDelta == null) { |
| oldChanges.add(newDelta); |
| continue; |
| } |
| switch (oldDelta.getKind()) { |
| case IResourceDelta.ADDED : |
| switch (newDelta.getKind()) { |
| case IResourceDelta.ADDED : |
| // add + add = N/A |
| break; |
| case IResourceDelta.REMOVED : |
| // add + remove = nothing |
| // Remove the original ADD delta. |
| oldChanges.remove(oldDelta); |
| break; |
| case IResourceDelta.CHANGED : |
| // add + change = add |
| break; |
| } |
| break; |
| case IResourceDelta.REMOVED : |
| switch (newDelta.getKind()) { |
| case IResourceDelta.ADDED : |
| // remove + add = N/A |
| break; |
| case IResourceDelta.REMOVED : |
| // remove + remove = N/A |
| break; |
| case IResourceDelta.CHANGED : |
| // remove + change = N/A |
| break; |
| } |
| break; |
| case IResourceDelta.CHANGED : |
| switch (newDelta.getKind()) { |
| case IResourceDelta.ADDED : |
| // change + add = N/A |
| break; |
| case IResourceDelta.REMOVED : |
| // change + remove = remove |
| // Change the delta kind. |
| oldDelta.setKind(IResourceDelta.REMOVED); |
| break; |
| case IResourceDelta.CHANGED : |
| // change + change = change |
| break; |
| } |
| break; |
| } |
| } |
| return oldChanges; |
| } |
| |
| private void setKind(int kind) { |
| this.kind = kind; |
| } |
| } |