/*******************************************************************************
* 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.resolver;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.eclipse.buckminster.core.CorePlugin;
import org.eclipse.buckminster.core.RMContext;
import org.eclipse.buckminster.core.cspec.IComponentIdentifier;
import org.eclipse.buckminster.core.cspec.IComponentRequest;
import org.eclipse.buckminster.core.cspec.IGenerator;
import org.eclipse.buckminster.core.cspec.model.CSpec;
import org.eclipse.buckminster.core.cspec.model.ComponentName;
import org.eclipse.buckminster.core.cspec.model.ComponentRequest;
import org.eclipse.buckminster.core.helpers.UnmodifiableMapUnion;
import org.eclipse.buckminster.core.metadata.model.GeneratorNode;
import org.eclipse.buckminster.core.mspec.model.MaterializationSpec;
import org.eclipse.buckminster.core.query.IAdvisorNode;
import org.eclipse.buckminster.core.query.model.ComponentQuery;
import org.eclipse.buckminster.sax.Utils;
import org.eclipse.core.runtime.IStatus;
/**
* @author Thomas Hallgren
*/
public class ResolutionContext extends RMContext implements IResolverBackchannel {
private final ComponentQuery componentQuery;
private HashMap<IComponentIdentifier, GeneratorNode> generators;
private final ResolutionContext parentContext;
private final HashMap<ComponentRequest, List<ResolverDecision>> decisionLog = new HashMap<ComponentRequest, List<ResolverDecision>>();
public ResolutionContext(ComponentQuery componentQuery) {
this(componentQuery, null);
}
public ResolutionContext(ComponentQuery componentQuery, ResolutionContext parentContext) {
super(parentContext == null ? componentQuery.getGlobalProperties() : new UnmodifiableMapUnion<String, Object>(
componentQuery.getGlobalProperties(), parentContext));
this.componentQuery = componentQuery;
this.parentContext = parentContext;
if (parentContext != null)
setSilentStatus(parentContext.isSilentStatus());
}
public ResolutionContext(MaterializationSpec mspec, ComponentQuery componentQuery) {
super(new UnmodifiableMapUnion<String, Object>(componentQuery.getGlobalProperties(), mspec.getProperties()));
this.componentQuery = componentQuery;
this.parentContext = null;
}
@Override
public synchronized void addRequestStatus(IComponentRequest request, IStatus resolveStatus) {
if (parentContext != null)
parentContext.addRequestStatus(request, resolveStatus);
else
super.addRequestStatus(request, resolveStatus);
}
@Override
public void addTagInfo(ComponentRequest request, String info) {
if (parentContext != null)
parentContext.addTagInfo(request, info);
else
super.addTagInfo(request, info);
}
@Override
public synchronized Map<String, String> getBindingProperties() {
return (parentContext != null) ? parentContext.getBindingProperties() : super.getBindingProperties();
}
@Override
public ComponentQuery getComponentQuery() {
return componentQuery;
}
public synchronized List<ResolverDecision> getDecisionLog(IComponentRequest request) {
if (parentContext != null)
return parentContext.getDecisionLog(request);
return Utils.createUnmodifiableList(decisionLog.get(request));
}
public GeneratorNode getGeneratorNode(ComponentRequest request) {
if (generators != null) {
for (GeneratorNode generator : generators.values()) {
if (request.designates(generator.getGeneratesId()))
return generator;
}
}
return (parentContext == null) ? null : parentContext.getGeneratorNode(request);
}
@Override
public Map<String, ? extends Object> getProperties(ComponentName cName) {
IAdvisorNode parentNode = null;
IAdvisorNode node = null;
Map<String, ? extends Object> p = super.getProperties(cName);
if (parentContext != null)
parentNode = parentContext.getComponentQuery().getMatchingNode(cName, this);
node = getComponentQuery().getMatchingNode(cName, this);
if (parentNode == null && node == null)
return p;
if (parentNode != null)
p = new UnmodifiableMapUnion<String, Object>(parentNode.getProperties(), p);
if (node != null && node != parentNode)
p = new UnmodifiableMapUnion<String, Object>(node.getProperties(), p);
return p;
}
@Override
public IStatus getStatus() {
return (parentContext != null) ? parentContext.getStatus() : super.getStatus();
}
@Override
public Map<ComponentRequest, TagInfo> getTagInfos() {
return (parentContext != null) ? parentContext.getTagInfos() : super.getTagInfos();
}
@Override
public Map<UUID, Object> getUserCache() {
return (parentContext != null) ? parentContext.getUserCache() : super.getUserCache();
}
@Override
public boolean isContinueOnError() {
return (parentContext != null) ? parentContext.isContinueOnError() : super.isContinueOnError();
}
@Override
public synchronized ResolverDecision logDecision(ComponentRequest request, ResolverDecisionType decisionType, Object... args) {
if (parentContext != null)
return parentContext.logDecision(request, decisionType, args);
List<ResolverDecision> decisions = decisionLog.get(request);
if (decisions == null) {
decisions = new ArrayList<ResolverDecision>();
decisionLog.put(request, decisions);
}
ResolverDecision decision = new ResolverDecision(request, decisionType, args);
decisions.add(decision);
if (!isSilentStatus())
CorePlugin.getLogger().debug("%s: %s", request, decision); //$NON-NLS-1$
return decision;
}
@Override
public ResolverDecision logDecision(ResolverDecisionType decisionType, Object... args) {
return logDecision(getComponentQuery().getExpandedRootRequest(this), decisionType, args);
}
@Override
public void setContinueOnError(boolean flag) {
if (parentContext != null)
parentContext.setContinueOnError(flag);
else
super.setContinueOnError(flag);
}
public void setGenerators(CSpec cspec, Collection<? extends IGenerator> generatorList) {
for (IGenerator generator : generatorList) {
if (generators == null)
generators = new HashMap<IComponentIdentifier, GeneratorNode>();
generators.put(generator.getGeneratedIdentifier(), new GeneratorNode(cspec, generator));
}
}
}