/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * James Blackburn (Broadcom Corp.) - ongoing development *******************************************************************************/ package org.eclipse.core.internal.resources; import java.util.Iterator; 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; } /* (non-Javadoc) * @see IMarkerDelta#getAttribute(String) */ public Object getAttribute(String attributeName) { return info.getAttribute(attributeName); } /* (non-Javadoc) * @see IMarkerDelta#getAttribute(String, int) */ public int getAttribute(String attributeName, int defaultValue) { Object value = info.getAttribute(attributeName); if (value instanceof Integer) return ((Integer) value).intValue(); return defaultValue; } /* (non-Javadoc) * @see IMarkerDelta#getAttribute(String, String) */ public String getAttribute(String attributeName, String defaultValue) { Object value = info.getAttribute(attributeName); if (value instanceof String) return (String) value; return defaultValue; } /* (non-Javadoc) * @see IMarkerDelta#getAttribute(String, boolean) */ public boolean getAttribute(String attributeName, boolean defaultValue) { Object value = info.getAttribute(attributeName); if (value instanceof Boolean) return ((Boolean) value).booleanValue(); return defaultValue; } /* (non-Javadoc) * @see IMarkerDelta#getAttributes() */ public Map<String, Object> getAttributes() { return info.getAttributes(); } /* (non-Javadoc) * @see IMarkerDelta#getAttributes(String[]) */ public Object[] getAttributes(String[] attributeNames) { return info.getAttributes(attributeNames); } /* (non-Javadoc) * @see IMarkerDelta#getId() */ public long getId() { return info.getId(); } /* (non-Javadoc) * @see IMarkerDelta#getKind() */ public int getKind() { return kind; } /* (non-Javadoc) * @see IMarkerDelta#getMarker() */ public IMarker getMarker() { return new Marker(resource, getId()); } /* (non-Javadoc) * @see IMarkerDelta#getResource() */ public IResource getResource() { return resource; } /* (non-Javadoc) * @see IMarkerDelta#getType() */ public String getType() { return info.getType(); } /* (non-Javadoc) * @see IMarkerDelta#isSubtypeOf(String) */ 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 (Iterator<IPath> it = newChanges.keySet().iterator(); it.hasNext();) { IPath key = it.next(); MarkerSet oldSet = oldChanges.get(key); MarkerSet newSet = newChanges.get(key); 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. * * 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) */ protected static MarkerSet merge(MarkerSet oldChanges, IMarkerSetElement[] newChanges) { if (oldChanges == null) { MarkerSet result = new MarkerSet(newChanges.length); for (int i = 0; i < newChanges.length; i++) result.add(newChanges[i]); return result; } if (newChanges == null) return oldChanges; for (int i = 0; i < newChanges.length; i++) { MarkerDelta newDelta = (MarkerDelta) newChanges[i]; 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; } }