Skip to content

Commit 3aa1ac2

Browse files
committedFeb 27, 2025
Added JVerify annotations per review (apache#2791)
1 parent 322cc1d commit 3aa1ac2

File tree

2 files changed

+138
-43
lines changed

2 files changed

+138
-43
lines changed
 

‎log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ComponentBuilder.java

+35-17
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import org.apache.logging.log4j.Level;
2020
import org.apache.logging.log4j.core.config.Configuration;
2121
import org.apache.logging.log4j.core.util.Builder;
22+
import org.jspecify.annotations.NonNull;
23+
import org.jspecify.annotations.Nullable;
2224

2325
/**
2426
* Builds arbitrary components and is the base type for the provided components.
@@ -35,9 +37,11 @@ public interface ComponentBuilder<T extends ComponentBuilder<T>> extends Builder
3537
* </p>
3638
* @param key The attribute key.
3739
* @param value The value of the attribute.
38-
* @return This ComponentBuilder.
40+
* @return this builder (for chaining)
41+
* @throws NullPointerException if the given {@code key} is {@code null}
3942
*/
40-
T addAttribute(String key, String value);
43+
@NonNull
44+
T addAttribute(@NonNull String key, @Nullable String value);
4145

4246
/**
4347
* Adds a logging Level attribute.
@@ -47,9 +51,11 @@ public interface ComponentBuilder<T extends ComponentBuilder<T>> extends Builder
4751
* </p>
4852
* @param key The attribute key.
4953
* @param level The logging Level.
50-
* @return This ComponentBuilder.
54+
* @return this builder (for chaining)
55+
* @throws NullPointerException if the given {@code key} is {@code null}
5156
*/
52-
T addAttribute(String key, Level level);
57+
@NonNull
58+
T addAttribute(@NonNull String key, @Nullable Level level);
5359

5460
/**
5561
* Adds an enumeration attribute.
@@ -59,25 +65,31 @@ public interface ComponentBuilder<T extends ComponentBuilder<T>> extends Builder
5965
* </p>
6066
* @param key The attribute key.
6167
* @param value The enumeration.
62-
* @return This ComponentBuilder.
68+
* @return this builder (for chaining)
69+
* @throws NullPointerException if the given {@code key} is {@code null}
6370
*/
64-
T addAttribute(String key, Enum<?> value);
71+
@NonNull
72+
T addAttribute(@NonNull String key, @Nullable Enum<?> value);
6573

6674
/**
6775
* Adds an integer attribute.
6876
* @param key The attribute key.
6977
* @param value The integer value.
70-
* @return This ComponentBuilder.
78+
* @return this builder (for chaining)
79+
* @throws NullPointerException if the given {@code key} is {@code null}
7180
*/
72-
T addAttribute(String key, int value);
81+
@NonNull
82+
T addAttribute(@NonNull String key, int value);
7383

7484
/**
7585
* Adds a boolean attribute.
7686
* @param key The attribute key.
7787
* @param value The boolean value.
78-
* @return This ComponentBuilder.
88+
* @return this builder (for chaining)
89+
* @throws NullPointerException if the given {@code key} is {@code null}
7990
*/
80-
T addAttribute(String key, boolean value);
91+
@NonNull
92+
T addAttribute(@NonNull String key, boolean value);
8193

8294
/**
8395
* Adds an Object attribute.
@@ -87,26 +99,32 @@ public interface ComponentBuilder<T extends ComponentBuilder<T>> extends Builder
8799
* </p>
88100
* @param key The attribute key.
89101
* @param value The object value.
90-
* @return This ComponentBuilder.
102+
* @return this builder (for chaining)
103+
* @throws NullPointerException if the given {@code key} is {@code null}
91104
*/
92-
T addAttribute(String key, Object value);
105+
@NonNull
106+
T addAttribute(@NonNull String key, @Nullable Object value);
93107

94108
/**
95109
* Adds a sub component.
96110
* @param builder The Assembler for the subcomponent with all of its attributes and sub-components set.
97-
* @return This ComponentBuilder (<em>not</em> the argument).
111+
* @return this builder (for chaining)
112+
* @throws NullPointerException if the given {@code builder} is {@code null}
98113
*/
99-
T addComponent(ComponentBuilder<?> builder);
114+
@NonNull
115+
T addComponent(@NonNull ComponentBuilder<?> builder);
100116

101117
/**
102-
* Returns the name of the component, if any.
103-
* @return The component's name or null if it doesn't have one.
118+
* Returns the name of the component.
119+
* @return The component's name or {@code null} if it doesn't have one.
104120
*/
121+
@Nullable
105122
String getName();
106123

107124
/**
108-
* Retrieves the ConfigurationBuilder.
125+
* Retrieves the {@code ConfigurationBuilder}.
109126
* @return The ConfigurationBuilder.
110127
*/
128+
@NonNull
111129
ConfigurationBuilder<? extends Configuration> getBuilder();
112130
}

