/* * Carrot2 project. * * Copyright (C) 2002-2016, Dawid Weiss, Stanisław Osiński. * All rights reserved. * * Refer to the full license file "carrot2.LICENSE" * in the root folder of the repository checkout or at: * http://www.carrot2.org/carrot2.LICENSE */ package org.carrot2.util.factory; import org.slf4j.Logger; import org.carrot2.shaded.guava.common.base.Predicate; import org.carrot2.shaded.guava.common.base.Throwables; /** * Fallback to the first factory that returns a value. */ public final class FallbackFactory<T> implements IFactory<T> { private final IFactory<T> defaultFactory; private final IFactory<T> fallbackFactory; private final String failureMessage; private final Logger logger; /** Verifies if T instances are functional or if fallback should be used. */ private final Predicate<T> verifier; public FallbackFactory( IFactory<T> defaultFactory, IFactory<T> fallbackFactory, Predicate<T> verifier, Logger logger, String failureMessage) { this.defaultFactory = defaultFactory; this.fallbackFactory = fallbackFactory; this.failureMessage = failureMessage; this.logger = logger; this.verifier = verifier; } /** * Creates an instance of <code>T</code>, making sure it is functional. */ @Override public final T createInstance() { try { T instance = defaultFactory.createInstance(); if (verifier.apply(instance)) { return instance; } logger.warn(failureMessage, "(false from predicate)"); return fallbackFactory.createInstance(); } catch (Throwable t) { if (logger.isDebugEnabled()) logger.warn(failureMessage, t.toString() + "\n" + Throwables.getStackTraceAsString(t)); else logger.warn(failureMessage, t.toString()); return fallbackFactory.createInstance(); } } }