/*******************************************************************************
* Copyright (c) 2000, 2005 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
*******************************************************************************/
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 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 merge(Map oldChanges, Map 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 it= newChanges.keySet().iterator(); it.hasNext();) {
IPath key= (IPath)it.next();
MarkerSet oldSet= (MarkerSet)oldChanges.get(key);
MarkerSet newSet= (MarkerSet)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;
}
}