else if (!desc.registered()) { if (!desc.userType()) { BinaryClassDescriptor desc0 = new BinaryClassDescriptor( this, desc.describedClass(), false, desc.typeId(), desc.typeName(), desc.affFieldKeyName(), desc.mapper(), desc.initialSerializer(), false, true desc0.schema() != null ? Collections.singleton(desc.schema()) : null; BinaryMetadata meta = new BinaryMetadata(desc0.typeId(), desc0.typeName(), desc0.fieldsMeta(), desc0.affFieldKeyName(), schemas, desc0.isEnum(), cls.isEnum() ? enumMap(cls) : null); metaHnd.addMeta(desc0.typeId(), meta.wrap(this), false);
ctor = constructor(cls); fields = null; stableFieldsMeta = null; Set<String> duplicates = duplicateFields(cls); if (serializeField(f)) { f.setAccessible(true);
throw new BinaryObjectException("Object is not binary: [class=" + cls + ']'); if (desc.excluded()) { out.writeByte(GridBinaryMarshaller.NULL); if (desc.useOptimizedMarshaller()) { out.writeByte(GridBinaryMarshaller.OPTM_MARSH); if (enableReplace && desc.isWriteReplace()) { Object replacedObj = desc.writeReplace(obj); desc.write(obj, this);
/** * Register user types schemas. */ public void registerUserTypesSchema() { for (BinaryClassDescriptor desc : predefinedTypes.values()) { if (desc.userType()) desc.registerStableSchema(); } }
/** * Creates and registers {@link BinaryClassDescriptor} for the given user {@code class}. * * @param desc Old descriptor that should be re-registered. * @return Class descriptor. */ private BinaryClassDescriptor registerUserClassDescriptor(BinaryClassDescriptor desc) { boolean registered; registered = registerUserClassName(desc.typeId(), desc.describedClass().getName()); if (registered) { BinarySerializer serializer = desc.initialSerializer(); if (serializer == null) serializer = serializerForClass(desc.describedClass()); desc = new BinaryClassDescriptor( this, desc.describedClass(), true, desc.typeId(), desc.typeName(), desc.affFieldKeyName(), desc.mapper(), serializer, true, true ); descByCls.put(desc.describedClass(), desc); } return desc; }
/** * @param val Value. */ void doWriteEnum(@Nullable Enum<?> val) { if (val == null) out.writeByte(GridBinaryMarshaller.NULL); else { BinaryClassDescriptor desc = ctx.descriptorForClass(val.getDeclaringClass(), false, failIfUnregistered); out.unsafeEnsure(1 + 4); out.unsafeWriteByte(GridBinaryMarshaller.ENUM); if (desc.registered()) out.unsafeWriteInt(desc.typeId()); else { out.unsafeWriteInt(GridBinaryMarshaller.UNREGISTERED_TYPE_ID); doWriteString(val.getDeclaringClass().getName()); } out.writeInt(val.ordinal()); } }
/** * @throws Exception If failed. */ @Test public void testCustomTypeRegistration() throws Exception { BinaryTypeConfiguration customType = new BinaryTypeConfiguration(Value.class.getName()); BinaryMarshaller marsh = binaryMarshaller(Arrays.asList(customType)); BinaryContext ctx = binaryContext(marsh); int typeId = ctx.typeId(Value.class.getName()); BinaryClassDescriptor descriptor = ctx.descriptorForTypeId(true, typeId, null, false); assertEquals(Value.class, descriptor.describedClass()); assertEquals(true, descriptor.registered()); assertEquals(true, descriptor.userType()); // Custom explicit types must be registered in 'predefinedTypes' in order not to break the interoperability. Field field = ctx.getClass().getDeclaredField("predefinedTypes"); field.setAccessible(true); Map<Integer, BinaryClassDescriptor> map = (Map<Integer, BinaryClassDescriptor>)field.get(ctx); assertTrue(!map.isEmpty()); assertNotNull(map.get(typeId)); // Custom explicit types must NOT be registered in 'predefinedTypeNames'. field = ctx.getClass().getDeclaredField("predefinedTypeNames"); field.setAccessible(true); Map<String, Integer> map2 = (Map<String, Integer>)field.get(ctx); assertTrue(!map2.isEmpty()); assertNull(map2.get(ctx.userTypeName(Value.class.getName()))); }
/** * @param cls type to examine. * @return true if typeId equals for passed type and current * binary enum. */ public boolean isTypeEquals(final Class<?> cls) { return ctx.descriptorForClass(cls, false, false).typeId() == typeId(); } }
/** * @throws Exception If failed. */ @Test public void testPredefinedTypeIds() throws Exception { BinaryMarshaller marsh = binaryMarshaller(); BinaryContext bCtx = binaryContext(marsh); Field field = bCtx.getClass().getDeclaredField("predefinedTypeNames"); field.setAccessible(true); Map<String, Integer> map = (Map<String, Integer>)field.get(bCtx); assertTrue(!map.isEmpty()); for (Map.Entry<String, Integer> entry : map.entrySet()) { int id = entry.getValue(); if (id == GridBinaryMarshaller.UNREGISTERED_TYPE_ID) continue; BinaryClassDescriptor desc = bCtx.descriptorForTypeId(false, entry.getValue(), null, false); assertEquals(desc.typeId(), bCtx.typeId(desc.describedClass().getName())); } }
BinaryClassDescriptor desc = new BinaryClassDescriptor(this, cls, true, metaHnd.addMeta(typeId, new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, null, desc.isEnum(), cls.isEnum() ? enumMap(cls) : null).wrap(this), false);
/** * Unregisters the user types descriptors. **/ public void unregisterUserTypeDescriptors() { Iterator<Map.Entry<Class<?>, BinaryClassDescriptor>> it = descByCls.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Class<?>, BinaryClassDescriptor> e = it.next(); if (e.getValue().userType()) it.remove(); } }
/** * Resolve the class. * * @param ctx Binary context. * @param typeId Type ID. * @param clsName Class name. * @param ldr Class loaded. * @return Resovled class. */ public static Class resolveClass(BinaryContext ctx, int typeId, @Nullable String clsName, @Nullable ClassLoader ldr, boolean deserialize) { Class cls; if (typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID) cls = ctx.descriptorForTypeId(true, typeId, ldr, deserialize).describedClass(); else { try { cls = U.forName(clsName, ldr); } catch (ClassNotFoundException e) { throw new BinaryInvalidTypeException("Failed to load the class: " + clsName, e); } // forces registering of class by type id, at least locally ctx.descriptorForClass(cls, true, false); } return cls; }
BinaryClassDescriptor desc = new BinaryClassDescriptor( this, cls, ); fieldsMeta = desc.fieldsMeta();
serializer = new BinaryReflectiveSerializer(); desc = new BinaryClassDescriptor(this, cls, false,
/** * Creates and registers {@link BinaryClassDescriptor} for the given user {@code class}. * * @param desc Old descriptor that should be re-registered. * @return Class descriptor. */ private BinaryClassDescriptor registerUserClassDescriptor(BinaryClassDescriptor desc) { boolean registered; registered = registerUserClassName(desc.typeId(), desc.describedClass().getName()); if (registered) { BinarySerializer serializer = desc.initialSerializer(); if (serializer == null) serializer = serializerForClass(desc.describedClass()); desc = new BinaryClassDescriptor( this, desc.describedClass(), true, desc.typeId(), desc.typeName(), desc.affFieldKeyName(), desc.mapper(), serializer, true, true ); descByCls.put(desc.describedClass(), desc); } return desc; }
/** * @param val Array. */ void doWriteEnumArray(@Nullable Object[] val) { assert val == null || val.getClass().getComponentType().isEnum(); if (val == null) out.writeByte(GridBinaryMarshaller.NULL); else { BinaryClassDescriptor desc = ctx.descriptorForClass( val.getClass().getComponentType(), false, failIfUnregistered); out.unsafeEnsure(1 + 4); out.unsafeWriteByte(GridBinaryMarshaller.ENUM_ARR); if (desc.registered()) out.unsafeWriteInt(desc.typeId()); else { out.unsafeWriteInt(GridBinaryMarshaller.UNREGISTERED_TYPE_ID); doWriteString(val.getClass().getComponentType().getName()); } out.writeInt(val.length); // TODO: Denis: Redundant data for each element of the array. for (Object o : val) doWriteEnum((Enum<?>)o); } }
desc = registerClassDescriptor(cls, deserialize); assert desc.typeId() == typeId : "Duplicate typeId [typeId=" + typeId + ", cls=" + cls + ", desc=" + desc + "]";
/** * Register user types schemas. */ public void registerUserTypesSchema() { for (BinaryClassDescriptor desc : predefinedTypes.values()) { if (desc.userType()) desc.registerStableSchema(); } }
BinaryClassDescriptor desc = new BinaryClassDescriptor(this, cls, true, metaHnd.addMeta(typeId, new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, null, desc.isEnum(), cls.isEnum() ? enumMap(cls) : null).wrap(this), false);
/** * Undeployment callback invoked when class loader is being undeployed. * * Some marshallers may want to clean their internal state that uses the undeployed class loader somehow. * * @param ldr Class loader being undeployed. */ public void onUndeploy(ClassLoader ldr) { for (Iterator<Map.Entry<Class<?>, BinaryClassDescriptor>> it = descByCls.entrySet().iterator(); it.hasNext();) { Map.Entry<Class<?>, BinaryClassDescriptor> e = it.next(); // Never undeploy system types. if (e.getValue().userType()) { if (ldr.equals(e.getKey().getClassLoader())) it.remove(); } } U.clearClassCache(ldr); }