/******************************************************************************* * Copyright (c) 2000, 2015 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 - Initial API and implementation *******************************************************************************/ package org.eclipse.core.tools.resources; import java.util.*; import org.eclipse.core.internal.resources.*; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.core.tools.*; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.jface.viewers.Viewer; import org.eclipse.osgi.util.NLS; /** * Constructs a tree made of <code>TreeContentProviderNode</code>, representing * several details about resources. * Details include: * <ul> * <li>resource's full path;</li> * <li>content ID;</li> * <li>node ID;</li> * <li>resource type;</li> * <li>local sync info;</li> * <li>resource info flags;</li> * <li>markers' type and attributes;</li> * <li>sync info;</li> * <li>session properties;</li> * <li>persistent properties.</li> * </ul> * * @see org.eclipse.core.tools.TreeContentProviderNode */ public class ResourceContentProvider extends AbstractTreeContentProvider { /** * The maximum number of bytes to be shown for sync info */ private final static int MAX_SYNC_INFO_BYTES = 8; /** * Collects resource info. Calls all other <code>extract...</code> methods. * * @param selectedResource the resource object from where to extract information */ protected void extractInfo(IResource selectedResource) { if (!(selectedResource instanceof Resource)) { String message = NLS.bind(Messages.resource_error_unknown_resource_impl, selectedResource.getClass().getName()); getRootNode().addChild(message); return; } Resource resource = (Resource) selectedResource; ResourceInfo info = resource.getResourceInfo(true, false); // Resource#getResourceInfo may return null when the resource // does not exist anymore. In this case, we just ignore it. if (info == null) return; extractBasicInfo(resource, info); extractFlags(info); extractContentDescription(resource); extractMarkersInfo(resource, info); extractSyncInfo(info); extractPersistentProperties(resource); extractSessionProperties(resource); } /** * Collects persistent properties information. * * @param resource the resource object from where to extract information */ protected void extractPersistentProperties(IResource resource) { try { Map<QualifiedName, String> properties = ((Workspace) ResourcesPlugin.getWorkspace()).getPropertyManager().getProperties(resource); if (properties.isEmpty()) return; // creates a node for persistent properties and populates it TreeContentProviderNode propertiesRootNode = createNode(Messages.resource_persistent_properties); getRootNode().addChild(propertiesRootNode); for (Map.Entry<QualifiedName, String> entry : properties.entrySet()) { propertiesRootNode.addChild(createNode(entry.getKey().toString(), entry.getValue())); } } catch (CoreException ce) { getRootNode().addChild(createNode(NLS.bind(Messages.resource_error_stored_properties, ce.toString()))); } } /** * Collects session properties information. * * @param resource the resource object from where to extract information */ protected void extractSessionProperties(IResource resource) { // retrieves all session properties for the selected resource Map<QualifiedName, Object> properties = org.eclipse.core.internal.resources.SpySupport.getSessionProperties(resource); if (properties == null || properties.size() == 0) return; // creates a node for session properties and populates it TreeContentProviderNode propertiesRootNode = createNode(Messages.resource_session_properties); getRootNode().addChild(propertiesRootNode); for (Map.Entry<QualifiedName, Object> entry : properties.entrySet()) { propertiesRootNode.addChild(createNode(entry.getKey().toString(), entry.getValue())); } } /** * Extracts basic resource info. * * @param resource the resource object from where to extract information * @param info the resource info object from where to extract information */ protected void extractBasicInfo(IResource resource, ResourceInfo info) { // extracts information from IResource IPath resourcePath = resource.getFullPath(); long id = info.getContentId(); String type = null; switch (resource.getType()) { case IResource.FILE : type = Messages.resource_file; break; case IResource.FOLDER : type = Messages.resource_folder; break; case IResource.PROJECT : type = Messages.resource_project; break; case IResource.ROOT : type = Messages.resource_root; break; } // extracts information from ResourceInfo long localSyncInfo = info.getLocalSyncInfo(); long nodeId = info.getNodeId(); // creates a root node for each basic information getRootNode().addChild(createNode(Messages.resource_full_path, resourcePath)); getRootNode().addChild(createNode(Messages.resource_content_id, Long.toString(id))); getRootNode().addChild(createNode(Messages.resource_type, type)); getRootNode().addChild(createNode(Messages.resource_node_id, Long.toString(nodeId))); getRootNode().addChild(createNode(Messages.resource_local_sync_info, Long.toString(localSyncInfo))); } /** * Extracts flags from the resource info object, building a 'Flags' * subtree in the resource details' tree. * * @param info the resource info object from where to extract information */ protected void extractFlags(ResourceInfo info) { // extract flags'values for the resource info object boolean isOpen = info.isSet(ICoreConstants.M_OPEN); boolean localExists = info.isSet(ICoreConstants.M_LOCAL_EXISTS); boolean isPhantom = info.isSet(ICoreConstants.M_PHANTOM); boolean isUsed = info.isSet(ICoreConstants.M_USED); boolean isDerived = info.isSet(ICoreConstants.M_DERIVED); boolean isTeamPrivateMember = info.isSet(ICoreConstants.M_TEAM_PRIVATE_MEMBER); boolean isMarkersSnapDirty = info.isSet(ICoreConstants.M_MARKERS_SNAP_DIRTY); boolean isSyncInfoSnapDirty = info.isSet(ICoreConstants.M_SYNCINFO_SNAP_DIRTY); boolean noContentDescription = info.isSet(ICoreConstants.M_NO_CONTENT_DESCRIPTION); boolean defaultContentDescription = info.isSet(ICoreConstants.M_DEFAULT_CONTENT_DESCRIPTION); boolean isHidden = info.isSet(ICoreConstants.M_HIDDEN); // creates a node for flags TreeContentProviderNode flagsParentNode = createNode(Messages.resource_flags); getRootNode().addChild(flagsParentNode); // creates a child node in "Flags" node for each basic information flagsParentNode.addChild(createNode(Messages.resource_open, Boolean.valueOf(isOpen))); flagsParentNode.addChild(createNode(Messages.resource_local_exists, Boolean.valueOf(localExists))); flagsParentNode.addChild(createNode(Messages.resource_phantom, Boolean.valueOf(isPhantom))); flagsParentNode.addChild(createNode(Messages.resource_used, Boolean.valueOf(isUsed))); flagsParentNode.addChild(createNode(Messages.resource_derived, Boolean.valueOf(isDerived))); flagsParentNode.addChild(createNode(Messages.resource_team_private, Boolean.valueOf(isTeamPrivateMember))); flagsParentNode.addChild(createNode(Messages.resource_markers_snap_dirty, Boolean.valueOf(isMarkersSnapDirty))); flagsParentNode.addChild(createNode(Messages.resource_sync_info_snap_dirty, Boolean.valueOf(isSyncInfoSnapDirty))); flagsParentNode.addChild(createNode(Messages.resource_no_content_description, Boolean.valueOf(noContentDescription))); flagsParentNode.addChild(createNode(Messages.resource_default_content_description, Boolean.valueOf(defaultContentDescription))); flagsParentNode.addChild(createNode(Messages.resource_hidden, Boolean.valueOf(isHidden))); } protected void extractContentDescription(Resource resource) { if (resource.getType() != IResource.FILE) return; File file = (File) resource; // creates a node for flags try { boolean cached = org.eclipse.core.internal.resources.SpySupport.isContentDescriptionCached(file); String description = file.getContentDescription() + " (" + NLS.bind(Messages.resource_content_description_from_cache, Boolean.toString(cached)) + ")"; //$NON-NLS-1$//$NON-NLS-2$ TreeContentProviderNode contentDescriptionNode = createNode(Messages.resource_content_description, description); getRootNode().addChild(contentDescriptionNode); } catch (CoreException ce) { // in the case of a CoreException, just present it as node getRootNode().addChild(createNode(NLS.bind(Messages.resource_error_content_description, ce.toString()))); } } /** * Extracts from resource info object all information regarding markers, * building a 'Markers' subtree in the resource details tree. * * @param resource the resource object from where to extract information * @param info the resource info object from where to extract information */ protected void extractMarkersInfo(IResource resource, ResourceInfo info) { MarkerSet markerSet = info.getMarkers(); if (markerSet == null) return; IMarkerSetElement[] markerSetElements = markerSet.elements(); if (markerSetElements.length == 0) return; // creates a root node for all markers TreeContentProviderNode markersParentNode = createNode(Messages.resource_markers); getRootNode().addChild(markersParentNode); int markerSetSize = markerSetElements.length; for (int i = 0; i < markerSetSize; i++) { try { long markerID = markerSetElements[i].getId(); IMarker marker = resource.getMarker(markerID); // creates a marker node String id = " [id = " + marker.getId() + "]"; //$NON-NLS-1$//$NON-NLS-2$ TreeContentProviderNode markerNode = createNode(marker.getType() + id); markersParentNode.addChild(markerNode); extractMarkerAttributes(markerNode, marker); } catch (CoreException ce) { // in the case of a CoreException, just present it as node markersParentNode.addChild(createNode(NLS.bind(Messages.resource_error_marker, ce.toString()))); } } } /** * Retrieves all attributes from a marker, adding them as sub-nodes in the * marker's node. * * @param markerNode the marker's node * @param marker the marker object * @throws CoreException */ protected void extractMarkerAttributes(TreeContentProviderNode markerNode, IMarker marker) throws CoreException { Map<String, Object> attributes = marker.getAttributes(); if (attributes == null || attributes.size() == 0) return; // create a node (under markerNode) for each attribute found for (Map.Entry<String, Object> mapEntry : attributes.entrySet()) { String attributeName = mapEntry.getKey(); Object attributeValue = mapEntry.getValue(); // adds each attribute as a subnode under // this marker's node markerNode.addChild(createNode(attributeName, attributeValue)); } // attributes will be ordered by attribute name markerNode.sort(); } /** * Extracts from the resource info object all information related to VCM, * building a 'Sync Info' subtree in the resource details tree. * * @param info the resource info object from where to extract information */ protected void extractSyncInfo(ResourceInfo info) { Map<QualifiedName, Object> syncInfo = info.getSyncInfo(true); if (syncInfo == null || syncInfo.isEmpty()) return; // creates a root node for all sync info TreeContentProviderNode syncInfoParentNode = createNode(Messages.resource_sync_info); getRootNode().addChild(syncInfoParentNode); for (Map.Entry<QualifiedName, Object> entry : syncInfo.entrySet()) { // creates a sync info node String name = entry.getKey().toString(); String value = ByteUtil.byteArrayToString((byte[]) entry.getValue(), MAX_SYNC_INFO_BYTES); syncInfoParentNode.addChild(createNode(name, value)); } } /** * Reconstructs this content provider data model upon the provided input object. * * @param input the new input object - must not be null */ @Override protected void rebuild(Viewer viewer, final Object input) { SafeRunner.run(new SafeRunnable() { @Override public void run() throws Exception { extractInfo((IResource) input); } }); } /** * Returns true if the input is a resource. * * @param input an input object * @see org.eclipse.core.tools.AbstractTreeContentProvider#acceptInput(java.lang.Object) */ @Override protected boolean acceptInput(Object input) { return input instanceof IResource; } }