+abstract class CodecDataObjectGenerator<T extends CodecDataObject<?>> implements ClassGenerator<T> {
+ // Not reusable definition: we can inline NodeContextSuppliers without a problem
+ // FIXME: MDSAL-443: wire this implementation, which requires that BindingRuntimeTypes provides information about
+ // types being generated from within a grouping
+ private static final class Fixed<T extends CodecDataObject<?>> extends CodecDataObjectGenerator<T>
+ implements NodeContextSupplierProvider<T> {
+ private final ImmutableMap<Method, NodeContextSupplier> properties;
+
+ Fixed(final TypeDescription superClass, final ImmutableMap<Method, NodeContextSupplier> properties,
+ final @Nullable Method keyMethod) {
+ super(superClass, keyMethod);
+ this.properties = requireNonNull(properties);
+ }
+
+ @Override
+ Builder<T> generateGetters(final Builder<T> builder) {
+ Builder<T> tmp = builder;
+ for (Method method : properties.keySet()) {
+ LOG.trace("Generating for fixed method {}", method);
+ final String methodName = method.getName();
+ final TypeDescription retType = TypeDescription.ForLoadedType.of(method.getReturnType());
+ tmp = tmp.defineMethod(methodName, retType, PUB_FINAL).intercept(
+ new SupplierGetterMethodImplementation(methodName, retType));
+ }
+ return tmp;
+ }
+
+ @Override
+ public NodeContextSupplier resolveNodeContextSupplier(final String methodName) {
+ final Optional<Entry<Method, NodeContextSupplier>> found = properties.entrySet().stream()
+ .filter(entry -> methodName.equals(entry.getKey().getName())).findAny();
+ verify(found.isPresent(), "Failed to find property for %s in %s", methodName, this);
+ return verifyNotNull(found.get().getValue());
+ }
+ }
+
+ // Reusable definition: we have to rely on context lookups
+ private static final class Reusable<T extends CodecDataObject<?>> extends CodecDataObjectGenerator<T>
+ implements LocalNameProvider<T> {
+ private final ImmutableMap<Method, ValueNodeCodecContext> simpleProperties;
+ private final Map<Method, Class<?>> daoProperties;
+
+ Reusable(final TypeDescription superClass, final ImmutableMap<Method, ValueNodeCodecContext> simpleProperties,
+ final Map<Method, Class<?>> daoProperties, final @Nullable Method keyMethod) {
+ super(superClass, keyMethod);
+ this.simpleProperties = requireNonNull(simpleProperties);
+ this.daoProperties = requireNonNull(daoProperties);
+ }
+
+ @Override
+ Builder<T> generateGetters(final Builder<T> builder) {
+ Builder<T> tmp = builder;
+ for (Method method : simpleProperties.keySet()) {
+ LOG.trace("Generating for simple method {}", method);
+ final String methodName = method.getName();
+ final TypeDescription retType = TypeDescription.ForLoadedType.of(method.getReturnType());
+ tmp = tmp.defineMethod(methodName, retType, PUB_FINAL).intercept(
+ new SimpleGetterMethodImplementation(methodName, retType));
+ }
+ for (Entry<Method, Class<?>> entry : daoProperties.entrySet()) {
+ final Method method = entry.getKey();
+ LOG.trace("Generating for structured method {}", method);
+ final String methodName = method.getName();
+ final TypeDescription retType = TypeDescription.ForLoadedType.of(method.getReturnType());
+ tmp = tmp.defineMethod(methodName, retType, PUB_FINAL).intercept(
+ new StructuredGetterMethodImplementation(methodName, retType, entry.getValue()));
+ }
+
+ return tmp;
+ }
+
+ @Override
+ public String resolveLocalName(final String methodName) {
+ final Optional<Entry<Method, ValueNodeCodecContext>> found = simpleProperties.entrySet().stream()
+ .filter(entry -> methodName.equals(entry.getKey().getName())).findAny();
+ verify(found.isPresent(), "Failed to find property for %s in %s", methodName, this);
+ return found.get().getValue().getSchema().getQName().getLocalName();
+ }
+ }
+