org.wildfly.clustering.marshalling.protostream.FieldSetMarshaller Maven / Gradle / Ivy
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/
package org.wildfly.clustering.marshalling.protostream;
import java.io.IOException;
import java.util.function.Supplier;
import org.infinispan.protostream.descriptors.WireType;
/**
* Marshaller for a set of fields, to be shared between multiple marshallers.
* @author Paul Ferraro
* @param the writer type
* @param the reader type
*/
public interface FieldSetMarshaller extends FieldReadable, Writable {
/**
* Returns a builder for use with {@link #readFrom(ProtoStreamReader, int, WireType, Object)}.
* May return a shared instance, if the builder type is immutable, or a new instance, if the builder is mutable.
* @return a builder.
*/
V createInitialValue();
/**
* Builds the target object from the read value.
* @param value a read value
* @return the target object
*/
T build(V value);
/**
* A simple field set marshaller whose reader and writer types are the same
* @param the marshaller type
*/
interface Simple extends FieldSetMarshaller {
@Override
default T build(T value) {
return value;
}
}
/**
* A field set marshaller whose reader type supplies the writer type.
* @param the writer type
* @param the reader type
*/
interface Supplied> extends FieldSetMarshaller {
@Override
default T build(V value) {
return value.get();
}
}
/**
* Creates a marshaller that reads and writes only the fields of this field set.
* @return a new marshaller
*/
@SuppressWarnings("unchecked")
default ProtoStreamMarshaller asMarshaller() {
return this.asMarshaller((Class) this.build(this.createInitialValue()).getClass());
}
/**
* Creates a marshaller that reads and writes only the fields of this field set.
* @param targetClass the marshaller type
* @return a new marshaller
*/
default ProtoStreamMarshaller asMarshaller(Class targetClass) {
FieldSetMarshaller marshaller = this;
return new ProtoStreamMarshaller<>() {
@Override
public Class extends T> getJavaClass() {
return targetClass;
}
@Override
public T readFrom(ProtoStreamReader reader) throws IOException {
FieldSetReader valueReader = reader.createFieldSetReader(marshaller, 1);
V value = marshaller.createInitialValue();
while (!reader.isAtEnd()) {
int tag = reader.readTag();
int index = WireType.getTagFieldNumber(tag);
if (valueReader.contains(index)) {
value = valueReader.readField(value);
} else {
reader.skipField(tag);
}
}
return marshaller.build(value);
}
@Override
public void writeTo(ProtoStreamWriter writer, T value) throws IOException {
writer.createFieldSetWriter(marshaller, 1).writeFields(value);
}
};
}
}