/******************************************************************************* * Copyright (c) 2008, 2014 Stuart McCulloch * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Stuart McCulloch - initial API and implementation *******************************************************************************/ package org.eclipse.sisu.peaberry.internal; import com.google.inject.Injector; import com.google.inject.Key; /** * Immutable setting that accepts either a binding key or explicit instance. * * @author mcculls@gmail.com (Stuart McCulloch) */ @SuppressWarnings("PMD.AbstractNaming") abstract class Setting<T> { /** * @param injector optional injector * @return injected setting value */ abstract T get(final Injector injector); /** * @return setting based on explicit instance */ static <T> Setting<T> newSetting(final T instance) { if (null == instance) { // null instances are not tolerated throw new IllegalArgumentException("null instance"); } return new Setting<T>() { private boolean configured; @Override synchronized T get(final Injector injector) { if (!configured && null != injector) { // given value may need injecting injector.injectMembers(instance); configured = true; } return instance; } }; } /** * @return setting based on binding key */ static <T> Setting<T> newSetting(final Key<? extends T> key) { if (null == key) { // null binding keys are not tolerated throw new IllegalArgumentException("null binding key"); } return new Setting<T>() { private T instance; @Override synchronized T get(final Injector injector) { if (null == instance) { if (null == injector) { throw new IllegalArgumentException("missing injector for setting: " + key); } // query the injector for the value instance = injector.getInstance(key); } return instance; } }; } @SuppressWarnings("unchecked") static <T> Setting<T> nullSetting() { return (Setting<T>) NULL_SETTING; } // constant null setting, safe to share between builders private static final Setting<Object> NULL_SETTING = new Setting<Object>() { @Override Object get(final Injector injector) { return null; } }; }