/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.depgraph;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import com.opengamma.engine.target.ComputationTargetReference;
import com.opengamma.engine.value.ValueProperties;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.util.ArgumentChecker;
/**
* Visitor for printing out resolution failure information to a file.
*/
public class ResolutionFailurePrinter extends ResolutionFailureVisitor<Void> {
private final Set<ResolutionFailure> _visited;
private final PrintWriter _out;
private final String _indent;
public ResolutionFailurePrinter() {
this(new OutputStreamWriter(System.out));
}
public ResolutionFailurePrinter(final Writer out) {
ArgumentChecker.notNull(out, "out");
_out = new PrintWriter(out, true);
_indent = "";
_visited = Collections.newSetFromMap(new IdentityHashMap<ResolutionFailure, Boolean>());
}
protected ResolutionFailurePrinter(final ResolutionFailurePrinter parent, final PrintWriter writer) {
ArgumentChecker.notNull(parent, "parent");
_out = writer;
_indent = parent._indent + " ";
_visited = parent._visited;
}
protected void println(final String str) {
synchronized (_out) {
_out.print(_indent);
_out.println(str);
}
}
protected String toString(final ValueRequirement valueRequirement) {
final StringBuilder sb = new StringBuilder();
sb.append(valueRequirement.getValueName());
if (!valueRequirement.getConstraints().isEmpty()) {
sb.append(' ').append(toString(valueRequirement.getConstraints()));
}
sb.append(" on ").append(toString(valueRequirement.getTargetReference()));
return sb.toString();
}
protected String toString(final ComputationTargetReference target) {
return target.toString();
}
protected String toString(final ResolvedValue resolvedValue) {
return toString(resolvedValue.getValueSpecification());
}
protected String toString(final ValueProperties valueProperties) {
return valueProperties.toString();
}
protected String toString(final ValueSpecification valueSpecification) {
return valueSpecification.getValueName() + ' ' + toString(valueSpecification.getProperties()) + " on " + toString(valueSpecification.getTargetSpecification());
}
protected String toString(final Map<ValueSpecification, ValueRequirement> requirements) {
final StringBuilder sb = new StringBuilder();
boolean comma = false;
for (ValueSpecification requirement : requirements.keySet()) {
if (comma) {
sb.append(", ");
} else {
sb.append("{");
comma = true;
}
sb.append(toString(requirement));
}
if (comma) {
sb.append("}");
} else {
sb.append("EMPTY");
}
return sb.toString();
}
protected String toStringResolutionFailures(final Set<ResolutionFailure> failures) {
final StringBuilder sb = new StringBuilder();
boolean comma = false;
for (ResolutionFailure failure : failures) {
if (comma) {
sb.append(", ");
} else {
sb.append("{");
comma = true;
}
sb.append(toString(failure));
}
if (comma) {
sb.append("}");
} else {
sb.append("EMPTY");
}
return sb.toString();
}
protected String toStringValueSpecifications(final Set<ValueSpecification> specifications) {
final StringBuilder sb = new StringBuilder();
boolean comma = false;
for (ValueSpecification specification : specifications) {
if (comma) {
sb.append(", ");
} else {
sb.append("{");
comma = true;
}
sb.append(toString(specification));
}
if (comma) {
sb.append("}");
} else {
sb.append("EMPTY");
}
return sb.toString();
}
protected String toString(final ResolutionFailure failure) {
return toString(failure.getValueRequirement());
}
@Override
protected Void visitCouldNotResolve(final ValueRequirement valueRequirement) {
println("Could not resolve " + toString(valueRequirement));
return null;
}
@Override
protected Void visitNoFunctions(final ValueRequirement valueRequirement) {
println("No functions available for " + toString(valueRequirement));
return null;
}
@Override
protected Void visitRecursiveRequirement(final ValueRequirement valueRequirement) {
println("Recursive requirement on " + toString(valueRequirement) + " for function(s) producing it");
return null;
}
@Override
protected Void visitUnsatisfied(final ValueRequirement valueRequirement) {
println("Unsatisfied requirement " + toString(valueRequirement));
return null;
}
@Override
protected Void visitMarketDataMissing(final ValueRequirement valueRequirement) {
println("Market data missing for requirement " + toString(valueRequirement));
return null;
}
@Override
protected Void visitSuccessfulFunction(final ValueRequirement valueRequirement, final String function, final ValueSpecification desiredOutput,
final Map<ValueSpecification, ValueRequirement> satisfied) {
println("Applied " + function + " to produce " + toString(desiredOutput) + " for " + toString(valueRequirement));
return null;
}
@Override
protected Void visitFailedFunction(final ValueRequirement valueRequirement, final String function, final ValueSpecification desiredOutput,
final Map<ValueSpecification, ValueRequirement> satisfied, final Set<ResolutionFailure> unsatisfied) {
final StringWriter buffer = new StringWriter();
final ResolutionFailurePrinter visitor = new ResolutionFailurePrinter(this, new PrintWriter(buffer));
for (ResolutionFailure requirement : unsatisfied) {
if (_visited.add(requirement)) {
requirement.accept(visitor);
} else {
visitor.println("... " + requirement.getValueRequirement());
}
}
synchronized (_out) {
_out.print(_indent);
_out.println("Couldn't satisfy " + toStringResolutionFailures(unsatisfied) + " for " + function + " to produce " + toString(desiredOutput) + " for " + toString(valueRequirement) +
". Caused by:");
_out.print(buffer.toString());
}
return null;
}
@Override
protected Void visitGetAdditionalRequirementsFailed(final ValueRequirement valueRequirement, final String function, final ValueSpecification desiredOutput,
final Map<ValueSpecification, ValueRequirement> requirements) {
println("getAdditionalRequirements method failed on " + function + " with inputs " + toString(requirements) + " to produce " + toString(desiredOutput) + " for " +
toString(valueRequirement));
return null;
}
@Override
protected Void visitGetResultsFailed(final ValueRequirement valueRequirement, final String function, final ValueSpecification desiredOutput,
final Map<ValueSpecification, ValueRequirement> requirements) {
println("getResults method failed on " + function + " with inputs " + toString(requirements) + " to produce " + toString(desiredOutput) + " for " + toString(valueRequirement));
return null;
}
@Override
protected Void visitGetRequirementsFailed(final ValueRequirement valueRequirement, final String function, final ValueSpecification desiredOutput) {
println("getRequirements method failed on " + function + " to produce " + toString(desiredOutput) + " for " + toString(valueRequirement));
return null;
}
@Override
protected Void visitLateResolutionFailure(final ValueRequirement valueRequirement, final String function, final ValueSpecification desiredOutput,
final Map<ValueSpecification, ValueRequirement> requirements) {
println("Provisional result " + toString(desiredOutput) + " for " + toString(desiredOutput) + " not in output of " + function + " after late resolution of " +
toStringValueSpecifications(requirements.keySet()));
return null;
}
}