blob: 95e82cc29604bf58d718767fab7f82323a61936d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 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
* Mickael Istria (Red Hat Inc.) - Bug 488937
*******************************************************************************/
package org.eclipse.core.internal.resources;
import java.text.DateFormat;
import java.util.*;
import java.util.Map.Entry;
import org.eclipse.core.internal.utils.Messages;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.osgi.util.NLS;
/**
* An abstract marker implementation.
* Subclasses must implement the <code>clone</code> method, and
* are free to declare additional field and method members.
* <p>
* Note: Marker objects do not store whether they are "standalone"
* vs. "attached" to the workspace. This information is maintained
* by the workspace.
* </p>
*
* @see IMarker
*/
public class Marker extends PlatformObject implements IMarker {
/** Marker identifier. */
protected long id;
/** Resource with which this marker is associated. */
protected IResource resource;
/**
* Constructs a new marker object.
*/
Marker(IResource resource, long id) {
Assert.isLegal(resource != null);
this.resource = resource;
this.id = id;
}
/**
* Checks the given marker info to ensure that it is not null.
* Throws an exception if it is.
*/
private void checkInfo(MarkerInfo info) throws CoreException {
if (info == null) {
String message = NLS.bind(Messages.resources_markerNotFound, Long.toString(id));
throw new ResourceException(new ResourceStatus(IResourceStatus.MARKER_NOT_FOUND, resource.getFullPath(), message));
}
}
/**
* @see IMarker#delete()
*/
@Override
public void delete() throws CoreException {
final ISchedulingRule rule = getWorkspace().getRuleFactory().markerRule(resource);
try {
getWorkspace().prepareOperation(rule, null);
getWorkspace().beginOperation(true);
getWorkspace().getMarkerManager().removeMarker(getResource(), getId());
} finally {
getWorkspace().endOperation(rule, false);
}
}
/**
* @see IMarker#equals(Object)
*/
@Override
public boolean equals(Object object) {
if (!(object instanceof IMarker))
return false;
IMarker other = (IMarker) object;
return (id == other.getId() && resource.equals(other.getResource()));
}
/**
* @see IMarker#exists()
*/
@Override
public boolean exists() {
return getInfo() != null;
}
/**
* @see IMarker#getAttribute(String)
*/
@Override
public Object getAttribute(String attributeName) throws CoreException {
Assert.isNotNull(attributeName);
MarkerInfo info = getInfo();
checkInfo(info);
return info.getAttribute(attributeName);
}
/**
* @see IMarker#getAttribute(String, int)
*/
@Override
public int getAttribute(String attributeName, int defaultValue) {
Assert.isNotNull(attributeName);
MarkerInfo info = getInfo();
if (info == null)
return defaultValue;
Object value = info.getAttribute(attributeName);
if (value instanceof Integer)
return ((Integer) value).intValue();
return defaultValue;
}
/**
* @see IMarker#getAttribute(String, String)
*/
@Override
public String getAttribute(String attributeName, String defaultValue) {
Assert.isNotNull(attributeName);
MarkerInfo info = getInfo();
if (info == null)
return defaultValue;
Object value = info.getAttribute(attributeName);
if (value instanceof String)
return (String) value;
return defaultValue;
}
/**
* @see IMarker#getAttribute(String, boolean)
*/
@Override
public boolean getAttribute(String attributeName, boolean defaultValue) {
Assert.isNotNull(attributeName);
MarkerInfo info = getInfo();
if (info == null)
return defaultValue;
Object value = info.getAttribute(attributeName);
if (value instanceof Boolean)
return ((Boolean) value).booleanValue();
return defaultValue;
}
/**
* @see IMarker#getAttributes()
*/
@Override
public Map<String, Object> getAttributes() throws CoreException {
MarkerInfo info = getInfo();
checkInfo(info);
return info.getAttributes();
}
/**
* @see IMarker#getAttributes(String[])
*/
@Override
public Object[] getAttributes(String[] attributeNames) throws CoreException {
Assert.isNotNull(attributeNames);
MarkerInfo info = getInfo();
checkInfo(info);
return info.getAttributes(attributeNames);
}
/**
* @see IMarker#getCreationTime()
*/
@Override
public long getCreationTime() throws CoreException {
MarkerInfo info = getInfo();
checkInfo(info);
return info.getCreationTime();
}
/**
* @see IMarker#getId()
*/
@Override
public long getId() {
return id;
}
protected MarkerInfo getInfo() {
return getWorkspace().getMarkerManager().findMarkerInfo(resource, id);
}
/**
* @see IMarker#getResource()
*/
@Override
public IResource getResource() {
return resource;
}
/**
* @see IMarker#getType()
*/
@Override
public String getType() throws CoreException {
MarkerInfo info = getInfo();
checkInfo(info);
return info.getType();
}
/**
* Returns the workspace which manages this marker. Returns
* <code>null</code> if this resource does not have an associated
* resource.
*/
private Workspace getWorkspace() {
return resource == null ? null : (Workspace) resource.getWorkspace();
}
@Override
public int hashCode() {
return (int) id + resource.hashCode();
}
/**
* @see IMarker#isSubtypeOf(String)
*/
@Override
public boolean isSubtypeOf(String type) throws CoreException {
return getWorkspace().getMarkerManager().isSubtype(getType(), type);
}
/**
* @see IMarker#setAttribute(String, int)
*/
@Override
public void setAttribute(String attributeName, int value) throws CoreException {
setAttribute(attributeName, Integer.valueOf(value));
}
/**
* @see IMarker#setAttribute(String, Object)
*/
@Override
public void setAttribute(String attributeName, Object value) throws CoreException {
Assert.isNotNull(attributeName);
Workspace workspace = getWorkspace();
MarkerManager manager = workspace.getMarkerManager();
try {
workspace.prepareOperation(null, null);
workspace.beginOperation(true);
MarkerInfo markerInfo = getInfo();
checkInfo(markerInfo);
//only need to generate delta info if none already
boolean needDelta = !manager.hasDelta(resource.getFullPath(), id);
MarkerInfo oldInfo = needDelta ? (MarkerInfo) markerInfo.clone() : null;
boolean validate = manager.isPersistentType(markerInfo.getType());
markerInfo.setAttribute(attributeName, value, validate);
if (manager.isPersistent(markerInfo))
((Resource) resource).getResourceInfo(false, true).set(ICoreConstants.M_MARKERS_SNAP_DIRTY);
if (needDelta) {
MarkerDelta delta = new MarkerDelta(IResourceDelta.CHANGED, resource, oldInfo);
manager.changedMarkers(resource, new MarkerDelta[] {delta});
}
} finally {
workspace.endOperation(null, false);
}
}
/**
* @see IMarker#setAttribute(String, boolean)
*/
@Override
public void setAttribute(String attributeName, boolean value) throws CoreException {
setAttribute(attributeName, value ? Boolean.TRUE : Boolean.FALSE);
}
/**
* @see IMarker#setAttributes(String[], Object[])
*/
@Override
public void setAttributes(String[] attributeNames, Object[] values) throws CoreException {
Assert.isNotNull(attributeNames);
Assert.isNotNull(values);
Workspace workspace = getWorkspace();
MarkerManager manager = workspace.getMarkerManager();
try {
workspace.prepareOperation(null, null);
workspace.beginOperation(true);
MarkerInfo markerInfo = getInfo();
checkInfo(markerInfo);
//only need to generate delta info if none already
boolean needDelta = !manager.hasDelta(resource.getFullPath(), id);
MarkerInfo oldInfo = needDelta ? (MarkerInfo) markerInfo.clone() : null;
boolean validate = manager.isPersistentType(markerInfo.getType());
markerInfo.setAttributes(attributeNames, values, validate);
if (manager.isPersistent(markerInfo))
((Resource) resource).getResourceInfo(false, true).set(ICoreConstants.M_MARKERS_SNAP_DIRTY);
if (needDelta) {
MarkerDelta delta = new MarkerDelta(IResourceDelta.CHANGED, resource, oldInfo);
manager.changedMarkers(resource, new MarkerDelta[] {delta});
}
} finally {
workspace.endOperation(null, false);
}
}
/**
* @see IMarker#setAttributes(Map)
*/
@Override
public void setAttributes(Map<String, ? extends Object> values) throws CoreException {
Workspace workspace = getWorkspace();
MarkerManager manager = workspace.getMarkerManager();
try {
workspace.prepareOperation(null, null);
workspace.beginOperation(true);
MarkerInfo markerInfo = getInfo();
checkInfo(markerInfo);
//only need to generate delta info if none already
boolean needDelta = !manager.hasDelta(resource.getFullPath(), id);
MarkerInfo oldInfo = needDelta ? (MarkerInfo) markerInfo.clone() : null;
boolean validate = manager.isPersistentType(markerInfo.getType());
markerInfo.setAttributes(values, validate);
if (manager.isPersistent(markerInfo))
((Resource) resource).getResourceInfo(false, true).set(ICoreConstants.M_MARKERS_SNAP_DIRTY);
if (needDelta) {
MarkerDelta delta = new MarkerDelta(IResourceDelta.CHANGED, resource, oldInfo);
manager.changedMarkers(resource, new MarkerDelta[] {delta});
}
} finally {
workspace.endOperation(null, false);
}
}
/** For debugging only */
@Override
public String toString() {
StringBuilder sb = new StringBuilder("Marker ["); //$NON-NLS-1$
sb.append("on: ").append(resource.getFullPath()); //$NON-NLS-1$
MarkerInfo info = getInfo();
if (info == null) {
sb.append(", not found]"); //$NON-NLS-1$
return sb.toString();
}
sb.append(", id: ").append(info.getId()); //$NON-NLS-1$
sb.append(", type: ").append(info.getType()); //$NON-NLS-1$
Map<String, Object> attributes = info.getAttributes();
if (attributes != null) {
TreeMap<String, Object> tm = new TreeMap<>(attributes);
Set<Entry<String, Object>> set = tm.entrySet();
if (!set.isEmpty()) {
sb.append(", attributes: ["); //$NON-NLS-1$
for (Entry<String, Object> entry : set) {
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append(", "); //$NON-NLS-1$ //$NON-NLS-2$
}
sb.setLength(sb.length() - 2);
sb.append(']');
}
}
sb.append(", created: ").append(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(new Date(info.getCreationTime()))); //$NON-NLS-1$
sb.append(']');
return sb.toString();
}
}