Compare commits

...

6 Commits

Author SHA1 Message Date
randgalt
d21994143f [maven-release-plugin] prepare release record-builder-1.5.ea 2019-12-24 18:43:10 -05:00
randgalt
f49089d26e Merge branch 'master' of github.com:Randgalt/record-builder 2019-12-24 12:34:08 -05:00
randgalt
e9a6e79e79 Added a component stream method 2019-12-24 12:34:02 -05:00
Jordan Zimmerman
f091e094e8 Update README.md 2019-12-23 09:38:36 -05:00
Jordan Zimmerman
72c9332b89 Update README.md 2019-12-23 09:37:47 -05:00
randgalt
41f1e5fa7e [maven-release-plugin] prepare for next development iteration 2019-12-22 13:21:26 -05:00
7 changed files with 85 additions and 22 deletions

View File

@@ -67,23 +67,6 @@ public class NameAndAgeBuilder {
return new NameAndAge(name, age);
}
@Override
public String toString() {
return "NameAndAgeBuilder[name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public boolean equals(Object o) {
return (this == o) || ((o instanceof NameAndAgeBuilder b)
&& Objects.equals(name, b.name)
&& (age == b.age));
}
/**
* Set a new value for the {@code name} record component in the builder
*/
@@ -113,6 +96,31 @@ public class NameAndAgeBuilder {
public int age() {
return age;
}
/**
* Return a stream of the record components as map entries keyed with the component name and the value as the component value
*/
public static Stream<Map.Entry<String, Object>> stream(NameAndAge record) {
return Stream.of(new AbstractMap.SimpleEntry<>("name", record.name()),
new AbstractMap.SimpleEntry<>("age", record.age()));
}
@Override
public String toString() {
return "NameAndAgeBuilder[name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public boolean equals(Object o) {
return (this == o) || ((o instanceof NameAndAgeBuilder b)
&& Objects.equals(name, b.name)
&& (age == b.age));
}
}
```
@@ -176,6 +184,14 @@ Note: records are a preview feature only. You'll need take a number of steps in
Note: I've seen some very odd compilation bugs with the current Java 14 and Maven. If you get internal Javac errors I suggest rebuilding with `mvn clean package` and/or `mvn clean install`.
## Customizing
The names of the generated methods, etc. are determined by [RecordBuilderMetaData](https://github.com/Randgalt/record-builder/blob/master/record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordBuilderMetaData.java). If you want to use your own meta data instance:
- Create a class that implements RecordBuilderMetaData
- When compiling, make sure that the compiled class is in the processor path
- Add a "metaDataClass" compiler option with the class name. E.g. `javac ... -AmetaDataClass=foo.bar.MyMetaData`
## TODOs
- Document how to integrate with Gradle

View File

@@ -5,7 +5,7 @@
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder</artifactId>
<packaging>pom</packaging>
<version>1.4.ea</version>
<version>1.5.ea</version>
<modules>
<module>record-builder-core</module>
@@ -70,7 +70,7 @@
<url>https://github.com/randgalt/record-builder</url>
<connection>scm:git:https://github.com/randgalt/record-builder.git</connection>
<developerConnection>scm:git:git@github.com:randgalt/record-builder.git</developerConnection>
<tag>record-builder-1.4.ea</tag>
<tag>record-builder-1.5.ea</tag>
</scm>
<issueManagement>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder</artifactId>
<version>1.4.ea</version>
<version>1.5.ea</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -68,6 +68,15 @@ public interface RecordBuilderMetaData {
return "build";
}
/**
* The name to use for the method that returns the record components as a stream
*
* @return build method
*/
default String componentsMethodName() {
return "stream";
}
/**
* Return the comment to place at the top of generated files. Return null or an empty string for no comment.
*

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder</artifactId>
<version>1.4.ea</version>
<version>1.5.ea</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -22,10 +22,13 @@ import javax.annotation.processing.Generated;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import java.util.AbstractMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
class InternalProcessor {
private static final AnnotationSpec generatedAnnotation = AnnotationSpec.builder(Generated.class).addMember("value", "$S", RecordBuilderProcessor.NAME).build();
@@ -55,6 +58,7 @@ class InternalProcessor {
addAllArgsConstructor();
addStaticDefaultBuilderMethod();
addStaticCopyBuilderMethod();
addStaticComponentsMethod();
addBuildMethod();
addToStringMethod();
addHashCodeMethod();
@@ -296,6 +300,40 @@ class InternalProcessor {
builder.addMethod(methodSpec);
}
private void addStaticComponentsMethod() {
/*
Adds a static method that converts a record instance into a stream of its component parts
public static Stream<Map.Entry<String, Object>> stream(MyRecord record) {
return Stream.of(
new AbstractMap.SimpleEntry<>("p1", record.p1()),
new AbstractMap.SimpleEntry<>("p2", record.p2())
);
}
*/
var codeBuilder = CodeBlock.builder().add("return $T.of(", Stream.class);
IntStream.range(0, recordComponents.size()).forEach(index -> {
if (index > 0) {
codeBuilder.add(",\n ");
}
var name = recordComponents.get(index).name();
codeBuilder.add("new $T<>($S, record.$L())", AbstractMap.SimpleEntry.class, name, name);
});
codeBuilder.add(")");
var mapEntryTypeVariables = ParameterizedTypeName.get(Map.Entry.class, String.class, Object.class);
var mapEntryType = ParameterizedTypeName.get(ClassName.get(Stream.class), mapEntryTypeVariables);
var methodSpec = MethodSpec.methodBuilder(metaData.componentsMethodName())
.addJavadoc("Return a stream of the record components as map entries keyed with the component name and the value as the component value\n")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(recordClassType.typeName(), "record")
.addAnnotation(generatedAnnotation)
.addTypeVariables(typeVariables)
.returns(mapEntryType)
.addStatement(codeBuilder.build())
.build();
builder.addMethod(methodSpec);
}
private void add1Field(ClassType component) {
/*
For a single record component, add a field similar to:

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder</artifactId>
<version>1.4.ea</version>
<version>1.5.ea</version>
</parent>
<modelVersion>4.0.0</modelVersion>