You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@river.apache.org by Peter Firmstone <pe...@zeus.net.au> on 2021/02/10 06:15:12 UTC

Public Serialization API to support other serialization frameworks.

Hello River Folk,

This is a concept test class, for testing a Public Serialization API, 
for supporting alternative serialization frameworks.  Note this doesn't 
implement Serializable for clarity.

-- 
Regards,
  
Peter

/*
  * Copyright 2021 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
package tests.support;

import java.io.IOException;
import java.io.ObjectStreamField;
import java.util.Arrays;
import java.util.Objects;
import org.apache.river.api.io.AtomicSerial;
import org.apache.river.api.io.AtomicSerial.GetArg;
import org.apache.river.api.io.AtomicSerial.PutArg;

/**
  *
  * @author peter
  */
@AtomicSerial
public class SerializableTestObject {

     /**
      * Names of serial fields.  Note how these names are unrelated to field
      * names.  If we refactor field names, and rename them, the Strings
      * representing serial fields don't change and the serial form of the
      * class is not broken.
      */
     private static final String TEST_STR = "testString";
     private static final String TEST_ARRY = "testArray";
     private static final String TEST_INT = "testInt";

     /**
      * serialPersistentFields.
      *
      * This method will be used by serialization frameworks to get names
      * and types of serial fields.  These will ensure type checking occurs
      * during de-serialization, fields will be de-serialized and 
created prior
      * to the instantiation of the parent object.
      *
      * @return array of ObjectStreamFields
      */
     public static ObjectStreamField [] serialPersistentFields() {
         return new ObjectStreamField []{
             new ObjectStreamField(TEST_STR, String.class),
             new ObjectStreamField(TEST_ARRY, long [].class),
             new ObjectStreamField(TEST_INT, int.class)
         };
     }

     public static void serialize(PutArg args, SerializableTestObject 
obj) throws IOException{
         args.put(TEST_STR, obj.str);
         args.put(TEST_ARRY, obj.longs);
         args.put(TEST_INT, obj.integer);
         args.writeFields();
     }

     /**
      * Invariant validation
      * @param args
      * @return
      * @throws IOException
      * @throws ClassNotFoundException
      */
     private static GetArg check(GetArg args) throws IOException, 
ClassNotFoundException{
         args.get(TEST_STR, null, String.class); // check String class type.
         args.get(TEST_ARRY, null, long [].class); // check array class 
type.
         // don't need to test int class type, but if there are other 
invariants
         // we check them here.
         return args;
     }

     /**
      * AtomicSerial constructor.
      * @param args
      * @throws IOException
      * @throws ClassNotFoundException
      */
     public SerializableTestObject(GetArg args) throws IOException, 
ClassNotFoundException{
         this(check(args).get(TEST_STR, "default", String.class),
                     args.get(TEST_ARRY, new long [0], long [].class),
                     args.get(TEST_INT, 0)
                 );
     }


     private final String str;
     private final long[] longs;
     private final int integer;


     public SerializableTestObject(String str, long [] longs, int integer){
         this.str = str;
         this.longs = longs.clone();
         this.integer = integer;
     }

     @Override
     public int hashCode() {
         int hash = 5;
         hash = 67 * hash + Objects.hashCode(this.str);
         hash = 67 * hash + Arrays.hashCode(this.longs);
         hash = 67 * hash + this.integer;
         return hash;
     }

     @Override
     public boolean equals(Object obj) {
         if (this == obj) {
             return true;
         }
         if (obj == null) {
             return false;
         }
         if (getClass() != obj.getClass()) {
             return false;
         }
         final SerializableTestObject other = (SerializableTestObject) obj;
         if (this.integer != other.integer) {
             return false;
         }
         if (!Objects.equals(this.str, other.str)) {
             return false;
         }
         return Arrays.equals(this.longs, other.longs);
     }


}