/** * Creates and registers {@link BinaryClassDescriptor} for the given {@code class}. * * @param cls Class. * @return Class descriptor. */ private BinaryClassDescriptor registerClassDescriptor(Class<?> cls, boolean deserialize) { BinaryClassDescriptor desc; String clsName = cls.getName(); if (marshCtx.isSystemType(clsName)) { desc = new BinaryClassDescriptor( this, cls, false, clsName.hashCode(), clsName, null, BinaryInternalIdMapper.defaultInstance(), null, false, true /* registered */); BinaryClassDescriptor old = descByCls.putIfAbsent(cls, desc); if (old != null) desc = old; } else desc = registerUserClassDescriptor(cls, deserialize); return desc; }
/** * Check whether class must be deserialized anyway. * * @param cls Class. * @return {@code True} if must be deserialized. */ public boolean mustDeserialize(Class cls) { BinaryClassDescriptor desc = descByCls.get(cls); if (desc == null) return marshCtx.isSystemType(cls.getName()) || serializerForClass(cls) == null; else return desc.useOptimizedMarshaller(); }
/** * @param typeName Type name. * @return Type ID. */ public int typeId(String typeName) { String typeName0 = typeName(typeName); Integer id = predefinedTypeNames.get(typeName0); if (id != null) return id; if (marshCtx.isSystemType(typeName)) return typeName.hashCode(); return userTypeIdMapper(typeName0).typeId(typeName0); }
/** * Creates and registers {@link BinaryClassDescriptor} for the given user {@code class}. * * @param cls Class. * @return Class descriptor. */ private BinaryClassDescriptor registerUserClassDescriptor(Class<?> cls, boolean deserialize) { boolean registered; String typeName = typeName(cls.getName()); BinaryIdMapper idMapper = userTypeIdMapper(typeName); int typeId = idMapper.typeId(typeName); try { registered = marshCtx.registerClass(typeId, cls); } catch (IgniteCheckedException e) { throw new BinaryObjectException("Failed to register class.", e); } BinarySerializer serializer = serializerForClass(cls); String affFieldName = affinityFieldName(cls); BinaryClassDescriptor desc = new BinaryClassDescriptor( this, cls, true, typeId, typeName, affFieldName, idMapper, serializer, true, registered); if (!deserialize) { Collection<BinarySchema> schemas = desc.schema() != null ? Collections.singleton(desc.schema()) : null; metaHnd.addMeta( typeId, new BinaryMetadata( typeId, typeName, desc.fieldsMeta(), affFieldName, schemas, desc.isEnum()) .wrap(this)); } // perform put() instead of putIfAbsent() because "registered" flag might have been changed or // class loader // might have reloaded described class. if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr)) userTypes.put(typeId, desc); descByCls.put(cls, desc); mappers.putIfAbsent(typeId, idMapper); return desc; }
/** * @param userType User type or not. * @param typeId Type ID. * @param ldr Class loader. * @return Class descriptor. */ public BinaryClassDescriptor descriptorForTypeId( boolean userType, int typeId, ClassLoader ldr, boolean deserialize) { assert typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID; // TODO: As a workaround for IGNITE-1358 we always check the predefined map before without // checking 'userType' BinaryClassDescriptor desc = predefinedTypes.get(typeId); if (desc != null) return desc; if (ldr == null) ldr = dfltLdr; // If the type hasn't been loaded by default class loader then we mustn't return the descriptor // from here // giving a chance to a custom class loader to reload type's class. if (userType && ldr.equals(dfltLdr)) { desc = userTypes.get(typeId); if (desc != null) return desc; } Class cls; try { cls = marshCtx.getClass(typeId, ldr); desc = descByCls.get(cls); } catch (ClassNotFoundException e) { // Class might have been loaded by default class loader. if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr, deserialize)) != null) return desc; throw new BinaryInvalidTypeException(e); } catch (IgniteCheckedException e) { // Class might have been loaded by default class loader. if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr, deserialize)) != null) return desc; throw new BinaryObjectException("Failed resolve class for ID: " + typeId, e); } if (desc == null) { desc = registerClassDescriptor(cls, deserialize); assert desc.typeId() == typeId; } return desc; }