Skip to content

Instantly share code, notes, and snippets.

@pawellabaj
Last active July 20, 2023 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pawellabaj/c773e35a17e3f7f4d75d2829d75680df to your computer and use it in GitHub Desktop.
Save pawellabaj/c773e35a17e3f7f4d75d2829d75680df to your computer and use it in GitHub Desktop.
Example of generated record with all features provided by AutoRecord
import io.soabase.recordbuilder.core.RecordBuilder;
import pl.com.labaj.autorecord.AutoRecord;
import pl.com.labaj.autorecord.Ignored;
import pl.com.labaj.autorecord.Memoized;
import pl.com.labaj.autorecord.extension.compact.LoggingExtension;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
@AutoRecord
@AutoRecord.Options(withBuilder = true, memoizedHashCode = true, memoizedToString = true)
@RecordBuilder.Options(suffix = "_Builder")
@AutoRecord.Extension(extensionClass = LoggingExtension.class)
interface Full<D, H extends Comparable<H>> {
String name();
Map<D, H> aMap();
int size();
@Nullable
@Ignored
Long nullableProperty();
List<D> genericCollection();
String[] arrayProperty();
D[] genericArrayProperty();
@Ignored
Supplier<H> hSupplier();
@Memoized
default H genericSlowProcessingMethod() {
return hSupplier().get();
}
@Memoized
default boolean booleanSlowProcessingMethod() {
return true;
}
static <A extends CharSequence, B extends Comparable<B>> FullRecord_Builder<A, B> builder() {
return FullRecord_Builder.builder();
}
FullRecord_Builder<D, H> toBuilder();
}
import io.soabase.recordbuilder.core.RecordBuilder;
import pl.com.labaj.autorecord.GeneratedWithAutoRecord;
import pl.com.labaj.autorecord.Ignored;
import pl.com.labaj.autorecord.Memoized;
import pl.com.labaj.autorecord.memoizer.BooleanMemoizer;
import pl.com.labaj.autorecord.memoizer.IntMemoizer;
import pl.com.labaj.autorecord.memoizer.Memoizer;
import javax.annotation.Nullable;
import javax.annotation.processing.Generated;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
import static java.util.Objects.hash;
import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNullElseGet;
import static java.util.logging.Level.FINE;
import static java.util.logging.Logger.getLogger;
@Generated("pl.com.labaj.autorecord.AutoRecord")
@GeneratedWithAutoRecord
@RecordBuilder
@RecordBuilder.Options(
addClassRetainedGenerated = true,
suffix = "_Builder"
)
record FullRecord<D, H extends Comparable<H>>(String name,
Map<D, H> aMap,
int size,
@Nullable @Ignored Long nullableProperty,
List<D> genericCollection,
String[] arrayProperty,
D[] genericArrayProperty,
@Ignored Supplier<H> hSupplier,
@Nullable IntMemoizer hashCodeMemoizer,
@Nullable Memoizer<String> toStringMemoizer,
@Nullable Memoizer<H> genericSlowProcessingMethodMemoizer,
@Nullable BooleanMemoizer booleanSlowProcessingMethodMemoizer) implements Full<D, H> {
FullRecord {
// pl.com.labaj.autorecord.extension.compact.LoggingExtension
var map = new HashMap<String, Object>();
map.put("name", name);
map.put("aMap", aMap);
map.put("size", size);
map.put("nullableProperty", nullableProperty);
map.put("genericCollection", genericCollection);
map.put("arrayProperty", arrayProperty);
map.put("genericArrayProperty", genericArrayProperty);
map.put("hSupplier", hSupplier);
var logger = getLogger(FullRecord.class.getName());
logger.log(FINE, "Parameters passed to record: {0}", map);
// pl.com.labaj.autorecord.processor.AutoRecordProcessor
requireNonNull(name, "name must not be null");
requireNonNull(aMap, "aMap must not be null");
requireNonNull(genericCollection, "genericCollection must not be null");
requireNonNull(arrayProperty, "arrayProperty must not be null");
requireNonNull(genericArrayProperty, "genericArrayProperty must not be null");
requireNonNull(hSupplier, "hSupplier must not be null");
hashCodeMemoizer = requireNonNullElseGet(hashCodeMemoizer, IntMemoizer::new);
toStringMemoizer = requireNonNullElseGet(toStringMemoizer, Memoizer::new);
genericSlowProcessingMethodMemoizer = requireNonNullElseGet(genericSlowProcessingMethodMemoizer, Memoizer::new);
booleanSlowProcessingMethodMemoizer = requireNonNullElseGet(booleanSlowProcessingMethodMemoizer, BooleanMemoizer::new);
}
FullRecord(String name,
Map<D, H> aMap,
int size,
@Nullable @Ignored Long nullableProperty,
List<D> genericCollection,
String[] arrayProperty,
D[] genericArrayProperty,
@Ignored Supplier<H> hSupplier) {
this(name,
aMap,
size,
nullableProperty,
genericCollection,
arrayProperty,
genericArrayProperty,
hSupplier,
new IntMemoizer(),
new Memoizer<>(),
new Memoizer<>(),
new BooleanMemoizer());
}
@Memoized
@Override
public int hashCode() {
return hashCodeMemoizer.computeAsIntIfAbsent(this::_hashCode);
}
@Memoized
@Override
public String toString() {
return toStringMemoizer.computeIfAbsent(this::_toString);
}
@Memoized
@Override
public H genericSlowProcessingMethod() {
return genericSlowProcessingMethodMemoizer.computeIfAbsent(Full.super::genericSlowProcessingMethod);
}
@Memoized
@Override
public boolean booleanSlowProcessingMethod() {
return booleanSlowProcessingMethodMemoizer.computeAsBooleanIfAbsent(Full.super::booleanSlowProcessingMethod);
}
private int _hashCode() {
return hash(name, aMap, size, genericCollection, Arrays.hashCode(arrayProperty), Arrays.hashCode(genericArrayProperty));
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null) {
return false;
}
if (!(other instanceof FullRecord)) {
return false;
}
if (hashCode() != other.hashCode()) {
return false;
}
var otherRecord = (FullRecord) other;
return Objects.equals(name, otherRecord.name)
&& Objects.equals(aMap, otherRecord.aMap)
&& Objects.equals(size, otherRecord.size)
&& Objects.equals(genericCollection, otherRecord.genericCollection)
&& Arrays.equals(arrayProperty, otherRecord.arrayProperty)
&& Arrays.equals(genericArrayProperty, otherRecord.genericArrayProperty);
}
private String _toString() {
return "FullRecord[" +
"name = " + name + ", " +
"aMap = " + aMap + ", " +
"size = " + size + ", " +
"nullableProperty = " + nullableProperty + ", " +
"genericCollection = " + genericCollection + ", " +
"arrayProperty = " + Arrays.toString(arrayProperty) + ", " +
"genericArrayProperty = " + Arrays.toString(genericArrayProperty) + ", " +
"hSupplier = " + hSupplier +
"]";
}
static <D, H extends Comparable<H>> FullRecord_Builder<D, H> builder() {
return FullRecord_Builder.<D, H>builder()
.hashCodeMemoizer(new IntMemoizer())
.toStringMemoizer(new Memoizer<>())
.genericSlowProcessingMethodMemoizer(new Memoizer<>())
.booleanSlowProcessingMethodMemoizer(new BooleanMemoizer());
}
@Override
public FullRecord_Builder<D, H> toBuilder() {
return FullRecord_Builder.<D, H>builder(this)
.hashCodeMemoizer(new IntMemoizer())
.toStringMemoizer(new Memoizer<>())
.genericSlowProcessingMethodMemoizer(new Memoizer<>())
.booleanSlowProcessingMethodMemoizer(new BooleanMemoizer());
}
}
package pl.com.labaj.autorecord.extension.compact;
import com.squareup.javapoet.CodeBlock;
import pl.com.labaj.autorecord.context.Context;
import pl.com.labaj.autorecord.context.RecordComponent;
import pl.com.labaj.autorecord.context.StaticImports;
import pl.com.labaj.autorecord.extension.CompactConstructorExtension;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.logging.Level.FINE;
public class LoggingExtension implements CompactConstructorExtension {
private Level level;
@Override
public void setParameters(String[] parameters) {
if (parameters.length < 1) {
level = FINE;
} else {
level = Level.parse(parameters[0].toUpperCase());
}
}
@Override
public boolean shouldGenerate(boolean isGeneratedByProcessor, Context context) {
return true;
}
@Override
public CodeBlock prefixCompactConstructorContent(Context context, StaticImports staticImports) {
var codeBuilder = CodeBlock.builder();
codeBuilder.addStatement("var map = new $T<$T, $T>()", HashMap.class, String.class, Object.class);
context.components().stream()
.map(RecordComponent::name)
.forEach(name -> codeBuilder.addStatement("map.put($S, $L)", name, name));
codeBuilder.addStatement("var logger = getLogger($L.class.getName())", context.recordName())
.addStatement("logger.log($L, $S, $L)", level, "Parameters passed to record: {0}", "map");
staticImports.add(Logger.class, "getLogger")
.add(Level.class, level.getName());
return codeBuilder.build();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment