OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Blame | Last modification | View Log | RSS feed

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 */
 
 package org.openconcerto.utils.function;

import java.util.Objects;
import java.util.function.Supplier;

import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.ThreadSafe;

/**
 * A Supplier that always returns the same value. Functional in the sense, that for the same input
 * (indeed none in this case) it returns the same output.
 * 
 * @author sylvain
 * @param <T> the type of results supplied by this supplier.
 */
@ThreadSafe
public abstract class FunctionalSupplier<T> implements Supplier<T> {
    // Not an interface to restrict implementations (even inadvertently with the :: notation)

    @ThreadSafe
    static final class LazyValue<T> extends FunctionalSupplier<T> {

        private final Supplier<T> supplier;
        @GuardedBy("this")
        private boolean set;
        @GuardedBy("this")
        private T value;

        LazyValue(final Supplier<T> supplier) {
            super();
            this.supplier = Objects.requireNonNull(supplier);
            this.set = false;
        }

        @Override
        public synchronized T get() {
            if (!this.set) {
                this.value = this.supplier.get();
                this.set = true;
            }
            return this.value;
        }

        @Override
        public String toString() {
            return this.getClass().getSimpleName() + " for " + this.supplier;
        }
    }

    static public final <U> FunctionalSupplier<U> get(Supplier<U> orig) {
        return orig instanceof FunctionalSupplier ? (FunctionalSupplier<U>) orig : new LazyValue<>(orig);
    }

    static public final <U> ConstantSupplier<U> getConstant(U value) {
        return new ConstantSupplier<>(value);
    }

    // not public to restrict implementations
    FunctionalSupplier() {
    }
}