‎log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultComponentBuilder.java

+103-26
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,19 @@
1717
package org.apache.logging.log4j.core.config.builder.impl;
1818

1919
import java.util.ArrayList;
20+
import java.util.Collections;
2021
import java.util.LinkedHashMap;
2122
import java.util.List;
2223
import java.util.Map;
24+
import java.util.Objects;
2325
import java.util.Optional;
24-
2526
import org.apache.logging.log4j.Level;
2627
import org.apache.logging.log4j.core.config.Configuration;
2728
import org.apache.logging.log4j.core.config.builder.api.Component;
2829
import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder;
2930
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
31+
import org.jspecify.annotations.NonNull;
32+
import org.jspecify.annotations.Nullable;
3033

3134
/**
3235
* Generic component that captures attributes and Components in preparation for assembling the Appender's
@@ -37,75 +40,125 @@
3740
class DefaultComponentBuilder<T extends ComponentBuilder<T>, CB extends ConfigurationBuilder<? extends Configuration>>
3841
implements ComponentBuilder<T> {
3942

40-
private final CB builder;
41-
private final String type;
43+
private final @NonNull CB builder;
44+
private final @Nullable String name;
45+
private final @NonNull String type;
46+
private final @Nullable String value;
4247
private final Map<String, String> attributes = new LinkedHashMap<>();
4348
private final List<Component> components = new ArrayList<>();
44-
private final String name;
45-
private final String value;
4649

47-
public DefaultComponentBuilder(final CB builder, final String type) {
50+
/**
51+
* Constructs a component builder with the given configuration builder and type with {@code null} name and value.
52+
* @param builder the configuration builder
53+
* @param type the type (plugin-type) of the component being built
54+
* @throws NullPointerException if either {@code builder} or {@code type} argument is null
55+
*/
56+
public DefaultComponentBuilder(final @NonNull CB builder, final @NonNull String type) {
4857
this(builder, null, type, null);
4958
}
5059

