blob: 15d44ad51230e5fb8684dd9096d75627bb766395 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 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
*******************************************************************************/
package org.eclipse.team.internal.ccvs.ui.actions;
import java.util.*;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.team.internal.ccvs.core.ICVSResource;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ui.Utils;
/**
* This class represents a selection for a set of CVS actions.
*/
public class CVSActionSelectionProperties {
// Use a weak hash map so that the properties ae collected when the selection is no longer referenced
private static Map<IStructuredSelection, CVSActionSelectionProperties> selectionProperties = new WeakHashMap<>();
private Object[] selection;
private Map<String, Object> properties = new HashMap<>();
private static final String SELECTED_RESOURCES = "selectedResources"; //$NON-NLS-1$
private static final String NONOVERLAPPING_SELECTED_RESOURCES = "nonoverlappingSelectedResources"; //$NON-NLS-1$
private static final String CVS_RESOURCE_MAP = "cvsResourceMap"; //$NON-NLS-1$
public static CVSActionSelectionProperties getProperties(IStructuredSelection selection) {
if (selection == null) return null;
CVSActionSelectionProperties props = selectionProperties.get(selection);
if (props == null) {
props = new CVSActionSelectionProperties(selection);
selectionProperties.put(selection, props);
}
return props;
}
public CVSActionSelectionProperties(IStructuredSelection selection) {
// Copy the selection so that the WeakHashMap will not think the seleciton used for the key is still in use
this.selection = selection.toArray();
}
public void put(String key, Object value) {
properties.put(key, value);
}
public Object get(String key) {
return properties.get(key);
}
public IResource[] getAllSelectedResources() {
IResource[] resources = (IResource[])get(SELECTED_RESOURCES);
if (resources == null) {
resources = getResources(selection);
put(SELECTED_RESOURCES, resources);
}
return resources;
}
/*
* This method gets the resources from the given objects.
* It does so in a manner that is consistent with how the workbench does it.
* Tha is, it first uses IContributionResourceAdapter, then IResource,
* then ResourceMapping.
*/
private IResource[] getResources(Object[] objects) {
return Utils.getContributedResources(objects);
}
public IResource[] getNonoverlappingSelectedResources() {
IResource[] resources = (IResource[])get(NONOVERLAPPING_SELECTED_RESOURCES);
if (resources == null) {
resources = getNonOverlapping(getAllSelectedResources());
put (NONOVERLAPPING_SELECTED_RESOURCES, resources);
}
return resources;
}
public ICVSResource getCVSResourceFor(IResource resource) {
Map map = (Map)get(CVS_RESOURCE_MAP);
if (map == null) {
map = new HashMap();
put(CVS_RESOURCE_MAP, map);
}
ICVSResource cvsResource = (ICVSResource)map.get(resource);
if (cvsResource == null) {
cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
map.put(resource, cvsResource);
}
return cvsResource;
}
/**
* Method getNonOverlapping ensures that a resource is not covered more than once.
* @param resources
* @return IResource[]
*/
public static IResource[] getNonOverlapping(IResource[] resources) {
if (resources == null || resources.length == 0 || resources.length == 1) {
return resources;
}
// Sort the resources so the shortest paths are first
List<IResource> sorted = new ArrayList<>();
sorted.addAll(Arrays.asList(resources));
Collections.sort(sorted, new Comparator<IResource>() {
@Override
public int compare(IResource resource0, IResource resource1) {
return resource0.getFullPath().segmentCount() - resource1.getFullPath().segmentCount();
}
@Override
public boolean equals(Object arg0) {
return false;
}
});
// Collect all non-overlapping resources
List<IPath> coveredPaths = new ArrayList<>();
for (Iterator iter = sorted.iterator(); iter.hasNext();) {
IResource resource = (IResource) iter.next();
IPath resourceFullPath = resource.getFullPath();
boolean covered = false;
for (Iterator it = coveredPaths.iterator(); it.hasNext();) {
IPath path = (IPath) it.next();
if(path.isPrefixOf(resourceFullPath)) {
covered = true;
}
}
if (covered) {
// if the resource is covered by a parent, remove it
iter.remove();
} else {
// if the resource is a non-covered folder, add it to the covered paths
if (resource.getType() == IResource.FOLDER) {
coveredPaths.add(resource.getFullPath());
}
}
}
return sorted.toArray(new IResource[sorted.size()]);
}
}