All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bndtools.model.resolution.CapReqMapContentProvider Maven / Gradle / Ivy

The newest version!
package bndtools.model.resolution;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.framework.namespace.PackageNamespace;
import org.osgi.resource.Capability;

import aQute.bnd.unmodifiable.Sets;
import aQute.libg.glob.Glob;

public class CapReqMapContentProvider implements ITreeContentProvider {

	private static final Object[]		EMPTY		= new Object[0];

	private static final Set	NAMESPACES	= Sets.of(BundleNamespace.BUNDLE_NAMESPACE,
		IdentityNamespace.IDENTITY_NAMESPACE, HostNamespace.HOST_NAMESPACE, PackageNamespace.PACKAGE_NAMESPACE);

	private final Comparator	comparator	= new CapReqComparator();

	private String						wildcardFilter	= null;

	@Override
	public void dispose() {}

	@Override
	public void inputChanged(Viewer viewer, Object oldValue, Object newValue) {}

	@Override
	public Object[] getElements(Object input) {
		List arrays = new LinkedList<>();

		@SuppressWarnings("unchecked")
		Map> map = (Map>) input;

		// Add entries for our preferred ordering of namespaces
		for (String namespace : NAMESPACES) {
			List listForNs = map.get(namespace);
			if (listForNs != null) {
				Object[] array = listForNs.toArray();
				Arrays.sort(array, comparator);
				arrays.add(array);
			}
		}

		// Now the rest in any order
		for (Entry> entry : map.entrySet()) {
			// Skip if namespace is a member of the namespaces we have already
			// added.
			if (NAMESPACES.contains(entry.getKey()))
				continue;

			List listForNs = entry.getValue();
			Object[] array = listForNs.toArray();
			Arrays.sort(array, comparator);
			arrays.add(array);
		}

		return filter(flatten(arrays));
	}

	private Object[] flatten(List arrays) {
		// Iterate over once to count the lengths
		int length = 0;
		for (Object[] array : arrays) {
			length += array.length;
		}
		Object[] result = new Object[length];

		// Iterate again to flatten out the arrays
		int position = 0;
		for (Object[] array : arrays) {
			System.arraycopy(array, 0, result, position, array.length);
			position += array.length;
		}
		return result;
	}

	@Override
	public Object getParent(Object object) {
		return null;
	}

	@Override
	public boolean hasChildren(Object object) {
		boolean children = false;

		if (object instanceof RequirementWrapper) {
			RequirementWrapper rw = (RequirementWrapper) object;
			children = rw.requirers != null && !rw.requirers.isEmpty();
		}

		return children;
	}

	@Override
	public Object[] getChildren(Object parent) {
		Object[] result = EMPTY;
		if (parent instanceof RequirementWrapper) {
			Collection requirers = ((RequirementWrapper) parent).requirers;
			if (requirers != null)
				result = requirers.toArray();
		}
		return result;
	}

	public void setFilter(String filterString) {
		if (filterString == null || filterString.length() == 0 || filterString.trim()
			.equals("*"))
			wildcardFilter = null;
		else
			wildcardFilter = "*" + filterString.trim() + "*";

	}

	private Object[] filter(Object[] array) {
		List filteredResults = new ArrayList<>();
		if (wildcardFilter == null || wildcardFilter.equals("*") || wildcardFilter.equals("")) {
			return array;
		} else {
			String[] split = wildcardFilter.split("\\s+");
			Glob globs[] = new Glob[split.length];
			for (int i = 0; i < split.length; i++) {
				globs[i] = new Glob(split[i].toLowerCase());
			}

			// parallel search
			Arrays.stream(array).parallel().forEach(obj -> {

				if (obj instanceof RequirementWrapper rw) {

					for (Glob g : globs) {
							if (g.matcher(RequirementWrapperLabelProvider.tooltipText(rw)
								.toLowerCase())
							.find()) {
							filteredResults.add(obj);
							return;
						}
					}
				}
				else if (obj instanceof Capability cap) {

					for (Glob g : globs) {
							if (g.matcher(CapabilityLabelProvider.tooltipText(cap)
								.toLowerCase())
							.find()) {
							filteredResults.add(obj);
							return;
						}
					}
				}

			});

		}

		// sort because parallel search causes random ordering
		filteredResults.sort(comparator);

		return filteredResults.toArray();
	}

}