51-
public DefaultComponentBuilder(final CB builder, final String name, final String type) {
60+
/**
61+
* Constructs a component builder with the given configuration builder, name, type, and {@code null} value.
62+
* @param builder the configuration builder
63+
* @param name the component name
64+
* @param type the type (plugin-type) of the component being built
65+
* @throws NullPointerException if either {@code builder} or {@code type} argument is null
66+
*/
67+
public DefaultComponentBuilder(final @NonNull CB builder, final @Nullable String name, final @NonNull String type) {
5268
this(builder, name, type, null);
5369
}
5470

55-
public DefaultComponentBuilder(final CB builder, final String name, final String type, final String value) {
56-
this.type = type;
57-
this.builder = builder;
71+
/**
72+
* Constructs a component builder with the given configuration builder, name, type, and value.
73+
* @param builder the configuration builder
74+
* @param name the component name
75+
* @param type the type (plugin-type) of the component being built
76+
* @param value the component value
77+
* @throws NullPointerException if either {@code builder} or {@code type} argument is null
78+
*/
79+
public DefaultComponentBuilder(
80+
final @NonNull CB builder,
81+
final @Nullable String name,
82+
final @NonNull String type,
83+
final @Nullable String value) {
84+
super();
85+
this.builder = Objects.requireNonNull(builder, "The 'builder' argument must not be null.");
86+
this.type = Objects.requireNonNull(type, "The 'type' argument must not be null.");
5887
this.name = name;
5988
this.value = value;
6089
}
6190

6291
/** {@inheritDoc} */
6392
@Override
64-
public T addAttribute(final String key, final boolean value) {
93+
public @NonNull T addAttribute(final @NonNull String key, final boolean value) {
6594
return put(key, Boolean.toString(value));
6695
}
6796

6897
/** {@inheritDoc} */
6998
@Override
70-
public T addAttribute(final String key, final Enum<?> value) {
71-
return put(key, Optional.ofNullable(value).map(Enum::name).orElse(null));
99+
public @NonNull T addAttribute(final @NonNull String key, final int value) {
100+
return put(key, Integer.toString(value));
72101
}
73102

74103
/** {@inheritDoc} */
75104
@Override
76-
public T addAttribute(final String key, final int value) {
77-
return put(key, Integer.toString(value));
105+
public @NonNull T addAttribute(final @NonNull String key, final @Nullable Enum<?> value) {
106+
return put(key, Optional.ofNullable(value).map(Enum::name).orElse(null));
78107
}
79108

80109
/** {@inheritDoc} */
81110
@Override
82-
public T addAttribute(final String key, final Level level) {
111+
public @NonNull T addAttribute(final @NonNull String key, final @Nullable Level level) {
83112
return put(key, Optional.ofNullable(level).map(Level::toString).orElse(null));
84113
}
85114

86115
/** {@inheritDoc} */
87116
@Override
88-
public T addAttribute(final String key, final Object value) {
117+
public @NonNull T addAttribute(final @NonNull String key, final @Nullable Object value) {
89118
return put(key, Optional.ofNullable(value).map(Object::toString).orElse(null));
90119
}
91120

92121
/** {@inheritDoc} */
93122
@Override
94-
public T addAttribute(final String key, final String value) {
123+
public @NonNull T addAttribute(final @NonNull String key, final @Nullable String value) {
95124
return put(key, value);
96125
}
97126

127+
/**
128+
* Gets the value of the component attribute with the given key.
129+
*
130+
* @param key the key
131+
* @return the attribute value or {@code null} if not found
132+
*/
133+
protected @Nullable String getAttribute(final @NonNull String key) {
134+
135+
Objects.requireNonNull(key, "The 'key' argument must not be null.");
136+
137+
return this.attributes.get(key);
138+
}
139+
140+
/**
141+
* Gets the map of key/value component attributes.
142+
* <p>
143+
* The result map is guaranteed to have both non-{@code null} keys and values.
144+
* </p>
145+
* @return an <i>immutable</i> map of the key/value attributes
146+
*/
147+
protected @NonNull Map<String, String> getAttributes() {
148+
return Collections.unmodifiableMap(attributes);
149+
}
150+
98151
/** {@inheritDoc} */
99152
@Override
100-
@SuppressWarnings("unchecked")
101-
public T addComponent(final ComponentBuilder<?> builder) {
153+
public @NonNull T addComponent(final @NonNull ComponentBuilder<?> builder) {
154+
Objects.requireNonNull(builder, "The 'builder' argument must not be null.");
102155
components.add(builder.build());
103-
return (T) this;
156+
return self();
104157
}
105158

106159
/** {@inheritDoc} */
107160
@Override
108-
public Component build() {
161+
public @NonNull Component build() {
109162
final Component component = new Component(type, name, value);
110163
component.getAttributes().putAll(attributes);
111164
component.getComponents().addAll(components);
@@ -114,13 +167,13 @@ public Component build() {
114167

115168
/** {@inheritDoc} */
116169
@Override
117-
public CB getBuilder() {
170+
public @NonNull CB getBuilder() {
118171
return builder;
119172
}
120173

121174
/** {@inheritDoc} */
122175
@Override
123-
public String getName() {
176+
public @Nullable String getName() {
124177
return name;
125178
}
126179

@@ -133,16 +186,40 @@ public String getName() {
133186
* @param key the key
134187
* @param value the value
135188
* @return this builder (for chaining)
189+
* @throws NullPointerException if the given {@code key} argument is {@code null}
136190
*/
137-
@SuppressWarnings("unchecked")
138-
protected T put(final String key, final String value) {
191+
private @NonNull T put(final @NonNull String key, final @Nullable String value) {
192+
193+
Objects.requireNonNull(key, "The 'key' argument must not be null.");
139194

140195
if (value != null) {
141196
attributes.put(key, value);
142197
} else {
143198
attributes.remove(key);
144199
}
145200

201+
return self();
202+
}
203+
204+
/**
205+
* Clears the internal state removing all configured attributes and components.
206+
* <p>
207+
* This method is primarily intended to be used in testing.
208+
* </p>
209+
*/
210+
protected void clear() {
211+
synchronized (this) {
212+
attributes.clear();
213+
components.clear();
214+
}
215+
}
216+
217+
/**
218+
* Returns an instance of this builder cast to its generic type.
219+
* @return this builder
220+
*/
221+
@SuppressWarnings("unchecked")
222+
protected @NonNull T self() {
146223
return (T) this;
147224
}
148225
}

0 commit comments

Comments
 (0)
Please sign in to comment.