/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.calcnode; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.LongSet; import it.unimi.dsi.fastutil.objects.Object2LongMap; import java.util.Collections; import java.util.Set; import org.springframework.util.ObjectUtils; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.opengamma.engine.cache.IdentifierEncodedValueSpecifications; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.engine.view.ExecutionLog; import com.opengamma.engine.view.ExecutionLogMode; import com.opengamma.util.ArgumentChecker; /** * Contains details about the result of executing a {@link CalculationJobItem}. */ public final class CalculationJobResultItem implements IdentifierEncodedValueSpecifications { /*package*/static final String MISSING_INPUTS_FAILURE_CLASS = "com.opengamma.engine.calcnode.MissingInputException"; /*package*/static final String EXECUTION_SUPPRESSED_CLASS = "com.opengamma.engine.calcnode.ExecutionSuppressedException"; /*package*/static final String EXECUTION_SUPPRESSED_MESSAGE = "Unable to execute because of function blacklisting entry"; private Set<ValueSpecification> _missingOutputs; private long[] _missingOutputIdentifiers; private Set<ValueSpecification> _missingInputs; private long[] _missingInputIdentifiers; private final ExecutionLog _executionLog; public CalculationJobResultItem(Set<ValueSpecification> missingInputs, Set<ValueSpecification> missingOutputs, final ExecutionLog executionLog) { if (missingInputs == null) { missingInputs = ImmutableSet.<ValueSpecification>of(); } if (missingOutputs == null) { missingOutputs = ImmutableSet.<ValueSpecification>of(); } _missingInputs = missingInputs; _missingOutputs = missingOutputs; _executionLog = executionLog; } public CalculationJobResultItem(long[] missingInputIdentifiers, long[] missingOutputIdentifiers, ExecutionLog executionLog) { _missingInputIdentifiers = missingInputIdentifiers; _missingOutputIdentifiers = missingOutputIdentifiers; _executionLog = executionLog; } //------------------------------------------------------------------------- /** * Returns an immutable result item representing success, containing no additional data. * * @return a result item representing success, not null */ public static CalculationJobResultItem success() { return new CalculationJobResultItem(ImmutableSet.<ValueSpecification>of(), ImmutableSet.<ValueSpecification>of(), ExecutionLog.EMPTY); } /** * Returns an immutable result item representing a simple failure. * * @param exceptionClass the exception class, not null * @param exceptionMessage the exception message * @return a result item representing a simple failure, not null */ public static CalculationJobResultItem failure(String exceptionClass, String exceptionMessage) { ArgumentChecker.notNull(exceptionClass, "exceptionClass"); return CalculationJobResultItemBuilder .of(new MutableExecutionLog(ExecutionLogMode.INDICATORS)) .withException(exceptionClass, exceptionMessage) .toResultItem(); } //------------------------------------------------------------------------- public boolean isFailed() { return getExecutionLog().hasException(); } public InvocationResult getResult() { if (getExecutionLog().hasException()) { if (MISSING_INPUTS_FAILURE_CLASS.equals(getExecutionLog().getExceptionClass())) { return InvocationResult.MISSING_INPUTS; } else if (EXECUTION_SUPPRESSED_CLASS.equals(getExecutionLog().getExceptionClass())) { return InvocationResult.SUPPRESSED; } else { return InvocationResult.FUNCTION_THREW_EXCEPTION; } } else { if (_missingOutputs.isEmpty()) { return InvocationResult.SUCCESS; } else { return InvocationResult.PARTIAL_SUCCESS; } } } public Set<ValueSpecification> getMissingInputs() { return Collections.unmodifiableSet(_missingInputs); } public long[] getMissingInputIdentifiers() { return _missingInputIdentifiers; } public Set<ValueSpecification> getMissingOutputs() { return Collections.unmodifiableSet(_missingOutputs); } public long[] getMissingOutputIdentifiers() { return _missingOutputIdentifiers; } public ExecutionLog getExecutionLog() { return _executionLog; } @Override public void convertIdentifiers(final Long2ObjectMap<ValueSpecification> identifiers) { if (_missingInputs == null) { if (_missingInputIdentifiers == null) { _missingInputs = Collections.emptySet(); } else { _missingInputs = Sets.newHashSetWithExpectedSize(_missingInputIdentifiers.length); for (long identifier : _missingInputIdentifiers) { _missingInputs.add(identifiers.get(identifier)); } } } if (_missingOutputs == null) { if (_missingOutputIdentifiers == null) { _missingOutputs = Collections.emptySet(); } else { _missingOutputs = Sets.newHashSetWithExpectedSize(_missingOutputIdentifiers.length); for (long identifier : _missingOutputIdentifiers) { _missingOutputs.add(identifiers.get(identifier)); } } } } @Override public void collectIdentifiers(final LongSet identifiers) { if (_missingInputIdentifiers != null) { for (long identifier : _missingInputIdentifiers) { identifiers.add(identifier); } } if (_missingOutputIdentifiers != null) { for (long identifier : _missingOutputIdentifiers) { identifiers.add(identifier); } } } @Override public void convertValueSpecifications(final Object2LongMap<ValueSpecification> valueSpecifications) { if ((_missingInputIdentifiers == null) && !_missingInputs.isEmpty()) { _missingInputIdentifiers = new long[_missingInputs.size()]; int i = 0; for (ValueSpecification input : _missingInputs) { _missingInputIdentifiers[i++] = valueSpecifications.getLong(input); } } if ((_missingOutputIdentifiers == null) && !_missingOutputs.isEmpty()) { _missingOutputIdentifiers = new long[_missingOutputs.size()]; int i = 0; for (ValueSpecification output : _missingOutputs) { _missingOutputIdentifiers[i++] = valueSpecifications.getLong(output); } } } @Override public void collectValueSpecifications(final Set<ValueSpecification> valueSpecifications) { valueSpecifications.addAll(_missingInputs); valueSpecifications.addAll(_missingOutputs); } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("CalculationJobResultItem-").append(getResult()); return sb.toString(); } @Override public int hashCode() { int hc = 1; hc += (hc << 4) + ObjectUtils.nullSafeHashCode(_missingOutputs); hc += (hc << 4) + ObjectUtils.nullSafeHashCode(_missingInputs); return hc; } @Override public boolean equals(final Object o) { if (o == this) { return true; } if (!(o instanceof CalculationJobResultItem)) { return false; } final CalculationJobResultItem other = (CalculationJobResultItem) o; return ObjectUtils.nullSafeEquals(other._missingOutputs, _missingOutputs) && ObjectUtils.nullSafeEquals(other._missingInputs, _missingInputs) && ObjectUtils.nullSafeEquals(other._executionLog, _executionLog); } }