1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.io.build;
19
20 import org.apache.commons.io.function.IOSupplier;
21
22 /**
23 * Abstracts supplying an instance of {@code T}.
24 * <p>
25 * Extend this class to implement the builder pattern.
26 * </p>
27 * <p>
28 * For example, here is a builder, a domain class, and a test.
29 * </p>
30 * <p>
31 * The builder:
32 * </p>
33 * <pre>
34 /**
35 * Builds Foo instances.
36 */
37 public static class Builder extends AbstractSupplier<Foo, Builder> {
38
39 private String bar1;
40 private String bar2;
41 private String bar3;
42
43 /**
44 * Builds a new Foo.
45 */
46 @Override
47 public Foo get() {
48 return new Foo(bar1, bar2, bar3);
49 }
50
51 public Builder setBar1(final String bar1) {
52 this.bar1 = bar1;
53 return this;
54 }
55
56 public Builder setBar2(final String bar2) {
57 this.bar2 = bar2;
58 return this;
59 }
60
61 public Builder setBar3(final String bar3) {
62 this.bar3 = bar3;
63 return this;
64 }
65 }
66 * </pre>
67 * <p>
68 * The domain class:
69 * </p>
70 * <pre>
71 /**
72 * Domain class.
73 */
74 public class Foo {
75
76 public static Builder builder() {
77 return new Builder();
78 }
79
80 private final String bar1;
81 private final String bar2;
82 private final String bar3;
83
84 private Foo(final String bar1, final String bar2, final String bar3) {
85 this.bar1 = bar1;
86 this.bar2 = bar2;
87 this.bar3 = bar3;
88 }
89
90 public String getBar1() {
91 return bar1;
92 }
93
94 public String getBar2() {
95 return bar2;
96 }
97
98 public String getBar3() {
99 return bar3;
100 }
101
102 }
103 * </pre>
104 * <p>
105 * The test:
106 * </p>
107 * <pre>
108 @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 */
125 public 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 }