/* * Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved. * * 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 com.hazelcast.nio.serialization; import com.hazelcast.internal.serialization.impl.ClassDefinitionImpl; import com.hazelcast.internal.serialization.impl.FieldDefinitionImpl; import java.util.ArrayList; import java.util.List; /** * ClassDefinitionBuilder is used to build and register ClassDefinitions manually. * * @see ClassDefinition * @see com.hazelcast.nio.serialization.Portable * @see com.hazelcast.config.SerializationConfig#addClassDefinition(ClassDefinition) */ public final class ClassDefinitionBuilder { private final int factoryId; private final int classId; private final int version; private final List<FieldDefinitionImpl> fieldDefinitions = new ArrayList<FieldDefinitionImpl>(); private int index; private boolean done; /** * IMPORTANT: It uses a default portableVersion (0) for non-versioned classes. * Make sure to specify the portableVersion in the constructor if you override the default portableVersion * in the SerializationService * * @param factoryId factoryId to use * @param classId classId to use */ public ClassDefinitionBuilder(int factoryId, int classId) { this.factoryId = factoryId; this.classId = classId; this.version = 0; } /** * IMPORTANT: Make sure that the version matches the portableVersion in the SerializationService * * @param factoryId factoryId to use * @param classId classId to use * @param version portableVersion to use */ public ClassDefinitionBuilder(int factoryId, int classId, int version) { this.factoryId = factoryId; this.classId = classId; this.version = version; } public ClassDefinitionBuilder addIntField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.INT, version)); return this; } public ClassDefinitionBuilder addLongField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.LONG, version)); return this; } public ClassDefinitionBuilder addUTFField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.UTF, version)); return this; } public ClassDefinitionBuilder addBooleanField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.BOOLEAN, version)); return this; } public ClassDefinitionBuilder addByteField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.BYTE, version)); return this; } public ClassDefinitionBuilder addBooleanArrayField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.BOOLEAN_ARRAY, version)); return this; } public ClassDefinitionBuilder addCharField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.CHAR, version)); return this; } public ClassDefinitionBuilder addDoubleField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.DOUBLE, version)); return this; } public ClassDefinitionBuilder addFloatField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.FLOAT, version)); return this; } public ClassDefinitionBuilder addShortField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.SHORT, version)); return this; } public ClassDefinitionBuilder addByteArrayField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.BYTE_ARRAY, version)); return this; } public ClassDefinitionBuilder addCharArrayField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.CHAR_ARRAY, version)); return this; } public ClassDefinitionBuilder addIntArrayField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.INT_ARRAY, version)); return this; } public ClassDefinitionBuilder addLongArrayField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.LONG_ARRAY, version)); return this; } public ClassDefinitionBuilder addDoubleArrayField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.DOUBLE_ARRAY, version)); return this; } public ClassDefinitionBuilder addFloatArrayField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.FLOAT_ARRAY, version)); return this; } public ClassDefinitionBuilder addShortArrayField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.SHORT_ARRAY, version)); return this; } public ClassDefinitionBuilder addUTFArrayField(String fieldName) { check(); fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.UTF_ARRAY, version)); return this; } public ClassDefinitionBuilder addPortableField(String fieldName, ClassDefinition def) { check(); if (def.getClassId() == 0) { throw new IllegalArgumentException("Portable class id cannot be zero!"); } fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.PORTABLE, def.getFactoryId(), def.getClassId(), def.getVersion())); return this; } public ClassDefinitionBuilder addPortableArrayField(String fieldName, ClassDefinition def) { check(); if (def.getClassId() == 0) { throw new IllegalArgumentException("Portable class id cannot be zero!"); } fieldDefinitions.add(new FieldDefinitionImpl(index++, fieldName, FieldType.PORTABLE_ARRAY, def.getFactoryId(), def.getClassId(), def.getVersion())); return this; } public ClassDefinitionBuilder addField(FieldDefinitionImpl fieldDefinition) { check(); if (index != fieldDefinition.getIndex()) { throw new IllegalArgumentException("Invalid field index"); } index++; fieldDefinitions.add(fieldDefinition); return this; } public ClassDefinition build() { done = true; final ClassDefinitionImpl cd = new ClassDefinitionImpl(factoryId, classId, version); for (FieldDefinitionImpl fd : fieldDefinitions) { cd.addFieldDef(fd); } return cd; } private void check() { if (done) { throw new HazelcastSerializationException("ClassDefinition is already built for " + classId); } } public int getFactoryId() { return factoryId; } public int getClassId() { return classId; } public int getVersion() { return version; } }