Skip to content

Commit f4d02f4

Browse files
committed
Remove mutability property
1 parent e7f95b6 commit f4d02f4

17 files changed

Lines changed: 110 additions & 290 deletions

File tree

‎README.md‎

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ Main properties:
7878
- [`#batchType`](#batch-type-property): bridge different services and generate providers on the fly
7979

8080
Advanced properties:
81-
- [`#mutability`](#mutability-property): on-demand set and reload
8281
- [`#backend` `#cleaner`](#backend-and-cleaner-properties): custom service loader
8382

8483
#### Quantifier property
@@ -247,14 +246,6 @@ Constraints:
247246
1. Batch type must be an interface or an abstract class.
248247
2. Batch method must be unique.
249248

250-
#### Mutability property
251-
252-
The `#mutability` property allows **on-demand set and reload** of a loader.
253-
254-
_Example: [nbbrd/service/examples/Messenger.java](java-service-examples/src/main/java/nbbrd/service/examples/Messenger.java)_
255-
256-
⚠️ _This is a complex mechanism that targets specific usages. It will be removed and/or simplified in a future release._
257-
258249
#### Backend and cleaner properties
259250

260251
The `#backend` and `#cleaner` properties allow to use a **custom service loader** such as [NetBeans Lookup](https://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/index.html) instead of JDK `ServiceLoader`.

‎java-service-annotation/src/main/java/nbbrd/service/ServiceDefinition.java‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
import java.util.ServiceLoader;
2121
import java.util.function.Consumer;
2222
import java.util.function.Function;
23-
import java.util.function.UnaryOperator;
24-
import java.util.stream.Stream;
2523

2624
/**
2725
* Declarative definition of a service that generates a specialized service
@@ -83,15 +81,6 @@
8381
*/
8482
Class<?> batchType() default Void.class;
8583

86-
/**
87-
* Specifies the mutability of the loader.
88-
*
89-
* @return a non-null mutability
90-
* @deprecated This is a complex mechanism that targets specific usages. It will be removed and/or simplified in a future release.
91-
*/
92-
@Deprecated
93-
Mutability mutability() default Mutability.NONE;
94-
9584
/**
9685
* Specifies the class that creates a service loader.
9786
* <br>The default backend uses {@link ServiceLoader#load(Class)}.

‎java-service-examples/src/main/java/nbbrd/service/examples/Messenger.java‎

Lines changed: 0 additions & 46 deletions
This file was deleted.

‎java-service-examples/src/test/java/nbbrd/service/examples/FileTypeSpiTest.java‎

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,38 @@
33
import internal.nbbrd.service.examples.FileTypeSpiLoader;
44
import org.junit.jupiter.api.Test;
55

6+
import java.util.List;
7+
import java.util.ServiceLoader;
8+
import java.util.stream.StreamSupport;
9+
10+
import static java.util.stream.Collectors.toList;
611
import static org.assertj.core.api.Assertions.assertThat;
7-
import static org.assertj.core.api.Assertions.atIndex;
12+
import static org.assertj.core.api.Assertions.assertThatCode;
813

914
public class FileTypeSpiTest {
1015

1116
@Test
1217
public void test() {
1318
FileTypeSpiLoader x = new FileTypeSpiLoader();
19+
1420
assertThat(x.get())
1521
.containsExactlyElementsOf(x.get())
16-
.hasSize(2)
17-
.satisfies(o -> assertThat(o).isInstanceOf(FileType.ByMagicNumberProbe.class), atIndex(0))
18-
.satisfies(o -> assertThat(o).isInstanceOf(FileType.ByExtensionProbe.class), atIndex(1));
22+
.hasExactlyElementsOfTypes(FileType.ByMagicNumberProbe.class, FileType.ByExtensionProbe.class)
23+
.extracting(FileTypeSpiTest::getTypeName)
24+
.containsExactlyElementsOf(toTypeNames(FileTypeSpiLoader.load()))
25+
.containsExactlyInAnyOrderElementsOf(toTypeNames(ServiceLoader.load(FileType.FileTypeSpi.class)));
26+
27+
assertThatCode(x::reload)
28+
.doesNotThrowAnyException();
29+
}
30+
31+
private static List<String> toTypeNames(Iterable<?> iterable) {
32+
return StreamSupport.stream(iterable.spliterator(), false)
33+
.map(FileTypeSpiTest::getTypeName)
34+
.collect(toList());
35+
}
36+
37+
private static String getTypeName(Object fileTypeSpi) {
38+
return fileTypeSpi.getClass().getName();
1939
}
2040
}

‎java-service-examples/src/test/java/nbbrd/service/examples/MessengerTest.java‎

Lines changed: 0 additions & 34 deletions
This file was deleted.

‎java-service-processor/src/main/java/internal/nbbrd/service/definition/LoadDefinition.java‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,6 @@ class LoadDefinition {
4141
@lombok.NonNull
4242
Quantifier quantifier;
4343

44-
@lombok.NonNull
45-
Lifecycle lifecycle;
46-
4744
@lombok.NonNull
4845
ClassName serviceType;
4946

‎java-service-processor/src/main/java/internal/nbbrd/service/definition/ServiceDefinitionCollector.java‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ private LoadDefinition definitionOf(TypeElement serviceType) {
113113
return LoadDefinition
114114
.builder()
115115
.quantifier(annotation.quantifier())
116-
.lifecycle(Lifecycle.of(annotation.mutability()))
117116
.serviceType(ClassName.get(serviceType))
118117
.fallback(fallback)
119118
.loaderName(annotation.loaderName())

‎java-service-processor/src/main/java/internal/nbbrd/service/definition/ServiceDefinitionGenerator.java‎

Lines changed: 17 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
import javax.lang.model.type.TypeMirror;
2727
import java.util.*;
28-
import java.util.concurrent.atomic.AtomicReference;
2928
import java.util.function.Consumer;
3029
import java.util.function.Predicate;
3130
import java.util.regex.Pattern;
@@ -119,17 +118,12 @@ public TypeSpec generateLoader(boolean nested) {
119118
result.addModifiers(STATIC).build();
120119
}
121120

122-
if (definition.getLifecycle().isModifiable()) {
123-
FieldSpec cleanerField = newCleanerField();
124-
result.addField(cleanerField);
125-
result.addMethod(newSetMethod(resourceField, quantifierType));
126-
result.addMethod(newReloadMethod(sourceField, batchField, cleanerField, doLoadMethod));
127-
result.addMethod(newResetMethod(sourceField, doLoadMethod));
128-
}
121+
FieldSpec cleanerField = newCleanerField();
122+
result.addField(cleanerField);
123+
result.addMethod(newSetMethod(resourceField, quantifierType));
124+
result.addMethod(newReloadMethod(sourceField, batchField, cleanerField, doLoadMethod));
129125

130-
if (definition.getLifecycle() == Lifecycle.IMMUTABLE) {
131-
result.addMethod(newLoadMethod(className, quantifierType, getMethod));
132-
}
126+
result.addMethod(newLoadMethod(className, quantifierType, getMethod));
133127

134128
return result.build();
135129
}
@@ -138,13 +132,11 @@ private CodeBlock getMainJavadoc() {
138132
return CodeBlock
139133
.builder()
140134
.add("Custom service loader for $L.\n", toJavadocLink(definition.getServiceType()))
141-
.add("<br>This class $L thread-safe.\n", definition.getLifecycle().isThreadSafe() ? "is" : "is not")
142135
.add("<p>Properties:\n")
143136
.add("<ul>\n")
144137
.add("<li>Quantifier: $L</li>\n", definition.getQuantifier())
145138
.add("<li>Fallback: $L</li>\n", toJavadocLink(definition.getFallback()))
146139
.add("<li>Preprocessing: $L</li>\n", getPreprocessingJavadoc())
147-
.add("<li>Mutability: $L</li>\n", definition.getLifecycle().toMutability())
148140
.add("<li>Name: $L</li>\n", definition.getLoaderName().isEmpty() ? "null" : definition.getLoaderName())
149141
.add("<li>Backend: $L</li>\n", definition.getBackend().map(HasTypeMirror::getTypeName).orElse("null"))
150142
.add("<li>Cleaner: $L</li>\n", definition.getCleaner().map(HasTypeMirror::getTypeName).orElse("null"))
@@ -401,23 +393,11 @@ private FieldSpec getResourceField(MethodSpec doLoadMethod, TypeName quantifierT
401393
}
402394

403395
private FieldSpec.Builder getResourceFieldBuilder(TypeName quantifierType) {
404-
String name = "resource";
405-
switch (definition.getLifecycle()) {
406-
case IMMUTABLE:
407-
return FieldSpec.builder(quantifierType, name, PRIVATE, FINAL);
408-
case MUTABLE:
409-
return FieldSpec.builder(quantifierType, name, PRIVATE);
410-
case CONCURRENT:
411-
return FieldSpec.builder(typeOf(AtomicReference.class, quantifierType), name, PRIVATE, FINAL);
412-
default:
413-
throw new Unreachable();
414-
}
396+
return FieldSpec.builder(quantifierType, "resource", PRIVATE);
415397
}
416398

417399
private CodeBlock getResourceInitializer(MethodSpec doLoadMethod) {
418-
return definition.getLifecycle().isAtomicReference()
419-
? CodeBlock.of("new $T<>($N())", ClassName.get(AtomicReference.class), doLoadMethod)
420-
: CodeBlock.of("$N()", doLoadMethod);
400+
return CodeBlock.of("$N()", doLoadMethod);
421401
}
422402

423403
private MethodSpec getGetMethod(FieldSpec resourceField, TypeName quantifierType) {
@@ -426,7 +406,6 @@ private MethodSpec getGetMethod(FieldSpec resourceField, TypeName quantifierType
426406
.addJavadoc(CodeBlock
427407
.builder()
428408
.add(getGetDescription())
429-
.add(getThreadSafetyComment())
430409
.add("@return the current non-null value\n")
431410
.build())
432411
.addModifiers(PUBLIC)
@@ -449,9 +428,7 @@ private CodeBlock getGetDescription() {
449428
}
450429

451430
private CodeBlock getGetterStatement(FieldSpec resourceField) {
452-
return definition.getLifecycle().isAtomicReference()
453-
? CodeBlock.of("return $N.get()", resourceField)
454-
: CodeBlock.of("return $N", resourceField);
431+
return CodeBlock.of("return $N", resourceField);
455432
}
456433

457434
private MethodSpec newSetMethod(FieldSpec resourceField, TypeName quantifierType) {
@@ -460,10 +437,9 @@ private MethodSpec newSetMethod(FieldSpec resourceField, TypeName quantifierType
460437
.addJavadoc(CodeBlock
461438
.builder()
462439
.add(getSetDescription())
463-
.add(getThreadSafetyComment())
464440
.add("@param newValue new non-null value\n")
465441
.build())
466-
.addModifiers(PUBLIC)
442+
.addModifiers(PRIVATE)
467443
.addParameter(quantifierType, "newValue")
468444
.addStatement(getSetterStatement(resourceField))
469445
.build();
@@ -483,9 +459,7 @@ private CodeBlock getSetDescription() {
483459
}
484460

485461
private CodeBlock getSetterStatement(FieldSpec resourceField) {
486-
return definition.getLifecycle().isAtomicReference()
487-
? CodeBlock.of("$N.set($T.requireNonNull(newValue))", resourceField, Objects.class)
488-
: CodeBlock.of("$N = $T.requireNonNull(newValue)", resourceField, Objects.class);
462+
return CodeBlock.of("$N = $T.requireNonNull(newValue)", resourceField, Objects.class);
489463
}
490464

491465
private MethodSpec newReloadMethod(
@@ -499,47 +473,14 @@ private MethodSpec newReloadMethod(
499473
.addJavadoc(CodeBlock
500474
.builder()
501475
.add("Reloads the content by clearing the cache and fetching available providers.\n")
502-
.add(getThreadSafetyComment())
503476
.build())
504477
.addModifiers(PUBLIC)
505478
.addExceptions(getQuantifierException());
506479

507-
if (definition.getLifecycle().isAtomicReference()) {
508-
result.beginControlFlow("synchronized($N)", sourceField);
509-
}
510-
511480
result.addStatement("$N.accept($N)", cleanerField, sourceField);
512481
batchField.ifPresent(fieldSpec -> result.addStatement("$N.accept($N)", cleanerField, fieldSpec));
513482
result.addStatement("set($N())", loaderMethod);
514483

515-
if (definition.getLifecycle().isAtomicReference()) {
516-
result.endControlFlow();
517-
}
518-
519-
return result.build();
520-
}
521-
522-
private MethodSpec newResetMethod(FieldSpec sourceField, MethodSpec loaderMethod) {
523-
MethodSpec.Builder result = MethodSpec
524-
.methodBuilder("reset")
525-
.addJavadoc(CodeBlock
526-
.builder()
527-
.add("Resets the content without clearing the cache.\n")
528-
.add(getThreadSafetyComment())
529-
.build())
530-
.addModifiers(PUBLIC)
531-
.addExceptions(getQuantifierException());
532-
533-
if (definition.getLifecycle().isAtomicReference()) {
534-
result.beginControlFlow("synchronized($N)", sourceField);
535-
}
536-
537-
result.addStatement("set($N())", loaderMethod);
538-
539-
if (definition.getLifecycle().isAtomicReference()) {
540-
result.endControlFlow();
541-
}
542-
543484
return result.build();
544485
}
545486

@@ -553,7 +494,6 @@ private MethodSpec newLoadMethod(String className, TypeName quantifierType, Meth
553494
.add(getGetDescription())
554495
.add("<br>This is equivalent to the following code: <code>$L</code>\n", mainStatement)
555496
.add("<br>Therefore, the returned value might be different at each call.\n")
556-
.add(getThreadSafetyComment())
557497
.add("@return a non-null value\n")
558498
.build())
559499
.addModifiers(PUBLIC, STATIC)
@@ -565,19 +505,14 @@ private MethodSpec newLoadMethod(String className, TypeName quantifierType, Meth
565505
return result.build();
566506
}
567507

568-
569508
private Optional<FieldSpec> getIdPatternField() {
570-
return ids.size() == 1 && !ids.get(0).getPattern().isEmpty() ? Optional.of(FieldSpec
571-
.builder(Pattern.class, "ID_PATTERN")
572-
.addModifiers(PUBLIC, STATIC, FINAL)
573-
.initializer("$T.compile(\"$N\")", Pattern.class, ids.get(0).getPattern())
574-
.build()) : Optional.empty();
575-
}
576-
577-
private CodeBlock getThreadSafetyComment() {
578-
return definition.getLifecycle().isThreadSafe()
579-
? CodeBlock.of("<br>This method is thread-safe.\n")
580-
: CodeBlock.of("<br>This method is not thread-safe.\n");
509+
return ids.size() == 1 && !ids.get(0).getPattern().isEmpty()
510+
? Optional.of(FieldSpec
511+
.builder(Pattern.class, "ID_PATTERN")
512+
.addModifiers(PUBLIC, STATIC, FINAL)
513+
.initializer("$T.compile(\"$N\")", Pattern.class, ids.get(0).getPattern())
514+
.build())
515+
: Optional.empty();
581516
}
582517

583518
private static ParameterizedTypeName typeOf(Class<?> rawType, TypeName typeArgument) {

0 commit comments

Comments
 (0)