    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.io.build;
    019
    020import org.apache.commons.io.function.IOSupplier;
    021
    022/**
    023 * Abstracts supplying an instance of {@code T}.
    024 * <p>
    025 * Extend this class to implement the builder pattern.
    026 * </p>
    027 * <p>
    028 * For example, here is a builder, a domain class, and a test.
    029 * </p>
    030 * <p>
    031 * The builder:
    032 * </p>
    033 * <pre>
    034    &#47;**
    035     &#42; Builds Foo instances.
    036     &#42;&#47;
    037    public static class Builder extends AbstractSupplier&#60;Foo, Builder&#62; {
    038
    039        private String bar1;
    040        private String bar2;
    041        private String bar3;
    042
    043        &#47;**
    044         &#42; Builds a new Foo.
    045         &#42;&#47;
    046        &#64;Override
    047        public Foo get() {
    048            return new Foo(bar1, bar2, bar3);
    049        }
    050
    051        public Builder setBar1(final String bar1) {
    052            this.bar1 = bar1;
    053            return this;
    054        }
    055
    056        public Builder setBar2(final String bar2) {
    057            this.bar2 = bar2;
    058            return this;
    059        }
    060
    061        public Builder setBar3(final String bar3) {
    062            this.bar3 = bar3;
    063            return this;
    064        }
    065    }
    066 * </pre>
    067 * <p>
    068 * The domain class:
    069 * </p>
    070 * <pre>
    071    &#47;**
    072     &#42; Domain class.
    073     &#42;&#47;
    074    public class Foo {
    075
    076        public static Builder builder() {
    077            return new Builder();
    078        }
    079
    080        private final String bar1;
    081        private final String bar2;
    082        private final String bar3;
    083
    084        private Foo(final String bar1, final String bar2, final String bar3) {
    085            this.bar1 = bar1;
    086            this.bar2 = bar2;
    087            this.bar3 = bar3;
    088        }
    089
    090        public String getBar1() {
    091            return bar1;
    092        }
    093
    094        public String getBar2() {
    095            return bar2;
    096        }
    097
    098        public String getBar3() {
    099            return bar3;
    100        }
    101
    102    }
    103 * </pre>
    104 * <p>
    105 * The test:
    106 * </p>
    107 * <pre>
    108    &#64;Test
    109    public void test() {
    110        final Foo foo = Foo.builder()
    111            .setBar1("value1")
    112            .setBar2("value2")
    113            .setBar3("value3")
    114            .get();
    115        assertEquals("value1", foo.getBar1());
    116        assertEquals("value2", foo.getBar2());
    117        assertEquals("value3", foo.getBar3());
    118    }
    119 * </pre>
    120 *
    121 * @param <T> the type of instances to build.
    122 * @param <B> the type of builder subclass.
    123 * @since 2.12.0
    124 */
    125public abstract class AbstractSupplier<T, B extends AbstractSupplier<T, B>> implements IOSupplier<T> {
    126
    127    /**
    128     * Constructs a new instance for subclasses.
    129     */
    130    public AbstractSupplier() {
    131        // empty
    132    }
    133
    134    /**
    135     * Returns this instance typed as the subclass type {@code B}.
    136     * <p>
    137     * This is the same as the expression:
    138     * </p>
    139     * <pre>
    140     * (B) this
    141     * </pre>
    142     *
    143     * @return this instance typed as the subclass type {@code B}.
    144     */
    145    @SuppressWarnings("unchecked")
    146    protected B asThis() {
    147        return (B) this;
    148    }
    149
    150}