/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.target.lazy; import com.opengamma.engine.ComputationTarget; import com.opengamma.engine.ComputationTargetResolver; import com.opengamma.engine.ComputationTargetSpecification; import com.opengamma.engine.DelegatingComputationTargetResolver; import com.opengamma.engine.target.ComputationTargetType; import com.opengamma.engine.target.ComputationTargetTypeMap; import com.opengamma.id.UniqueIdentifiable; import com.opengamma.id.VersionCorrection; import com.opengamma.util.function.BiFunction; /** * A target resolver that does not resolve the targets immediately but returns a deferred handle. This is excellent for consumers of the target that only care about it's unique identifier and don't * need the resolution but can obtain it if they do. */ public final class LazyComputationTargetResolver extends DelegatingComputationTargetResolver { private static final ComputationTargetTypeMap<BiFunction<ComputationTargetResolver.AtVersionCorrection, ComputationTargetSpecification, UniqueIdentifiable>> s_resolvers; static { s_resolvers = new ComputationTargetTypeMap<BiFunction<ComputationTargetResolver.AtVersionCorrection, ComputationTargetSpecification, UniqueIdentifiable>>(); s_resolvers.put(ComputationTargetType.PORTFOLIO_NODE, new BiFunction<ComputationTargetResolver.AtVersionCorrection, ComputationTargetSpecification, UniqueIdentifiable>() { @Override public UniqueIdentifiable apply(final ComputationTargetResolver.AtVersionCorrection underlying, final ComputationTargetSpecification specification) { return new LazyTargetResolverPortfolioNode(underlying, specification); } }); s_resolvers.put(ComputationTargetType.POSITION, new BiFunction<ComputationTargetResolver.AtVersionCorrection, ComputationTargetSpecification, UniqueIdentifiable>() { @Override public UniqueIdentifiable apply(final ComputationTargetResolver.AtVersionCorrection underlying, final ComputationTargetSpecification specification) { return new LazyTargetResolverPosition(underlying, specification); } }); s_resolvers.put(ComputationTargetType.TRADE, new BiFunction<ComputationTargetResolver.AtVersionCorrection, ComputationTargetSpecification, UniqueIdentifiable>() { @Override public UniqueIdentifiable apply(final ComputationTargetResolver.AtVersionCorrection underlying, final ComputationTargetSpecification specification) { return new LazyTargetResolverTrade(underlying, specification); } }); } public LazyComputationTargetResolver(final ComputationTargetResolver underlying) { super(underlying); } /** * If the specification is lazily resolvable, returns a target that will resolve it on demand. Otherwise it is resolved immediately. * * @param underlying the underlying resolver to use for resolution * @param specification the specification to resolve * @return the target */ public static ComputationTarget resolve(final ComputationTargetResolver.AtVersionCorrection underlying, final ComputationTargetSpecification specification) { final BiFunction<ComputationTargetResolver.AtVersionCorrection, ComputationTargetSpecification, UniqueIdentifiable> resolver = s_resolvers.get(specification.getType()); if (resolver != null) { final UniqueIdentifiable lazy = resolver.apply(underlying, specification); if (specification.getUniqueId().isVersioned()) { return new ComputationTarget(specification, lazy); } else { return new ComputationTarget(specification.replaceIdentifier(lazy.getUniqueId()), lazy); } } else { return underlying.resolve(specification); } } public static ComputationTarget resolve(final ComputationTargetResolver underlying, final ComputationTargetSpecification specification, final VersionCorrection versionCorrection) { final BiFunction<ComputationTargetResolver.AtVersionCorrection, ComputationTargetSpecification, UniqueIdentifiable> resolver = s_resolvers.get(specification.getType()); if (resolver != null) { final UniqueIdentifiable lazy = resolver.apply(underlying.atVersionCorrection(versionCorrection), specification); if (specification.getUniqueId().isVersioned()) { return new ComputationTarget(specification, lazy); } else { return new ComputationTarget(specification.replaceIdentifier(lazy.getUniqueId()), lazy); } } else { return underlying.resolve(specification, versionCorrection); } } /** * Tests if the specification can be lazily resolved by a call to {@link #resolve}. * * @param specification the specification to test * @return true if lazy resolution will happen, false if the underlying will be queried immediately */ public static boolean isLazilyResolvable(final ComputationTargetSpecification specification) { return s_resolvers.get(specification.getType()) != null; } @Override public ComputationTarget resolve(final ComputationTargetSpecification specification, final VersionCorrection versionCorrection) { return resolve(getUnderlying(), specification, versionCorrection); } }