/*****************************************************************************
* Copyright (c) 2006-2013, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text of
* such license is available at www.eclipse.org.
*****************************************************************************/
package org.eclipse.buckminster.core.cspec;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.buckminster.core.cspec.model.ComponentRequest;
import org.eclipse.buckminster.core.query.IAdvisorNode;
import org.eclipse.buckminster.sax.Utils;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.equinox.p2.metadata.VersionRange;
public class QualifiedDependency {
private final ComponentRequest request;
private final Set<String> attributes;
public QualifiedDependency(ComponentRequest request, Collection<String> attributes) {
this.request = request;
this.attributes = Utils.createUnmodifiableSet(attributes);
}
public QualifiedDependency applyAdvice(IAdvisorNode advice) {
if (advice == null)
return this;
boolean change = false;
ComponentRequest rq = request;
VersionRange dsg = advice.getVersionOverride();
if (dsg != null) {
change = true;
rq = new ComponentRequest(rq.getName(), rq.getComponentTypeID(), dsg, rq.getFilter());
}
Collection<String> attrs = advice.getAttributes();
if (attrs.size() > 0) {
change = true;
if (advice.isPrune() && attributes.size() > 0 && !attributes.containsAll(attrs)) {
HashSet<String> pruned = new HashSet<String>();
for (String attrName : attrs)
if (attributes.contains(attrName))
pruned.add(attrName);
if (pruned.size() == 0)
//
// We don't want anything from this cspec
//
return null;
attrs = pruned;
}
} else
attrs = attributes;
return change ? new QualifiedDependency(rq, attrs) : this;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof QualifiedDependency))
return false;
QualifiedDependency that = (QualifiedDependency) o;
return request.equals(that.request) && attributes.equals(that.attributes);
}
public final Set<String> getAttributeNames() {
return attributes;
}
public final ComponentRequest getRequest() {
return request;
}
public boolean hasAllAttributes(Collection<String> attrs) {
return attributes.containsAll(attrs);
}
public boolean hasAllAttributes(String[] attrs) {
return hasAllAttributes(Arrays.asList(attrs));
}
@Override
public int hashCode() {
return request.hashCode() * 31 + attributes.hashCode();
}
/**
* Merges the version designator and the attributes of the new dependency
* with the current one. The method will return this instance if the merge
* is a no-op.
*
* @param newQDep
* the new qualified depenency
* @return This instance or a new instance if modifications where necessary.
* @throws CoreException
* if the qualification is in conflict with the previously
* defined dependency with respect to its version designator
*/
public QualifiedDependency mergeDependency(QualifiedDependency newQDep) throws CoreException {
Set<String> attrs = newQDep.getAttributeNames();
ComponentRequest newRequest = request.mergeDesignator(newQDep.getRequest());
if (newRequest == request && hasAllAttributes(attrs))
return this;
Set<String> allAttrs;
if (attributes.size() == 0)
allAttrs = attrs;
else if (attrs.size() == 0)
allAttrs = attributes;
else {
allAttrs = new HashSet<String>(attributes);
allAttrs.addAll(attrs);
}
return new QualifiedDependency(newRequest, allAttrs);
}
@Override
public String toString() {
if (attributes.isEmpty())
return request.toString();
StringBuilder bld = new StringBuilder(request.toString());
bld.append('[');
Iterator<String> attrs = attributes.iterator();
bld.append(attrs.next());
while (attrs.hasNext()) {
bld.append(',');
bld.append(attrs.next());
}
bld.append(']');
return bld.toString();
}
}