Skip to content

Commit c3c2569

Browse files
aepfliclaude
andcommitted
feat: Add builder patterns to ImmutableContext and ImmutableStructure with comprehensive tests
- Added complete builder pattern implementation to ImmutableContext with targeting key support and all data type methods - Added complete builder pattern implementation to ImmutableStructure with comprehensive data type support - Created ImmutableContextBuilderTest with 22 tests covering targeting key handling, builder chaining, toBuilder functionality, defensive copying, and consistency with constructors - Created ImmutableStructureBuilderTest with 22 tests covering all builder functionality, nested structures, and builder independence - Both implementations follow established patterns with fluent APIs and defensive copying 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent e2c2d3f commit c3c2569

File tree

4 files changed

+1107
-0
lines changed

4 files changed

+1107
-0
lines changed

openfeature-api/src/main/java/dev/openfeature/api/ImmutableContext.java

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,166 @@ public String toString() {
142142
return "ImmutableContext{" + "structure=" + structure + '}';
143143
}
144144

145+
/**
146+
* Returns a builder for creating ImmutableContext instances.
147+
*
148+
* @return a builder for ImmutableContext
149+
*/
150+
public static Builder builder() {
151+
return new Builder();
152+
}
153+
154+
/**
155+
* Returns a builder initialized with the current state of this object.
156+
*
157+
* @return a builder for ImmutableContext
158+
*/
159+
public Builder toBuilder() {
160+
return builder().targetingKey(this.getTargetingKey()).attributes(this.structure.asMap());
161+
}
162+
163+
/**
164+
* Builder class for creating instances of ImmutableContext.
165+
*/
166+
public static class Builder {
167+
private String targetingKey;
168+
private final Map<String, Value> attributes;
169+
170+
private Builder() {
171+
this.attributes = new HashMap<>();
172+
}
173+
174+
/**
175+
* Sets the targeting key for the evaluation context.
176+
*
177+
* @param targetingKey the targeting key
178+
* @return this builder
179+
*/
180+
public Builder targetingKey(String targetingKey) {
181+
this.targetingKey = targetingKey;
182+
return this;
183+
}
184+
185+
/**
186+
* Sets the attributes from a map.
187+
*
188+
* @param attributes map of attributes
189+
* @return this builder
190+
*/
191+
public Builder attributes(Map<String, Value> attributes) {
192+
if (attributes != null) {
193+
this.attributes.clear();
194+
this.attributes.putAll(attributes);
195+
}
196+
return this;
197+
}
198+
199+
/**
200+
* Add String value to the evaluation context.
201+
*
202+
* @param key attribute key
203+
* @param value attribute value
204+
* @return this builder
205+
*/
206+
public Builder add(final String key, final String value) {
207+
attributes.put(key, Value.objectToValue(value));
208+
return this;
209+
}
210+
211+
/**
212+
* Add Integer value to the evaluation context.
213+
*
214+
* @param key attribute key
215+
* @param value attribute value
216+
* @return this builder
217+
*/
218+
public Builder add(final String key, final Integer value) {
219+
attributes.put(key, Value.objectToValue(value));
220+
return this;
221+
}
222+
223+
/**
224+
* Add Long value to the evaluation context.
225+
*
226+
* @param key attribute key
227+
* @param value attribute value
228+
* @return this builder
229+
*/
230+
public Builder add(final String key, final Long value) {
231+
attributes.put(key, Value.objectToValue(value));
232+
return this;
233+
}
234+
235+
/**
236+
* Add Float value to the evaluation context.
237+
*
238+
* @param key attribute key
239+
* @param value attribute value
240+
* @return this builder
241+
*/
242+
public Builder add(final String key, final Float value) {
243+
attributes.put(key, Value.objectToValue(value));
244+
return this;
245+
}
246+
247+
/**
248+
* Add Double value to the evaluation context.
249+
*
250+
* @param key attribute key
251+
* @param value attribute value
252+
* @return this builder
253+
*/
254+
public Builder add(final String key, final Double value) {
255+
attributes.put(key, Value.objectToValue(value));
256+
return this;
257+
}
258+
259+
/**
260+
* Add Boolean value to the evaluation context.
261+
*
262+
* @param key attribute key
263+
* @param value attribute value
264+
* @return this builder
265+
*/
266+
public Builder add(final String key, final Boolean value) {
267+
attributes.put(key, Value.objectToValue(value));
268+
return this;
269+
}
270+
271+
/**
272+
* Add Structure value to the evaluation context.
273+
*
274+
* @param key attribute key
275+
* @param value attribute value
276+
* @return this builder
277+
*/
278+
public Builder add(final String key, final Structure value) {
279+
attributes.put(key, Value.objectToValue(value));
280+
return this;
281+
}
282+
283+
/**
284+
* Add Value to the evaluation context.
285+
*
286+
* @param key attribute key
287+
* @param value attribute value
288+
* @return this builder
289+
*/
290+
public Builder add(final String key, final Value value) {
291+
attributes.put(key, value);
292+
return this;
293+
}
294+
295+
/**
296+
* Build the ImmutableContext with the provided values.
297+
*
298+
* @return a new ImmutableContext instance
299+
*/
300+
public ImmutableContext build() {
301+
return new ImmutableContext(targetingKey, new HashMap<>(attributes));
302+
}
303+
}
304+
145305
@SuppressWarnings("all")
146306
private static class DelegateExclusions {
147307
@ExcludeFromGeneratedCoverageReport

openfeature-api/src/main/java/dev/openfeature/api/ImmutableStructure.java

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,154 @@ public Map<String, Value> asMap() {
8585
return copyAttributes(attributes);
8686
}
8787

88+
/**
89+
* Returns a builder for creating ImmutableStructure instances.
90+
*
91+
* @return a builder for ImmutableStructure
92+
*/
93+
public static Builder builder() {
94+
return new Builder();
95+
}
96+
97+
/**
98+
* Returns a builder initialized with the current state of this object.
99+
*
100+
* @return a builder for ImmutableStructure
101+
*/
102+
public Builder toBuilder() {
103+
return builder().attributes(this.asMap());
104+
}
105+
106+
/**
107+
* Builder class for creating instances of ImmutableStructure.
108+
*/
109+
public static class Builder {
110+
private final Map<String, Value> attributes;
111+
112+
private Builder() {
113+
this.attributes = new HashMap<>();
114+
}
115+
116+
/**
117+
* Sets the attributes from a map.
118+
*
119+
* @param attributes map of attributes
120+
* @return this builder
121+
*/
122+
public Builder attributes(Map<String, Value> attributes) {
123+
if (attributes != null) {
124+
this.attributes.clear();
125+
this.attributes.putAll(attributes);
126+
}
127+
return this;
128+
}
129+
130+
/**
131+
* Add String value to the structure.
132+
*
133+
* @param key attribute key
134+
* @param value attribute value
135+
* @return this builder
136+
*/
137+
public Builder add(final String key, final String value) {
138+
attributes.put(key, Value.objectToValue(value));
139+
return this;
140+
}
141+
142+
/**
143+
* Add Integer value to the structure.
144+
*
145+
* @param key attribute key
146+
* @param value attribute value
147+
* @return this builder
148+
*/
149+
public Builder add(final String key, final Integer value) {
150+
attributes.put(key, Value.objectToValue(value));
151+
return this;
152+
}
153+
154+
/**
155+
* Add Long value to the structure.
156+
*
157+
* @param key attribute key
158+
* @param value attribute value
159+
* @return this builder
160+
*/
161+
public Builder add(final String key, final Long value) {
162+
attributes.put(key, Value.objectToValue(value));
163+
return this;
164+
}
165+
166+
/**
167+
* Add Float value to the structure.
168+
*
169+
* @param key attribute key
170+
* @param value attribute value
171+
* @return this builder
172+
*/
173+
public Builder add(final String key, final Float value) {
174+
attributes.put(key, Value.objectToValue(value));
175+
return this;
176+
}
177+
178+
/**
179+
* Add Double value to the structure.
180+
*
181+
* @param key attribute key
182+
* @param value attribute value
183+
* @return this builder
184+
*/
185+
public Builder add(final String key, final Double value) {
186+
attributes.put(key, Value.objectToValue(value));
187+
return this;
188+
}
189+
190+
/**
191+
* Add Boolean value to the structure.
192+
*
193+
* @param key attribute key
194+
* @param value attribute value
195+
* @return this builder
196+
*/
197+
public Builder add(final String key, final Boolean value) {
198+
attributes.put(key, Value.objectToValue(value));
199+
return this;
200+
}
201+
202+
/**
203+
* Add Structure value to the structure.
204+
*
205+
* @param key attribute key
206+
* @param value attribute value
207+
* @return this builder
208+
*/
209+
public Builder add(final String key, final Structure value) {
210+
attributes.put(key, Value.objectToValue(value));
211+
return this;
212+
}
213+
214+
/**
215+
* Add Value to the structure.
216+
*
217+
* @param key attribute key
218+
* @param value attribute value
219+
* @return this builder
220+
*/
221+
public Builder add(final String key, final Value value) {
222+
attributes.put(key, value);
223+
return this;
224+
}
225+
226+
/**
227+
* Build the ImmutableStructure with the provided values.
228+
*
229+
* @return a new ImmutableStructure instance
230+
*/
231+
public ImmutableStructure build() {
232+
return new ImmutableStructure(new HashMap<>(attributes));
233+
}
234+
}
235+
88236
private static Map<String, Value> copyAttributes(Map<String, Value> in) {
89237
return copyAttributes(in, null);
90238
}

0 commit comments

Comments
 (0)