Search code examples
hazelcast

How do I make a class definition for an ArrayList<byte[]>


I am trying to make my class implement VersionedPortable. It has a field

ArrayList<byte[]> someMessages = new ArrayList<>();

How do I specify this field in my ClassDefiniton? I assume it would be something like

new ClassDefinitionBuilder(FACTORY_ID, MESSAGE_BUNDLE_CLASS_ID, VERSION_ID)
              .addPortableArrayField("someMessages", ?? what goes here ??)

And how would I read and write them?


Solution

  • Arrays of arrays are not supported in the Portable format by default. However, you can use the following trick to wrap the nested array as a separate Portable type and write your field as a Portable array.

    class Foo implements Portable {
    
        private ArrayList<byte[]> messages;
    
        @Override
        public int getFactoryId() {
            return 1;
        }
    
        @Override
        public int getClassId() {
            return 1;
        }
    
        @Override
        public void writePortable(PortableWriter writer) throws IOException {
            Portable[] wrappedMessages = messages.stream()
                    .map(ByteArrayWrapper::new)
                    .toArray(Portable[]::new);
            writer.writePortableArray("messages", wrappedMessages);
        }
    
        @Override
        public void readPortable(PortableReader reader) throws IOException {
            messages = Arrays.stream(reader.readPortableArray("messages"))
                    .map(item -> ((ByteArrayWrapper) item).getArray())
                    .collect(Collectors.toCollection(ArrayList::new));
        }
    }
    
    class ByteArrayWrapper implements Portable {
    
        private byte[] array;
    
        public ByteArrayWrapper() {
        }
    
        public ByteArrayWrapper(byte[] array) {
            this.array = array;
        }
    
        @Override
        public int getFactoryId() {
            return 1;
        }
    
        @Override
        public int getClassId() {
            return 2;
        }
    
        @Override
        public void writePortable(PortableWriter writer) throws IOException {
            writer.writeByteArray("array", array);
        }
    
        @Override
        public void readPortable(PortableReader reader) throws IOException {
            array = reader.readByteArray("array");
        }
    
        public byte[] getArray() {
            return array;
        }
    }