diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinariesFactory.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinariesFactory.java index 5b3462941be6f..135e1ad08978f 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinariesFactory.java +++ b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinariesFactory.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.function.ToIntFunction; import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.internal.binary.streams.BinaryInputStream; import org.apache.ignite.internal.binary.streams.BinaryOutputStream; import org.apache.ignite.internal.processors.cache.CacheObjectValueContext; @@ -35,42 +36,31 @@ public interface BinariesFactory { * * @param ctx Context. * @param in Input stream. - * @param ldr Class loader. + * @param ldr Custom class loader or {@code null} to use {@link BinaryContext#classLoader()}. + * @param hnds Reader handles or {@code null} to start a new handles context. + * @param skipHdrCheck Whether to skip header check. * @param forUnmarshal {@code True} if reader is needed to unmarshal object. */ - public BinaryReaderEx reader(BinaryContext ctx, BinaryInputStream in, ClassLoader ldr, boolean forUnmarshal); + public BinaryReaderEx reader( + BinaryContext ctx, + BinaryInputStream in, + @Nullable ClassLoader ldr, + @Nullable BinaryReaderHandles hnds, + boolean skipHdrCheck, + boolean forUnmarshal + ); /** - * Creates reader instance. + * Unmarshals object from the input stream without deserialization of user types. * - * @param ctx Context. * @param in Input stream. - * @param ldr Class loader. - * @param hnds Context. - * @param forUnmarshal {@code True} if reader is needed to unmarshal object. - */ - public BinaryReaderEx reader(BinaryContext ctx, - BinaryInputStream in, - ClassLoader ldr, - @Nullable BinaryReaderHandles hnds, - boolean forUnmarshal); - - /** - * Constructor. - * * @param ctx Context. - * @param in Input stream. * @param ldr Class loader. - * @param hnds Context. - * @param skipHdrCheck Whether to skip header check. - * @param forUnmarshal {@code True} if reader is needed to unmarshal object. + * @return Unmarshalled object. + * @throws BinaryObjectException In case of error. */ - public BinaryReaderEx reader(BinaryContext ctx, - BinaryInputStream in, - ClassLoader ldr, - @Nullable BinaryReaderHandles hnds, - boolean skipHdrCheck, - boolean forUnmarshal); + @Nullable public Object unmarshal(BinaryInputStream in, BinaryContext ctx, @Nullable ClassLoader ldr) + throws BinaryObjectException; /** * @param ctx Context. @@ -129,6 +119,14 @@ public BinaryReaderEx reader(BinaryContext ctx, */ public BinaryObjectEx binaryOffheapObject(BinaryContext ctx, long ptr, int start, int size); + /** + * @param ctx Context + * @param compCls Component class. + * @param arr Data. + * @return Binary array instance. + */ + public BinaryObjectEx binaryArray(BinaryContext ctx, Class compCls, Object[] arr); + /** * @return Binary enum class. */ @@ -139,6 +137,16 @@ public BinaryReaderEx reader(BinaryContext ctx, */ public Class binaryObjectImplClass(); + /** + * @return Binary array class. + */ + public Class binaryArrayClass(); + + /** + * @return Binary enum array class. + */ + public Class binaryEnumArrayClass(); + /** * @return Map of predefined types. */ diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java index 64450ca2b2182..6185eea136b99 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java +++ b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java @@ -25,6 +25,7 @@ import java.sql.Time; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -54,7 +55,6 @@ import org.apache.ignite.binary.BinaryIdMapper; import org.apache.ignite.binary.BinaryInvalidTypeException; import org.apache.ignite.binary.BinaryNameMapper; -import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.binary.BinaryReflectiveSerializer; import org.apache.ignite.binary.BinarySerializer; @@ -80,11 +80,22 @@ /** * Binary context. + * + *

Class loaders

+ * Binary code deals with exactly two kinds of class loaders: + * + * A {@code null} loader anywhere in the binary API means "use the default loader". + * Use {@link #resolveClassLoader(ClassLoader)} to turn a caller supplied loader into the one to actually use and + * {@link #isCustomLoader(ClassLoader)} to decide whether caching must be bypassed. */ public class BinaryContext { - /** System loader. */ - private static final ClassLoader sysLdr = CommonUtils.gridClassLoader(); - /** */ private static final BinaryInternalMapper DFLT_MAPPER = new BinaryInternalMapper(new BinaryBasicNameMapper(false), new BinaryBasicIdMapper(true), false); @@ -126,14 +137,14 @@ public class BinaryContext { /** Node name. */ private final @Nullable String igniteInstanceName; - /** Class loader. */ - private final @Nullable ClassLoader clsLdr; + /** Default class loader. Configured loader or the loader Ignite was loaded by. Never {@code null}. */ + private final ClassLoader clsLdr; /** Actual marshaller. */ - private BinaryMarshaller marsh; + private final BinaryMarshaller marsh; /** */ - private MarshallerContext marshCtx; + private final MarshallerContext marshCtx; /** */ private final @Nullable BinarySerializer dfltSerializer; @@ -160,7 +171,7 @@ public class BinaryContext { * @param metaHnd Meta data handler. * @param marsh Binary marshaller. * @param igniteInstanceName Ignite instance name. - * @param clsLdr Class loader. + * @param clsLdr Configured class loader or {@code null} to use the loader Ignite was loaded by. * @param dfltSerializer Binary serializer. * @param idMapper Binary id mapper. * @param nameMapper Binary name mapper. @@ -189,7 +200,7 @@ public BinaryContext( this.metaHnd = metaHnd; this.igniteInstanceName = igniteInstanceName; - this.clsLdr = clsLdr; + this.clsLdr = clsLdr != null ? clsLdr : CommonUtils.gridClassLoader(); this.dfltSerializer = dfltSerializer; if (idMapper != null || nameMapper != null || !F.isEmpty(typeCfgs)) @@ -260,8 +271,6 @@ public BinaryContext( registerPredefinedType(BinaryMetadata.class, 0); registerPredefinedType(BinaryTreeMap.class, 0); - registerPredefinedType(BinaryArray.class, 0); - registerPredefinedType(BinaryEnumArray.class, 0); BinaryUtils.binariesFactory.predefinedTypes().forEach(this::registerPredefinedType); @@ -279,8 +288,7 @@ public BinaryContext( if (marsh != null) { this.marsh = marsh; - - marshCtx = marsh.getContext(); + this.marshCtx = marsh.getContext(); assert marshCtx != null; @@ -288,6 +296,10 @@ public BinaryContext( configure(nameMapper, idMapper, dfltSerializer, typeCfgs, affFlds); } + else { + this.marsh = null; + this.marshCtx = null; + } } /** @@ -328,12 +340,43 @@ public String igniteInstanceName() { } /** - * @return Class loader. + * @return Default class loader. Configured loader or the loader Ignite was loaded by. Never {@code null}. */ public ClassLoader classLoader() { return clsLdr; } + /** + * @param ldr Caller supplied class loader or {@code null}. + * @return {@code ldr} if it is a custom loader, default loader otherwise. + * @see #isCustomLoader(ClassLoader) + */ + public ClassLoader resolveClassLoader(@Nullable ClassLoader ldr) { + return isCustomLoader(ldr) ? ldr : clsLdr; + } + + /** + * @param ldr Caller supplied class loader or {@code null}. + * @return {@code true} if {@code ldr} is a custom (deployment or user supplied) loader, + * {@code false} if it is {@code null}, the default loader or the loader Ignite was loaded by. + */ + public boolean isCustomLoader(@Nullable ClassLoader ldr) { + return ldr != null && ldr != clsLdr && ldr != CommonUtils.gridClassLoader(); + } + + /** + * @param clsName Class name. + * @return Class loaded by {@link #classLoader()} or {@code null} if it is not available to it. + */ + @Nullable private Class loadClassOrNull(String clsName) { + try { + return clsLdr.loadClass(clsName); + } + catch (ClassNotFoundException | NoClassDefFoundError ignored) { + return null; + } + } + /** * @param globalNameMapper Name mapper. * @param globalIdMapper ID mapper. @@ -373,7 +416,7 @@ private void configure( String affField = affFields.remove(clsName0); if (affField == null) { - Class cls = ClassLoaderUtils.classForName(clsName0); + Class cls = loadClassOrNull(clsName0); if (cls != null) affField = affFldNameProvider.apply(cls); @@ -387,7 +430,7 @@ private void configure( String affField = affFields.remove(clsName); if (affField == null) { - Class cls = ClassLoaderUtils.classForName(clsName); + Class cls = loadClassOrNull(clsName); if (cls != null) affField = affFldNameProvider.apply(cls); @@ -462,20 +505,24 @@ public static BinaryNameMapper defaultNameMapper() { } /** + * Lists classes of the package visible on the classpath of {@link #classLoader()}. + * When a custom loader is configured, the classpath Ignite itself was loaded from is scanned as well. + * * @param pkgName Package name. * @return Class names. */ @SuppressWarnings("ConstantConditions") - private static Iterable classesInPackage(String pkgName) { + private Iterable classesInPackage(String pkgName) { assert pkgName != null; Collection clsNames = new ArrayList<>(); - ClassLoader ldr = CommonUtils.gridClassLoader(); - String pkgPath = pkgName.replaceAll("\\.", "/"); - URL[] urls = CommonUtils.classLoaderUrls(ldr); + Collection urls = new LinkedHashSet<>(Arrays.asList(CommonUtils.classLoaderUrls(clsLdr))); + + if (clsLdr != CommonUtils.gridClassLoader()) + urls.addAll(Arrays.asList(CommonUtils.classLoaderUrls(CommonUtils.gridClassLoader()))); for (URL url : urls) { String proto = url.getProtocol().toLowerCase(); @@ -706,14 +753,14 @@ private BinaryClassDescriptor systemClassDescriptor(Class cls, String clsName /** * @param userType User type or not. * @param typeId Type ID. - * @param ldr Class loader. + * @param ldr Custom class loader or {@code null} to use {@link #classLoader()}. * @param registerMeta If {@code true}, then metadata will be registered along with the type descriptor. * @return Class descriptor. */ BinaryClassDescriptor descriptorForTypeId( boolean userType, int typeId, - ClassLoader ldr, + @Nullable ClassLoader ldr, boolean registerMeta ) { assert typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID; @@ -724,8 +771,7 @@ BinaryClassDescriptor descriptorForTypeId( if (desc != null) return desc; - if (ldr == null) - ldr = sysLdr; + ldr = resolveClassLoader(ldr); Class cls; @@ -752,15 +798,23 @@ BinaryClassDescriptor descriptorForTypeId( } catch (ClassNotFoundException e) { // Class might have been loaded by default class loader. - if (userType && !ldr.equals(sysLdr) && (desc = descriptorForTypeId(true, typeId, sysLdr, registerMeta)) != null) + if (userType + && ldr != null + && !ldr.equals(CommonUtils.gridClassLoader()) + && (desc = descriptorForTypeId(true, typeId, null, registerMeta)) != null) { return desc; + } throw new BinaryInvalidTypeException(e); } catch (IgniteCheckedException e) { // Class might have been loaded by default class loader. - if (userType && !ldr.equals(sysLdr) && (desc = descriptorForTypeId(true, typeId, sysLdr, registerMeta)) != null) + if (userType + && ldr != null + && !ldr.equals(CommonUtils.gridClassLoader()) + && (desc = descriptorForTypeId(true, typeId, null, registerMeta)) != null) { return desc; + } throw new BinaryObjectException("Failed resolve class for ID: " + typeId, e); } @@ -1115,14 +1169,7 @@ public void registerUserType(String clsName, @Nullable Map enumMap) throws BinaryObjectException { assert mapper != null; - Class cls = null; - - try { - cls = CommonUtils.resolveClassLoader(null, classLoader()).loadClass(clsName); - } - catch (ClassNotFoundException | NoClassDefFoundError ignored) { - // No-op. - } + Class cls = loadClassOrNull(clsName); String typeName = mapper.typeName(clsName); @@ -1512,34 +1559,6 @@ Collection predefinedTypes() { return Collections.unmodifiableCollection(predefinedTypes.values()); } - /** Creates instance of {@link BinaryArray}. */ - public BinaryObject createBinaryArray(Class compCls, Object[] pArr) { - boolean isBinaryArr = BinaryObject.class.isAssignableFrom(compCls); - - String compClsName = isBinaryArr ? Object.class.getName() : compCls.getName(); - - // In case of interface or multidimensional array rely on class name. - // Interfaces and array not registered as binary types. - BinaryClassDescriptor desc = descriptorForClass(compCls); - - if (compCls.isEnum() || compCls == BinaryUtils.binariesFactory.binaryEnumClass()) { - return new BinaryEnumArray( - this, - desc.registered() ? desc.typeId() : GridBinaryMarshaller.UNREGISTERED_TYPE_ID, - compClsName, - pArr - ); - } - else { - return new BinaryArray( - this, - desc.registered() ? desc.typeId() : GridBinaryMarshaller.UNREGISTERED_TYPE_ID, - compClsName, - pArr - ); - } - } - /** * Type descriptors. */ diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryObjectEx.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryObjectEx.java index f5d8d61d62e47..6dc99ed91b0d9 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryObjectEx.java +++ b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryObjectEx.java @@ -68,6 +68,11 @@ public default Object[] array() { throw new UnsupportedOperationException("Not array"); } + /** @return {@code true} if binary object stores array. */ + public default boolean isArray() { + return false; + } + /** * @return Enum class name. */ diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryReaderEx.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryReaderEx.java index 9b6c6688fb31d..8cf141fbd3839 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryReaderEx.java +++ b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryReaderEx.java @@ -27,7 +27,7 @@ /** * Extended reader interface. */ -public interface BinaryReaderEx extends BinaryReader, BinaryRawReader, BinaryReaderHandlesHolder, ObjectInput { +public interface BinaryReaderEx extends BinaryReader, BinaryRawReader, ObjectInput { /** * @return Object. * @throws org.apache.ignite.binary.BinaryObjectException In case of error. diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandlesHolder.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandlesHolder.java deleted file mode 100644 index 5308d9e0766c4..0000000000000 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandlesHolder.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.ignite.internal.binary; - -/** - * Holder for handles. - */ -interface BinaryReaderHandlesHolder { - /** - * Set handle. - * - * @param obj Object. - * @param pos Position. - */ - public void setHandle(Object obj, int pos); - - /** - * Get handle. - * - * @param pos Position. - * @return Handle. - */ - public Object getHandle(int pos); - - /** - * Get all handles. - * - * @return Handles. - */ - public BinaryReaderHandles handles(); - - /** */ - public boolean isEmpty(); -} diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandlesHolderImpl.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandlesHolderImpl.java deleted file mode 100644 index 6adb2f2f1a747..0000000000000 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandlesHolderImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.ignite.internal.binary; - -/** - * Simple holder for handles. - */ -class BinaryReaderHandlesHolderImpl implements BinaryReaderHandlesHolder { - /** Handles. */ - private BinaryReaderHandles hnds; - - /** {@inheritDoc} */ - @Override public void setHandle(Object obj, int pos) { - handles().put(pos, obj); - } - - /** {@inheritDoc} */ - @Override public Object getHandle(int pos) { - return hnds != null ? hnds.get(pos) : null; - } - - /** {@inheritDoc} */ - @Override public BinaryReaderHandles handles() { - if (hnds == null) - hnds = new BinaryReaderHandles(); - - return hnds; - } - - /** {@inheritDoc} */ - @Override public boolean isEmpty() { - return hnds == null || hnds.isEmpty(); - } -} diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java index 274d8addced0c..414341748c3a7 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java +++ b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java @@ -18,7 +18,6 @@ package org.apache.ignite.internal.binary; import java.io.BufferedReader; -import java.io.ByteArrayInputStream; import java.io.Externalizable; import java.io.File; import java.io.FileInputStream; @@ -26,14 +25,11 @@ import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.lang.reflect.Array; import java.lang.reflect.Field; -import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.math.BigDecimal; -import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.sql.Time; import java.sql.Timestamp; @@ -60,14 +56,10 @@ import java.util.function.Function; import java.util.function.IntFunction; import java.util.stream.Collectors; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteCommonsSystemProperties; import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteLogger; -import org.apache.ignite.binary.BinaryCollectionFactory; import org.apache.ignite.binary.BinaryIdMapper; -import org.apache.ignite.binary.BinaryInvalidTypeException; -import org.apache.ignite.binary.BinaryMapFactory; import org.apache.ignite.binary.BinaryNameMapper; import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.binary.BinaryObjectException; @@ -79,7 +71,6 @@ import org.apache.ignite.configuration.BinaryConfiguration; import org.apache.ignite.internal.binary.streams.BinaryInputStream; import org.apache.ignite.internal.binary.streams.BinaryOutputStream; -import org.apache.ignite.internal.marshaller.ClassLoaderUtils; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.CommonUtils; import org.apache.ignite.internal.util.MutableSingletonList; @@ -88,7 +79,6 @@ import org.apache.ignite.internal.util.typedef.internal.A; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.logger.NullLogger; -import org.apache.ignite.marshaller.Marshallers; import org.apache.ignite.platform.PlatformType; import org.jetbrains.annotations.Nullable; @@ -355,10 +345,10 @@ public static byte typeByClass(Class cls) { return cls.getComponentType().isEnum() || cls.getComponentType() == Enum.class ? GridBinaryMarshaller.ENUM_ARR : GridBinaryMarshaller.OBJ_ARR; - if (cls == BinaryArray.class) + if (cls == binariesFactory.binaryArrayClass()) return GridBinaryMarshaller.OBJ_ARR; - if (cls == BinaryEnumArray.class) + if (cls == binariesFactory.binaryEnumArrayClass()) return GridBinaryMarshaller.ENUM_ARR; if (isSpecialCollection(cls)) @@ -489,27 +479,6 @@ else if (cls == SINGLETON_LIST_CLS) return null; } - /** - * Check protocol version. - * - * @param protoVer Protocol version. - */ - public static void checkProtocolVersion(byte protoVer) { - if (GridBinaryMarshaller.PROTO_VER != protoVer) - throw new BinaryObjectException("Unsupported protocol version: " + protoVer); - } - - /** - * Get binary object length. - * - * @param in Input stream. - * @param start Start position. - * @return Length. - */ - public static int length(BinaryPositionReadable in, int start) { - return in.readIntPositioned(start + GridBinaryMarshaller.TOTAL_LEN_POS); - } - /** * Merge old and new metas. * @@ -721,9 +690,9 @@ else if (cls == Time[].class) return BinaryWriteMode.TIME_ARR; else if (cls.isArray()) return cls.getComponentType().isEnum() ? BinaryWriteMode.ENUM_ARR : BinaryWriteMode.OBJECT_ARR; - else if (cls == BinaryArray.class) + else if (cls == binariesFactory.binaryArrayClass()) return BinaryWriteMode.OBJECT_ARR; - else if (cls == BinaryEnumArray.class) + else if (cls == binariesFactory.binaryEnumArrayClass()) return BinaryWriteMode.ENUM_ARR; else if (cls == binariesFactory.binaryObjectImplClass()) return BinaryWriteMode.BINARY_OBJ; @@ -742,787 +711,94 @@ else if (cls == Class.class) else if (Proxy.class.isAssignableFrom(cls)) return BinaryWriteMode.PROXY; else - return BinaryWriteMode.OBJECT; - } - - /** - * Check if class represents a collection which must be treated specially. - * - * @param cls Class. - * @return {@code True} if this is a special collection class. - */ - public static boolean isSpecialCollection(Class cls) { - return ArrayList.class.equals(cls) || LinkedList.class.equals(cls) || SINGLETON_LIST_CLS.equals(cls) || - HashSet.class.equals(cls) || LinkedHashSet.class.equals(cls); - } - - /** - * Check if class represents a map which must be treated specially. - * - * @param cls Class. - * @return {@code True} if this is a special map class. - */ - public static boolean isSpecialMap(Class cls) { - return HashMap.class.equals(cls) || LinkedHashMap.class.equals(cls); - } - - /** - * @return Value. - */ - static byte[] doReadByteArray(BinaryInputStream in) { - int len = in.readInt(); - - return in.readByteArray(len); - } - - /** - * @return Value. - */ - static boolean[] doReadBooleanArray(BinaryInputStream in) { - int len = in.readInt(); - - return in.readBooleanArray(len); - } - - /** - * @return Value. - */ - static short[] doReadShortArray(BinaryInputStream in) { - int len = in.readInt(); - - return in.readShortArray(len); - } - - /** - * @return Value. - */ - static char[] doReadCharArray(BinaryInputStream in) { - int len = in.readInt(); - - return in.readCharArray(len); - } - - /** - * @return Value. - */ - static int[] doReadIntArray(BinaryInputStream in) { - int len = in.readInt(); - - return in.readIntArray(len); - } - - /** - * @return Value. - */ - static long[] doReadLongArray(BinaryInputStream in) { - int len = in.readInt(); - - return in.readLongArray(len); - } - - /** - * @return Value. - */ - static float[] doReadFloatArray(BinaryInputStream in) { - int len = in.readInt(); - - return in.readFloatArray(len); - } - - /** - * @return Value. - */ - static double[] doReadDoubleArray(BinaryInputStream in) { - int len = in.readInt(); - - return in.readDoubleArray(len); - } - - /** - * @return Value. - */ - static BigDecimal doReadDecimal(BinaryInputStream in) { - int scale = in.readInt(); - byte[] mag = doReadByteArray(in); - - boolean negative = mag[0] < 0; - - if (negative) - mag[0] &= 0x7F; - - BigInteger intVal = new BigInteger(mag); - - if (negative) - intVal = intVal.negate(); - - return new BigDecimal(intVal, scale); - } - - /** - * @return Value. - */ - static String doReadString(BinaryInputStream in) { - if (!in.hasArray()) { - byte[] arr = doReadByteArray(in); - - if (USE_STR_SERIALIZATION_VER_2) - return utf8BytesToStr(arr, 0, arr.length); - else - return new String(arr, UTF_8); - } - - int strLen = in.readInt(); - - int pos = in.position(); - - // String will copy necessary array part for us. - String res; - - if (USE_STR_SERIALIZATION_VER_2) { - res = utf8BytesToStr(in.array(), pos, strLen); - } - else { - res = new String(in.array(), pos, strLen, UTF_8); - } - - in.position(pos + strLen); - - return res; - } - - /** - * @return Value. - */ - static UUID doReadUuid(BinaryInputStream in) { - return new UUID(in.readLong(), in.readLong()); - } - - /** - * @return Value. - */ - static Date doReadDate(BinaryInputStream in) { - long time = in.readLong(); - - return new Date(time); - } - - /** - * @return Value. - */ - static Timestamp doReadTimestamp(BinaryInputStream in) { - long time = in.readLong(); - int nanos = in.readInt(); - - Timestamp ts = new Timestamp(time); - - ts.setNanos(ts.getNanos() + nanos); - - return ts; - } - - /** - * @return Value. - */ - static Time doReadTime(BinaryInputStream in) { - long time = in.readLong(); - - return new Time(time); - } - - /** - * @return Value. - * @throws BinaryObjectException In case of error. - */ - static BigDecimal[] doReadDecimalArray(BinaryInputStream in) throws BinaryObjectException { - int len = in.readInt(); - - BigDecimal[] arr = new BigDecimal[len]; - - for (int i = 0; i < len; i++) { - byte flag = in.readByte(); - - if (flag == GridBinaryMarshaller.NULL) - arr[i] = null; - else { - if (flag != GridBinaryMarshaller.DECIMAL) - throw new BinaryObjectException("Invalid flag value: " + flag); - - arr[i] = doReadDecimal(in); - } - } - - return arr; - } - - /** - * @return Value. - * @throws BinaryObjectException In case of error. - */ - public static String[] doReadStringArray(BinaryInputStream in) throws BinaryObjectException { - int len = in.readInt(); - - String[] arr = new String[len]; - - for (int i = 0; i < len; i++) { - byte flag = in.readByte(); - - if (flag == GridBinaryMarshaller.NULL) - arr[i] = null; - else { - if (flag != GridBinaryMarshaller.STRING) - throw new BinaryObjectException("Invalid flag value: " + flag); - - arr[i] = doReadString(in); - } - } - - return arr; - } - - /** - * @return Value. - * @throws BinaryObjectException In case of error. - */ - static UUID[] doReadUuidArray(BinaryInputStream in) throws BinaryObjectException { - int len = in.readInt(); - - UUID[] arr = new UUID[len]; - - for (int i = 0; i < len; i++) { - byte flag = in.readByte(); - - if (flag == GridBinaryMarshaller.NULL) - arr[i] = null; - else { - if (flag != GridBinaryMarshaller.UUID) - throw new BinaryObjectException("Invalid flag value: " + flag); - - arr[i] = doReadUuid(in); - } - } - - return arr; - } - - /** - * @return Value. - * @throws BinaryObjectException In case of error. - */ - static Date[] doReadDateArray(BinaryInputStream in) throws BinaryObjectException { - int len = in.readInt(); - - Date[] arr = new Date[len]; - - for (int i = 0; i < len; i++) { - byte flag = in.readByte(); - - if (flag == GridBinaryMarshaller.NULL) - arr[i] = null; - else { - if (flag != GridBinaryMarshaller.DATE) - throw new BinaryObjectException("Invalid flag value: " + flag); - - arr[i] = doReadDate(in); - } - } - - return arr; - } - - /** - * @return Value. - * @throws BinaryObjectException In case of error. - */ - static Timestamp[] doReadTimestampArray(BinaryInputStream in) throws BinaryObjectException { - int len = in.readInt(); - - Timestamp[] arr = new Timestamp[len]; - - for (int i = 0; i < len; i++) { - byte flag = in.readByte(); - - if (flag == GridBinaryMarshaller.NULL) - arr[i] = null; - else { - if (flag != GridBinaryMarshaller.TIMESTAMP) - throw new BinaryObjectException("Invalid flag value: " + flag); - - arr[i] = doReadTimestamp(in); - } - } - - return arr; - } - - /** - * @return Value. - * @throws BinaryObjectException In case of error. - */ - static Time[] doReadTimeArray(BinaryInputStream in) throws BinaryObjectException { - int len = in.readInt(); - - Time[] arr = new Time[len]; - - for (int i = 0; i < len; i++) { - byte flag = in.readByte(); - - if (flag == GridBinaryMarshaller.NULL) - arr[i] = null; - else { - if (flag != GridBinaryMarshaller.TIME) - throw new BinaryObjectException("Invalid flag value: " + flag); - - arr[i] = doReadTime(in); - } - } - - return arr; - } - - /** - * @return Value. - */ - static BinaryObject doReadBinaryObject(BinaryInputStream in, BinaryContext ctx, boolean detach) { - if (in.offheapPointer() > 0) { - int len = in.readInt(); - - int pos = in.position(); - - in.position(in.position() + len); - - int start = in.readInt(); - - return binariesFactory.binaryOffheapObject(ctx, in.offheapPointer() + pos, start, len); - } - else { - byte[] arr = doReadByteArray(in); - int start = in.readInt(); - - BinaryObject binO = binariesFactory.binaryObject(ctx, arr, start); - - if (detach) - return detach(binO); - - return binO; - } - } - - /** - * @param in Binary input stream. - * @param ctx Binary context. - * @param ldr Class loader. - * @return Class object specified at the input stream. - * @throws BinaryObjectException If failed. - */ - static Class doReadClass(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr) - throws BinaryObjectException { - return doReadClass(in, ctx, ldr, true); - } - - /** - * @param in Binary input stream. - * @param ctx Binary context. - * @param ldr Class loader. - * @param deserialize Doesn't load the class when the flag is {@code false}. Class information is skipped. - * @return Class object specified at the input stream if {@code deserialize == true}. Otherwise returns {@code null} - * @throws BinaryObjectException If failed. - */ - private static Class doReadClass(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, boolean deserialize) - throws BinaryObjectException { - int typeId = in.readInt(); - - if (!deserialize) { - // Skip class name at the stream. - if (typeId == GridBinaryMarshaller.UNREGISTERED_TYPE_ID) - doReadClassName(in); - - return null; - } - - return doReadClass(in, ctx, ldr, typeId); - } - - /** - * @return Value. - */ - @SuppressWarnings("ConstantConditions") - static Object doReadProxy(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, - BinaryReaderHandlesHolder handles) { - Class[] intfs = new Class[in.readInt()]; - - for (int i = 0; i < intfs.length; i++) - intfs[i] = doReadClass(in, ctx, ldr); - - InvocationHandler ih = (InvocationHandler)doReadObject(in, ctx, ldr, handles); - - return Proxy.newProxyInstance(ldr != null ? ldr : CommonUtils.gridClassLoader(), intfs, ih); - } - - /** - * Read plain type. - * - * @param in Input stream. - * @return Plain type. - */ - static EnumType doReadEnumType(BinaryInputStream in) { - int typeId = in.readInt(); - - if (typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID) - return new EnumType(typeId, null); - else { - String clsName = doReadClassName(in); - - return new EnumType(GridBinaryMarshaller.UNREGISTERED_TYPE_ID, clsName); - } - } - - /** - * @param in Input stream. - * @return Class name. - */ - static String doReadClassName(BinaryInputStream in) { - byte flag = in.readByte(); - - if (flag != GridBinaryMarshaller.STRING) - throw new BinaryObjectException("Failed to read class name [position=" + (in.position() - 1) + ']'); - - return doReadString(in); - } - - /** - * @param in Binary input stream. - * @param ctx Binary context. - * @param ldr Class loader. - * @param typeId Type id. - * @return Class object specified at the input stream. - * @throws BinaryObjectException If failed. - */ - static Class doReadClass(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, int typeId) - throws BinaryObjectException { - Class cls; - - if (typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID) - cls = ctx.descriptorForTypeId(true, typeId, ldr, false).describedClass(); - else { - String clsName = doReadClassName(in); - - try { - cls = ClassLoaderUtils.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 - if (Marshallers.USE_CACHE.get()) - ctx.registerType(cls, false, false); - } - - return cls; - } - - /** - * Resolve the class. - * - * @param ctx Binary context. - * @param typeId Type ID. - * @param clsName Class name. - * @param ldr Class loaded. - * @return Resovled class. - */ - static Class resolveClass(BinaryContext ctx, int typeId, @Nullable String clsName, - @Nullable ClassLoader ldr, boolean registerMeta) { - Class cls; - - if (ldr == null) - ldr = ctx.classLoader(); - - if (typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID) - cls = ctx.descriptorForTypeId(true, typeId, ldr, registerMeta).describedClass(); - else { - try { - cls = ClassLoaderUtils.forName(clsName, ldr); - } - catch (ClassNotFoundException e) { - throw new BinaryInvalidTypeException("Failed to load the class: " + clsName, e); - } - - ctx.registerType(cls, false, false); - } - - return cls; - } - - /** - * Read binary enum. - * - * @param in Input stream. - * @param ctx Binary context. - * @param type Plain type. - * @return Enum. - */ - static BinaryObjectEx doReadBinaryEnum(BinaryInputStream in, BinaryContext ctx, - EnumType type) { - return binariesFactory.binaryEnum(ctx, type.typeId, type.clsName, in.readInt()); - } - - /** - * Read binary enum array. - * - * @param in Input stream. - * @param ctx Binary context. - * @return Enum array. - */ - private static Object[] doReadBinaryEnumArray(BinaryInputStream in, BinaryContext ctx) { - int len = in.readInt(); - - Object[] arr = (Object[])Array.newInstance(binariesFactory.binaryEnumClass(), len); - - for (int i = 0; i < len; i++) { - byte flag = in.readByte(); - - if (flag == GridBinaryMarshaller.NULL) - arr[i] = null; - else - arr[i] = doReadBinaryEnum(in, ctx, doReadEnumType(in)); - } - - return arr; + return BinaryWriteMode.OBJECT; } /** - * Read object serialized using optimized marshaller. + * Check if class represents a collection which must be treated specially. * - * @return Result. + * @param cls Class. + * @return {@code True} if this is a special collection class. */ - public static Object doReadOptimized(BinaryInputStream in, BinaryContext ctx, @Nullable ClassLoader clsLdr) { - int len = in.readInt(); - - ByteArrayInputStream input = new ByteArrayInputStream(in.array(), in.position(), len); - - try { - return ctx.optimizedMarsh().unmarshal(input, CommonUtils.resolveClassLoader(clsLdr, ctx.classLoader())); - } - catch (IgniteCheckedException e) { - throw new BinaryObjectException("Failed to unmarshal object with optimized marshaller", e); - } - finally { - in.position(in.position() + len); - } + public static boolean isSpecialCollection(Class cls) { + return ArrayList.class.equals(cls) || LinkedList.class.equals(cls) || SINGLETON_LIST_CLS.equals(cls) || + HashSet.class.equals(cls) || LinkedHashSet.class.equals(cls); } /** - * @return Object. - * @throws BinaryObjectException In case of error. + * Check if class represents a map which must be treated specially. + * + * @param cls Class. + * @return {@code True} if this is a special map class. */ - @Nullable static Object doReadObject(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, - BinaryReaderHandlesHolder handles) throws BinaryObjectException { - return reader(ctx, in, ldr, handles.handles(), false, true).deserialize(); + public static boolean isSpecialMap(Class cls) { + return HashMap.class.equals(cls) || LinkedHashMap.class.equals(cls); } /** - * @return Unmarshalled value. - * @throws BinaryObjectException In case of error. + * @return Value. */ - @Nullable static Object unmarshal(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr) - throws BinaryObjectException { - return unmarshal(in, ctx, ldr, new BinaryReaderHandlesHolderImpl()); - } + static byte[] doReadByteArray(BinaryInputStream in) { + int len = in.readInt(); - /** - * @return Unmarshalled value. - * @throws BinaryObjectException In case of error. - */ - @Nullable static Object unmarshal(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, - BinaryReaderHandlesHolder handles) throws BinaryObjectException { - return unmarshal(in, ctx, ldr, handles, false, false); + return in.readByteArray(len); } /** - * @return Unmarshalled value. - * @throws BinaryObjectException In case of error. + * @return Value. */ - @Nullable static Object unmarshal(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, - BinaryReaderHandlesHolder handles, boolean detach, boolean deserialize) throws BinaryObjectException { - int start = in.position(); - - byte flag = in.readByte(); - - switch (flag) { - case GridBinaryMarshaller.NULL: - return null; - - case GridBinaryMarshaller.HANDLE: { - int handlePos = start - in.readInt(); - - Object obj = handles.getHandle(handlePos); - - if (obj == null) { - int retPos = in.position(); - - in.position(handlePos); + static String doReadString(BinaryInputStream in) { + if (!in.hasArray()) { + byte[] arr = doReadByteArray(in); - obj = unmarshal(in, ctx, ldr, handles, detach, deserialize); + if (USE_STR_SERIALIZATION_VER_2) + return utf8BytesToStr(arr, 0, arr.length); + else + return new String(arr, UTF_8); + } - in.position(retPos); - } + int strLen = in.readInt(); - return obj; - } + int pos = in.position(); - case GridBinaryMarshaller.OBJ: { - checkProtocolVersion(in.readByte()); + // String will copy necessary array part for us. + String res; - int len = length(in, start); + if (USE_STR_SERIALIZATION_VER_2) { + res = utf8BytesToStr(in.array(), pos, strLen); + } + else { + res = new String(in.array(), pos, strLen, UTF_8); + } - BinaryObjectEx po; + in.position(pos + strLen); - if (detach) { - BinaryObjectEx binObj = binariesFactory.binaryObject(ctx, in.array(), start); + return res; + } - binObj.detachAllowed(true); + /** + * @return Value. + * @throws BinaryObjectException In case of error. + */ + public static String[] doReadStringArray(BinaryInputStream in) throws BinaryObjectException { + int len = in.readInt(); - po = binObj.detach(!handles.isEmpty()); - } - else { - if (in.offheapPointer() == 0) - po = binariesFactory.binaryObject(ctx, in.array(), start); - else - po = binariesFactory.binaryOffheapObject(ctx, in.offheapPointer(), start, - in.remaining() + in.position()); - } + String[] arr = new String[len]; - in.position(start + len); + for (int i = 0; i < len; i++) { + byte flag = in.readByte(); - handles.setHandle(po, start); + if (flag == GridBinaryMarshaller.NULL) + arr[i] = null; + else { + if (flag != GridBinaryMarshaller.STRING) + throw new BinaryObjectException("Invalid flag value: " + flag); - return po; + arr[i] = doReadString(in); } - - case GridBinaryMarshaller.BYTE: - return in.readByte(); - - case GridBinaryMarshaller.SHORT: - return in.readShort(); - - case GridBinaryMarshaller.INT: - return in.readInt(); - - case GridBinaryMarshaller.LONG: - return in.readLong(); - - case GridBinaryMarshaller.FLOAT: - return in.readFloat(); - - case GridBinaryMarshaller.DOUBLE: - return in.readDouble(); - - case GridBinaryMarshaller.CHAR: - return in.readChar(); - - case GridBinaryMarshaller.BOOLEAN: - return in.readBoolean(); - - case GridBinaryMarshaller.DECIMAL: - return doReadDecimal(in); - - case GridBinaryMarshaller.STRING: - return doReadString(in); - - case GridBinaryMarshaller.UUID: - return doReadUuid(in); - - case GridBinaryMarshaller.DATE: - return doReadDate(in); - - case GridBinaryMarshaller.TIMESTAMP: - return doReadTimestamp(in); - - case GridBinaryMarshaller.TIME: - return doReadTime(in); - - case GridBinaryMarshaller.BYTE_ARR: - return doReadByteArray(in); - - case GridBinaryMarshaller.SHORT_ARR: - return doReadShortArray(in); - - case GridBinaryMarshaller.INT_ARR: - return doReadIntArray(in); - - case GridBinaryMarshaller.LONG_ARR: - return doReadLongArray(in); - - case GridBinaryMarshaller.FLOAT_ARR: - return doReadFloatArray(in); - - case GridBinaryMarshaller.DOUBLE_ARR: - return doReadDoubleArray(in); - - case GridBinaryMarshaller.CHAR_ARR: - return doReadCharArray(in); - - case GridBinaryMarshaller.BOOLEAN_ARR: - return doReadBooleanArray(in); - - case GridBinaryMarshaller.DECIMAL_ARR: - return doReadDecimalArray(in); - - case GridBinaryMarshaller.STRING_ARR: - return doReadStringArray(in); - - case GridBinaryMarshaller.UUID_ARR: - return doReadUuidArray(in); - - case GridBinaryMarshaller.DATE_ARR: - return doReadDateArray(in); - - case GridBinaryMarshaller.TIMESTAMP_ARR: - return doReadTimestampArray(in); - - case GridBinaryMarshaller.TIME_ARR: - return doReadTimeArray(in); - - case GridBinaryMarshaller.OBJ_ARR: - if (useBinaryArrays() && !deserialize) - return doReadBinaryArray(in, ctx, ldr, handles, detach, deserialize, false); - else - return doReadObjectArray(in, ctx, ldr, handles, detach, deserialize); - - case GridBinaryMarshaller.COL: - return doReadCollection(in, ctx, ldr, handles, detach, deserialize, null); - - case GridBinaryMarshaller.MAP: - return doReadMap(in, ctx, ldr, handles, detach, deserialize, null); - - case GridBinaryMarshaller.BINARY_OBJ: - return doReadBinaryObject(in, ctx, detach); - - case GridBinaryMarshaller.ENUM: - case GridBinaryMarshaller.BINARY_ENUM: - return doReadBinaryEnum(in, ctx, doReadEnumType(in)); - - case GridBinaryMarshaller.ENUM_ARR: - if (useBinaryArrays() && !deserialize) - return doReadBinaryArray(in, ctx, ldr, handles, detach, deserialize, true); - else { - doReadEnumType(in); // Simply skip this part as we do not need it. - - return doReadBinaryEnumArray(in, ctx); - } - - case GridBinaryMarshaller.CLASS: - return doReadClass(in, ctx, ldr); - - case GridBinaryMarshaller.PROXY: - return doReadProxy(in, ctx, ldr, handles); - - case GridBinaryMarshaller.OPTM_MARSH: - return doReadOptimized(in, ctx, ldr); - - default: - throw new BinaryObjectException("Invalid flag value: " + flag); } + + return arr; } /** @@ -1584,226 +860,6 @@ public static byte sqlTypeToBinary(int sqlType) { } } - /** - * @param in Binary input stream. - * @param ctx Binary context. - * @param ldr Class loader. - * @param handles Holder for handles. - * @param detach Detach flag. - * @param deserialize Deep flag. - * @return Value. - * @throws BinaryObjectException In case of error. - */ - static Object[] doReadObjectArray(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, - BinaryReaderHandlesHolder handles, boolean detach, boolean deserialize) throws BinaryObjectException { - int hPos = positionForHandle(in); - - Class compType = doReadClass(in, ctx, ldr, deserialize); - - int len = in.readInt(); - - Object[] arr = (deserialize && !BinaryObject.class.isAssignableFrom(compType)) - ? (Object[])Array.newInstance(compType, len) - : new Object[len]; - - handles.setHandle(arr, hPos); - - for (int i = 0; i < len; i++) { - Object res = deserializeOrUnmarshal(in, ctx, ldr, handles, detach, deserialize); - - if (deserialize && useBinaryArrays() && res instanceof BinaryObject) - arr[i] = ((BinaryObject)res).deserialize(ldr); - else - arr[i] = res; - } - - return arr; - } - - /** - * @param in Binary input stream. - * @param ctx Binary context. - * @param ldr Class loader. - * @param handles Holder for handles. - * @param detach Detach flag. - * @param deserialize Deep flag. - * @return Value. - * @throws BinaryObjectException In case of error. - */ - private static BinaryArray doReadBinaryArray(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, - BinaryReaderHandlesHolder handles, boolean detach, boolean deserialize, boolean isEnumArray) { - int hPos = positionForHandle(in); - - int compTypeId = in.readInt(); - String compClsName = null; - - if (compTypeId == GridBinaryMarshaller.UNREGISTERED_TYPE_ID) - compClsName = doReadClassName(in); - - int len = in.readInt(); - - Object[] arr = new Object[len]; - - BinaryArray res = isEnumArray - ? new BinaryEnumArray(ctx, compTypeId, compClsName, arr) - : new BinaryArray(ctx, compTypeId, compClsName, arr); - - handles.setHandle(res, hPos); - - for (int i = 0; i < len; i++) - arr[i] = deserializeOrUnmarshal(in, ctx, ldr, handles, detach, deserialize); - - return res; - } - - /** - * @param deserialize Deep flag. - * @param factory Collection factory. - * @return Value. - * @throws BinaryObjectException In case of error. - */ - @SuppressWarnings("unchecked") - static Collection doReadCollection(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, - BinaryReaderHandlesHolder handles, boolean detach, boolean deserialize, BinaryCollectionFactory factory) - throws BinaryObjectException { - int hPos = positionForHandle(in); - - int size = in.readInt(); - - assert size >= 0; - - byte colType = in.readByte(); - - Collection col; - - if (factory != null) - col = factory.create(size); - else { - switch (colType) { - case GridBinaryMarshaller.ARR_LIST: - col = new ArrayList<>(size); - - break; - - case GridBinaryMarshaller.LINKED_LIST: - col = new LinkedList<>(); - - break; - - case GridBinaryMarshaller.SINGLETON_LIST: - col = new MutableSingletonList<>(); - - break; - - case GridBinaryMarshaller.HASH_SET: - col = CommonUtils.newHashSet(size); - - break; - - case GridBinaryMarshaller.LINKED_HASH_SET: - col = CommonUtils.newLinkedHashSet(size); - - break; - - case GridBinaryMarshaller.USER_SET: - col = CommonUtils.newHashSet(size); - - break; - - case GridBinaryMarshaller.USER_COL: - col = new ArrayList<>(size); - - break; - - default: - throw new BinaryObjectException("Invalid collection type: " + colType); - } - } - - handles.setHandle(col, hPos); - - for (int i = 0; i < size; i++) - col.add(deserializeOrUnmarshal(in, ctx, ldr, handles, detach, deserialize)); - - return colType == GridBinaryMarshaller.SINGLETON_LIST ? CommonUtils.convertToSingletonList(col) : col; - } - - /** - * @param deserialize Deep flag. - * @param factory Map factory. - * @return Value. - * @throws BinaryObjectException In case of error. - */ - @SuppressWarnings("unchecked") - static Map doReadMap(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, - BinaryReaderHandlesHolder handles, boolean detach, boolean deserialize, BinaryMapFactory factory) - throws BinaryObjectException { - int hPos = positionForHandle(in); - - int size = in.readInt(); - - assert size >= 0; - - byte mapType = in.readByte(); - - Map map; - - if (factory != null) - map = factory.create(size); - else { - switch (mapType) { - case GridBinaryMarshaller.HASH_MAP: - map = CommonUtils.newHashMap(size); - - break; - - case GridBinaryMarshaller.LINKED_HASH_MAP: - map = CommonUtils.newLinkedHashMap(size); - - break; - - case GridBinaryMarshaller.USER_COL: - map = CommonUtils.newHashMap(size); - - break; - - default: - throw new BinaryObjectException("Invalid map type: " + mapType); - } - } - - handles.setHandle(map, hPos); - - for (int i = 0; i < size; i++) { - Object key = deserializeOrUnmarshal(in, ctx, ldr, handles, detach, deserialize); - Object val = deserializeOrUnmarshal(in, ctx, ldr, handles, detach, deserialize); - - map.put(key, val); - } - - return map; - } - - /** - * Deserialize or unmarshal the object. - * - * @param deserialize Deserialize. - * @return Result. - */ - private static Object deserializeOrUnmarshal(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, - BinaryReaderHandlesHolder handles, boolean detach, boolean deserialize) { - return deserialize ? doReadObject(in, ctx, ldr, handles) : unmarshal(in, ctx, ldr, handles, detach, deserialize); - } - - /** - * Get position to be used for handle. We assume here that the hdr byte was read, hence subtract -1. - * - * @return Position for handle. - */ - static int positionForHandle(BinaryInputStream in) { - return in.position() - 1; - } - /** * Check if class is binarylizable. * @@ -2159,7 +1215,7 @@ private static Map mergeEnumValues(String typeName, } /** - * @param obj {@link BinaryArray} or {@code Object[]}. + * @param obj {@code BinaryArray} or {@code Object[]}. * @return Objects array. */ public static Object[] rawArrayFromBinary(Object obj) { @@ -2174,7 +1230,7 @@ public static Object[] rawArrayFromBinary(Object obj) { /** */ public static boolean isObjectArray(Class cls) { - return Object[].class == cls || BinaryArray.class == cls || BinaryEnumArray.class == cls; + return Object[].class == cls || binariesFactory.binaryArrayClass() == cls || binariesFactory.binaryEnumArrayClass() == cls; } /** @return Type name of the specified object. If {@link BinaryObject} was specified its type will be returned. */ @@ -2222,8 +1278,8 @@ public static int[] getSchema(BinaryContext ctx, IntFunction metadat */ public static Map, Function> unwrapFuncForSizeCalc() { return Map.of( - BinaryArray.class, bo -> ((BinaryArray)bo).array(), - BinaryEnumArray.class, bo -> ((BinaryArray)bo).array() + binariesFactory.binaryArrayClass(), bo -> ((BinaryObjectEx)bo).array(), + binariesFactory.binaryEnumArrayClass(), bo -> ((BinaryObjectEx)bo).array() ); } @@ -2236,15 +1292,14 @@ public static boolean isBinaryEnumObject(Object val) { } /** - * Creates reader instance. + * Creates reader instance that resolves classes with {@link BinaryContext#classLoader()}. * * @param ctx Context. * @param in Input stream. - * @param ldr Class loader. * @param forUnmarshal {@code True} if reader is needed to unmarshal object. */ - public static BinaryReaderEx reader(BinaryContext ctx, BinaryInputStream in, ClassLoader ldr, boolean forUnmarshal) { - return binariesFactory.reader(ctx, in, ldr, forUnmarshal); + public static BinaryReaderEx reader(BinaryContext ctx, BinaryInputStream in, boolean forUnmarshal) { + return binariesFactory.reader(ctx, in, null, null, false, forUnmarshal); } /** @@ -2252,52 +1307,29 @@ public static BinaryReaderEx reader(BinaryContext ctx, BinaryInputStream in, Cla * * @param ctx Context. * @param in Input stream. - * @param ldr Class loader. - * @param hnds Context. - * @param forUnmarshal {@code True} if reader is need to unmarshal object. - */ - static BinaryReaderEx reader(BinaryContext ctx, - BinaryInputStream in, - ClassLoader ldr, - @Nullable BinaryReaderHandles hnds, - boolean forUnmarshal) { - return binariesFactory.reader(ctx, in, ldr, hnds, forUnmarshal); - } - - /** - * Constructor. - * - * @param ctx Context. - * @param in Input stream. - * @param ldr Class loader. - * @param skipHdrCheck Whether to skip header check. + * @param ldr Custom class loader or {@code null} to use {@link BinaryContext#classLoader()}. + * @param hnds Reader handles or {@code null} to start a new handles context. * @param forUnmarshal {@code True} if reader is need to unmarshal object. */ - public static BinaryReaderEx reader(BinaryContext ctx, + static BinaryReaderEx reader( + BinaryContext ctx, BinaryInputStream in, - ClassLoader ldr, - boolean skipHdrCheck, - boolean forUnmarshal) { - return reader(ctx, in, ldr, null, skipHdrCheck, forUnmarshal); + @Nullable ClassLoader ldr, + @Nullable BinaryReaderHandles hnds, + boolean forUnmarshal + ) { + return binariesFactory.reader(ctx, in, ldr, hnds, false, forUnmarshal); } /** - * Constructor. + * Creates reader instance for a stream that is not positioned at a binary object header (header check is skipped). + * Classes are resolved with {@link BinaryContext#classLoader()}. * * @param ctx Context. * @param in Input stream. - * @param ldr Class loader. - * @param hnds Context. - * @param skipHdrCheck Whether to skip header check. - * @param forUnmarshal {@code True} if reader is need to unmarshal object. */ - static BinaryReaderEx reader(BinaryContext ctx, - BinaryInputStream in, - ClassLoader ldr, - @Nullable BinaryReaderHandles hnds, - boolean skipHdrCheck, - boolean forUnmarshal) { - return binariesFactory.reader(ctx, in, ldr, hnds, skipHdrCheck, forUnmarshal); + public static BinaryReaderEx reader(BinaryContext ctx, BinaryInputStream in) { + return binariesFactory.reader(ctx, in, null, null, true, true); } /** @@ -2346,10 +1378,10 @@ public static boolean isBinaryObjectImpl(Object val) { /** * @param val Value to check. - * @return {@code True} if {@code val} instance of {@link BinaryArray}. + * @return {@code True} if {@code val} instance of {@code BinaryArray}. */ public static boolean isBinaryArray(Object val) { - return val instanceof BinaryArray; + return val instanceof BinaryObjectEx && ((BinaryObjectEx)val).isArray(); } /** @return {@code True} if typed arrays should be used, {@code false} otherwise. */ @@ -2438,31 +1470,6 @@ public static BinaryMetadata binaryMetadata( return new BinaryMetadata(typeId, typeName, fields, affKeyFieldName, schemas, isEnum, enumMap); } - /** - * Enum type. - */ - private static class EnumType { - /** Type ID. */ - private final int typeId; - - /** Class name. */ - private final String clsName; - - /** - * Constructor. - * - * @param typeId Type ID. - * @param clsName Class name. - */ - public EnumType(int typeId, @Nullable String clsName) { - assert typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID && clsName == null || - typeId == GridBinaryMarshaller.UNREGISTERED_TYPE_ID && clsName != null; - - this.typeId = typeId; - this.clsName = clsName; - } - } - /** * @param cls Class to get affinity field for. * @return Affinity field name or {@code null} if field name was not found. diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java index 119fd1a771ad7..09fa3e096d150 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java +++ b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java @@ -321,7 +321,7 @@ public void marshal(Object obj, BinaryOutputStream out) { BinaryContext oldCtx = pushContext(ctx); try { - return (T)BinaryUtils.unmarshal(BinaryStreams.inputStream(bytes), ctx, clsLdr); + return (T)BinaryUtils.binariesFactory.unmarshal(BinaryStreams.inputStream(bytes), ctx, clsLdr); } finally { popContext(oldCtx); @@ -337,7 +337,7 @@ public void marshal(Object obj, BinaryOutputStream out) { BinaryContext oldCtx = pushContext(ctx); try { - return (T)BinaryUtils.unmarshal(in, ctx, null); + return (T)BinaryUtils.binariesFactory.unmarshal(in, ctx, null); } finally { popContext(oldCtx); @@ -352,7 +352,7 @@ public void marshal(Object obj, BinaryOutputStream out) { */ @Nullable public T unwrapBinary(BinaryInputStream in, Class clazz) throws BinaryObjectException { BinaryReaderHandles hnds = new BinaryReaderHandles(); - Object obj = deserialize(in, null, hnds); + Object obj = deserialize(in, hnds); return (T)unwrapBinary(obj, hnds, clazz); } @@ -365,7 +365,7 @@ private Object unwrapBinary(Object obj, BinaryReaderHandles hnds, Class clazz BinaryObjectEx obj0 = (BinaryObjectEx)obj; BinaryInputStream in = BinaryStreams.inputStream(obj0.bytes(), obj0.start()); - return deserialize(in, null, hnds); + return deserialize(in, hnds); } else if (obj instanceof BinaryObject) return ((BinaryObject)obj).deserialize(); @@ -435,22 +435,27 @@ private Object[] unwrapArray(Object[] arr, BinaryReaderHandles hnds, Class ar if (arr[0] == NULL) return null; - return deserialize(BinaryStreams.inputStream(arr), ldr, null); + BinaryContext oldCtx = pushContext(ctx); + + try { + return (T)BinaryUtils.reader(ctx, BinaryStreams.inputStream(arr), ldr, null, true).deserialize(); + } + finally { + popContext(oldCtx); + } } /** * @param in Input stream. - * @param ldr Class loader. * @param hnds Handles. * @return Deserialized object. * @throws org.apache.ignite.binary.BinaryObjectException In case of error. */ - @Nullable T deserialize(BinaryInputStream in, @Nullable ClassLoader ldr, - @Nullable BinaryReaderHandles hnds) throws BinaryObjectException { + @Nullable T deserialize(BinaryInputStream in, @Nullable BinaryReaderHandles hnds) throws BinaryObjectException { BinaryContext oldCtx = pushContext(ctx); try { - return (T)BinaryUtils.reader(ctx, in, ldr, hnds, true).deserialize(); + return (T)BinaryUtils.reader(ctx, in, null, hnds, true).deserialize(); } finally { popContext(oldCtx); @@ -485,18 +490,6 @@ public static void popContext(@Nullable BinaryContext oldCtx) { BINARY_CTX.get().set(oldCtx); } - /** - * Creates a reader. - * - * @param stream Stream. - * @return Reader. - */ - public BinaryReaderEx reader(BinaryInputStream stream) { - assert stream != null; - - return BinaryUtils.reader(ctx, stream, null, true); - } - /** * Whether object must be deserialized anyway. I.e. it cannot be converted to BinaryObject. * @@ -507,16 +500,6 @@ public boolean mustDeserialize(Object obj) { return obj != null && ctx.mustDeserialize(obj.getClass()); } - /** - * Gets writer for the given output stream. - * - * @param out Output stream. - * @return Writer. - */ - public BinaryWriterEx writer(BinaryOutputStream out) { - return BinaryUtils.writer(ctx, out); - } - /** * @return Context. */ diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/marshaller/ClassLoaderUtils.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/marshaller/ClassLoaderUtils.java index 9c6be55dd34ba..00ccbf9e5d6f5 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/marshaller/ClassLoaderUtils.java +++ b/modules/binary/api/src/main/java/org/apache/ignite/internal/marshaller/ClassLoaderUtils.java @@ -29,6 +29,12 @@ /** * Utility class to deal with class loading. * Contains internal class cache. + *

+ * A {@code null} class loader passed to any method of this class means the loader Ignite itself was loaded by, + * {@link CommonUtils#gridClassLoader()}. This fallback serves {@link org.apache.ignite.marshaller.Marshaller} API + * callers and deployment code. + * Binary code resolves loaders through {@code BinaryContext#resolveClassLoader(ClassLoader)} and never passes + * {@code null} here. */ public class ClassLoaderUtils { /** Primitive class map. */ @@ -100,7 +106,7 @@ else if (!includePrimitiveTypes || cls.length() > 7 || (clazz = primitiveMap.get * Gets class for provided name. Accepts primitive types names. * * @param clsName Class name. - * @param ldr Class loader. + * @param ldr Class loader or {@code null} to use {@link CommonUtils#gridClassLoader()}. * @param useCache If true class loader and result should be cached internally, false otherwise. * @return Class. * @throws ClassNotFoundException If class not found. @@ -159,7 +165,7 @@ public static Class forName( * Gets class for provided name. Accepts primitive types names. * * @param clsName Class name. - * @param ldr Class loader. + * @param ldr Class loader or {@code null} to use {@link CommonUtils#gridClassLoader()}. * @return Class. * @throws ClassNotFoundException If class not found. */ @@ -168,7 +174,7 @@ public static Class forName(String clsName, @Nullable ClassLoader ldr) throws } /** - * Gets class for provided name. Accepts primitive types names. + * Gets class for provided name using {@link CommonUtils#gridClassLoader()}. Accepts primitive types names. * * @param clsName Class name. * @return Class. diff --git a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java b/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java index 428e0a673a77c..7ddaa3eb7fea6 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java +++ b/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java @@ -81,10 +81,10 @@ private static ClassSet classWhiteList() { if (fileName != null && !fileName.isBlank()) { clsSet = new ClassSet(); - addClassNames(JDK_CLS_NAMES_FILE, clsSet, CommonUtils.gridClassLoader()); - addClassNames(CLS_NAMES_FILE, clsSet, CommonUtils.gridClassLoader()); - addClassNames(DEFAULT_WHITELIST_CLS_NAMES_FILE, clsSet, CommonUtils.gridClassLoader()); - addClassNames(fileName, clsSet, CommonUtils.gridClassLoader()); + addClassNames(JDK_CLS_NAMES_FILE, clsSet); + addClassNames(CLS_NAMES_FILE, clsSet); + addClassNames(DEFAULT_WHITELIST_CLS_NAMES_FILE, clsSet); + addClassNames(fileName, clsSet); } return clsSet; @@ -96,12 +96,12 @@ private static ClassSet classWhiteList() { private static ClassSet classBlackList() { ClassSet clsSet = new ClassSet(); - addClassNames(DEFAULT_BLACKLIST_CLS_NAMES_FILE, clsSet, CommonUtils.gridClassLoader()); + addClassNames(DEFAULT_BLACKLIST_CLS_NAMES_FILE, clsSet); String blackListFileName = IgniteCommonsSystemProperties.getString(IGNITE_MARSHALLER_BLACKLIST); if (blackListFileName != null && !blackListFileName.isBlank()) - addClassNames(blackListFileName, clsSet, CommonUtils.gridClassLoader()); + addClassNames(blackListFileName, clsSet); return clsSet; } @@ -111,14 +111,12 @@ private static ClassSet classBlackList() { * * @param fileName File name containing list of classes. * @param clsSet Class set for update. - * @param clsLdr Class loader. */ private static void addClassNames( String fileName, - ClassSet clsSet, - ClassLoader clsLdr + ClassSet clsSet ) { - InputStream is = clsLdr.getResourceAsStream(fileName); + InputStream is = CommonUtils.gridClassLoader().getResourceAsStream(fileName); if (is == null) { try { diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinariesFactoryImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinariesFactoryImpl.java index 0740a3b343688..cc1ac572a43b4 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinariesFactoryImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinariesFactoryImpl.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.function.ToIntFunction; import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.internal.binary.streams.BinaryHeapOutputStream; import org.apache.ignite.internal.binary.streams.BinaryInputStream; import org.apache.ignite.internal.binary.streams.BinaryOutputStream; @@ -35,32 +36,22 @@ * @see CommonUtils#loadService(Class) */ public class BinariesFactoryImpl implements BinariesFactory { - /** {@inheritDoc} */ - @Override public BinaryReaderEx reader(BinaryContext ctx, BinaryInputStream in, ClassLoader ldr, boolean forUnmarshal) { - return new BinaryReaderExImpl(ctx, in, ldr, forUnmarshal); - } - /** {@inheritDoc} */ @Override public BinaryReaderEx reader( BinaryContext ctx, BinaryInputStream in, - ClassLoader ldr, + @Nullable ClassLoader ldr, @Nullable BinaryReaderHandles hnds, + boolean skipHdrCheck, boolean forUnmarshal ) { - return new BinaryReaderExImpl(ctx, in, ldr, hnds, forUnmarshal); + return new BinaryReaderExImpl(ctx, in, ldr, hnds, skipHdrCheck, forUnmarshal); } /** {@inheritDoc} */ - @Override public BinaryReaderEx reader( - BinaryContext ctx, - BinaryInputStream in, - ClassLoader ldr, - @Nullable BinaryReaderHandles hnds, - boolean skipHdrCheck, - boolean forUnmarshal - ) { - return new BinaryReaderExImpl(ctx, in, ldr, hnds, skipHdrCheck, forUnmarshal); + @Override public @Nullable Object unmarshal(BinaryInputStream in, BinaryContext ctx, @Nullable ClassLoader ldr) + throws BinaryObjectException { + return new SimpleBinaryReader(ctx, in, ldr).unmarshal(); } /** {@inheritDoc} */ @@ -166,6 +157,34 @@ public static BinaryWriterExImpl newWriter(BinaryContext ctx, boolean failIfUnre return new BinaryObjectOffheapImpl(ctx, ptr, start, size); } + /** {@inheritDoc} */ + @Override public BinaryObjectEx binaryArray(BinaryContext ctx, Class compCls, Object[] arr) { + boolean isBinaryArr = BinaryObject.class.isAssignableFrom(compCls); + + String compClsName = isBinaryArr ? Object.class.getName() : compCls.getName(); + + // In case of interface or multidimensional array rely on class name. + // Interfaces and array not registered as binary types. + BinaryClassDescriptor desc = ctx.descriptorForClass(compCls); + + if (compCls.isEnum() || compCls == BinaryUtils.binariesFactory.binaryEnumClass()) { + return new BinaryEnumArray( + ctx, + desc.registered() ? desc.typeId() : GridBinaryMarshaller.UNREGISTERED_TYPE_ID, + compClsName, + arr + ); + } + else { + return new BinaryArray( + ctx, + desc.registered() ? desc.typeId() : GridBinaryMarshaller.UNREGISTERED_TYPE_ID, + compClsName, + arr + ); + } + } + /** {@inheritDoc} */ @Override public Class binaryEnumClass() { return BinaryEnumObjectImpl.class; @@ -176,6 +195,16 @@ public static BinaryWriterExImpl newWriter(BinaryContext ctx, boolean failIfUnre return BinaryObjectImpl.class; } + /** {@inheritDoc} */ + @Override public Class binaryArrayClass() { + return BinaryArray.class; + } + + /** {@inheritDoc} */ + @Override public Class binaryEnumArrayClass() { + return BinaryEnumArray.class; + } + /** {@inheritDoc} */ @Override public Map, Integer> predefinedTypes() { Map, Integer> predefinedTypes = new HashMap<>(); @@ -183,6 +212,8 @@ public static BinaryWriterExImpl newWriter(BinaryContext ctx, boolean failIfUnre predefinedTypes.put(BinaryEnumObjectImpl.class, 0); predefinedTypes.put(BinaryObjectOffheapImpl.class, 0); predefinedTypes.put(BinaryObjectImpl.class, 0); + predefinedTypes.put(BinaryArray.class, 0); + predefinedTypes.put(BinaryEnumArray.class, 0); return predefinedTypes; } diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java similarity index 97% rename from modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java rename to modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java index b998a31d0cd2d..62b8de21afc72 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java @@ -104,11 +104,11 @@ public BinaryArray(BinaryContext ctx, int compTypeId, @Nullable String compClsNa /** {@inheritDoc} */ @Override public T deserialize(ClassLoader ldr) throws BinaryObjectException { - if (ldr != null) + if (ctx.isCustomLoader(ldr)) Marshallers.USE_CACHE.set(Boolean.FALSE); try { - Class compType = BinaryUtils.resolveClass(ctx, compTypeId, compClsName, ldr, false); + Class compType = BinaryImplUtils.resolveClass(ctx, compTypeId, compClsName, ldr, false); // Skip deserialization if already deserialized. // Prepared result is in arr, already. @@ -138,6 +138,11 @@ public BinaryArray(BinaryContext ctx, int compTypeId, @Nullable String compClsNa return arr; } + /** {@inheritDoc} */ + @Override public boolean isArray() { + return true; + } + /** {@inheritDoc} */ @Override public int componentTypeId() { // This can happen when binary type was not registered in time of binary array creation. diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryEnumArray.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumArray.java similarity index 100% rename from modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryEnumArray.java rename to modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumArray.java diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java index 1daea71a44a42..2f3ea279920b9 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java @@ -169,13 +169,15 @@ public BinaryEnumObjectImpl(BinaryContext ctx, byte[] arr) { /** {@inheritDoc} */ @Override public T deserialize(@Nullable ClassLoader ldr) throws BinaryObjectException { - if (ldr != null) + boolean customLdr = ctx.isCustomLoader(ldr); + + if (customLdr) Marshallers.USE_CACHE.set(Boolean.FALSE); try { - Class cls = BinaryUtils.resolveClass(ctx, typeId, clsName, ldr, false); + Class cls = BinaryImplUtils.resolveClass(ctx, typeId, clsName, ldr, false); - return (T)(ldr == null ? BinaryEnumCache.get(cls, ord) : uncachedValue(cls)); + return (T)(customLdr ? uncachedValue(cls) : BinaryEnumCache.get(cls, ord)); } finally { Marshallers.USE_CACHE.set(Boolean.TRUE); diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryImplUtils.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryImplUtils.java index f97c931555f5f..59a29bafdc0c5 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryImplUtils.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryImplUtils.java @@ -16,10 +16,15 @@ */ package org.apache.ignite.internal.binary; +import java.io.ByteArrayInputStream; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.binary.BinaryInvalidTypeException; +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.internal.binary.streams.BinaryInputStream; +import org.apache.ignite.internal.marshaller.ClassLoaderUtils; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.lang.IgniteBiTuple; - -import static org.apache.ignite.internal.binary.BinaryUtils.length; +import org.jetbrains.annotations.Nullable; /** * Binary utils used only in implementation. @@ -317,4 +322,94 @@ public static int hashCode(byte[] data, int startPos, int endPos) { return hash; } + + /** + * Check protocol version. + * + * @param protoVer Protocol version. + */ + public static void checkProtocolVersion(byte protoVer) { + if (GridBinaryMarshaller.PROTO_VER != protoVer) + throw new BinaryObjectException("Unsupported protocol version: " + protoVer); + } + + /** + * Get binary object length. + * + * @param in Input stream. + * @param start Start position. + * @return Length. + */ + public static int length(BinaryPositionReadable in, int start) { + return in.readIntPositioned(start + GridBinaryMarshaller.TOTAL_LEN_POS); + } + + /** + * @param in Input stream. + * @return Class name. + */ + static String doReadClassName(BinaryInputStream in) { + byte flag = in.readByte(); + + if (flag != GridBinaryMarshaller.STRING) + throw new BinaryObjectException("Failed to read class name [position=" + (in.position() - 1) + ']'); + + return BinaryUtils.doReadString(in); + } + + /** + * Read object serialized using optimized marshaller. + * + * @param in Input stream. + * @param ctx Binary context. + * @param clsLdr Custom class loader or {@code null} to use {@link BinaryContext#classLoader()}. + * @return Result. + */ + public static Object doReadOptimized(BinaryInputStream in, BinaryContext ctx, @Nullable ClassLoader clsLdr) { + int len = in.readInt(); + + ByteArrayInputStream input = new ByteArrayInputStream(in.array(), in.position(), len); + + try { + return ctx.optimizedMarsh().unmarshal(input, ctx.resolveClassLoader(clsLdr)); + } + catch (IgniteCheckedException e) { + throw new BinaryObjectException("Failed to unmarshal object with optimized marshaller", e); + } + finally { + in.position(in.position() + len); + } + } + + /** + * Resolve the class. + * + * @param ctx Binary context. + * @param typeId Type ID. + * @param clsName Class name. + * @param ldr Custom class loader or {@code null} to use {@link BinaryContext#classLoader()}. + * @param registerMeta If {@code true}, then metadata will be registered along with the type descriptor. + * @return Resolved class. + */ + static Class resolveClass(BinaryContext ctx, int typeId, @Nullable String clsName, + @Nullable ClassLoader ldr, boolean registerMeta) { + Class cls; + + ldr = ctx.resolveClassLoader(ldr); + + if (typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID) + cls = ctx.descriptorForTypeId(true, typeId, ldr, registerMeta).describedClass(); + else { + try { + cls = ClassLoaderUtils.forName(clsName, ldr); + } + catch (ClassNotFoundException e) { + throw new BinaryInvalidTypeException("Failed to load the class: " + clsName, e); + } + + ctx.registerType(cls, false, false); + } + + return cls; + } } diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java index 3359c73459de8..09621303ababc 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java @@ -391,12 +391,12 @@ public void context(BinaryContext ctx) { /** {@inheritDoc} */ @Nullable @Override public F field(String fieldName) throws BinaryObjectException { - return (F)reader(null, false).unmarshalField(fieldName); + return (F)reader().unmarshalField(fieldName); } /** {@inheritDoc} */ @Nullable @Override public F field(int fieldId) throws BinaryObjectException { - return (F)reader(null, false).unmarshalField(fieldId); + return (F)reader().unmarshalField(fieldId); } /** {@inheritDoc} */ @@ -565,7 +565,7 @@ else if (fieldOffLen == BinaryImplUtils.OFFSET_2) break; default: - val = BinaryUtils.unmarshal(BinaryStreams.inputStream(arr, fieldPos), ctx, null); + val = new SimpleBinaryReader(ctx, BinaryStreams.inputStream(arr, fieldPos), null).unmarshal(); break; } @@ -690,18 +690,18 @@ else if (fieldOffsetLen == BinaryImplUtils.OFFSET_2) } /** {@inheritDoc} */ - @Nullable @Override protected F field(BinaryReaderHandles rCtx, String fieldName) { - return (F)reader(rCtx, false).unmarshalField(fieldName); + @Nullable @Override protected F field(BinaryReaderHandles hnds, String fieldName) { + return (F)reader(hnds, ctx.classLoader(), false).unmarshalField(fieldName); } /** {@inheritDoc} */ @Override public boolean hasField(String fieldName) { - return reader(null, false).findFieldByName(fieldName); + return reader().findFieldByName(fieldName); } /** {@inheritDoc} */ @Nullable @Override public T deserialize(@Nullable ClassLoader ldr) throws BinaryObjectException { - if (ldr == null) + if (!ctx.isCustomLoader(ldr)) return deserialize(); Marshallers.USE_CACHE.set(Boolean.FALSE); @@ -748,7 +748,7 @@ else if (fieldOffsetLen == BinaryImplUtils.OFFSET_2) /** {@inheritDoc} */ @Override BinarySchema createSchema() { - return reader(null, false).getOrCreateSchema(); + return reader().getOrCreateSchema(); } /** {@inheritDoc} */ @@ -806,20 +806,16 @@ private boolean needCopy(CacheObjectValueContext ctx) { /** * Create new reader for this object. * - * @param rCtx Reader context. + * @param hnds Reader context. * @param ldr Class loader. * @param forUnmarshal {@code True} if reader is need to unmarshal object. * @return Reader. */ - private BinaryReaderExImpl reader(@Nullable BinaryReaderHandles rCtx, @Nullable ClassLoader ldr, - boolean forUnmarshal) { - if (ldr == null) - ldr = ctx.classLoader(); - + private BinaryReaderExImpl reader(@Nullable BinaryReaderHandles hnds, ClassLoader ldr, boolean forUnmarshal) { return new BinaryReaderExImpl(ctx, BinaryStreams.inputStream(arr, start), ldr, - rCtx, + hnds, false, forUnmarshal); } @@ -827,12 +823,10 @@ private BinaryReaderExImpl reader(@Nullable BinaryReaderHandles rCtx, @Nullable /** * Create new reader for this object. * - * @param rCtx Reader context. - * @param forUnmarshal {@code True} if reader is need to unmarshal object. * @return Reader. */ - private BinaryReaderExImpl reader(@Nullable BinaryReaderHandles rCtx, boolean forUnmarshal) { - return reader(rCtx, null, forUnmarshal); + private BinaryReaderExImpl reader() { + return reader(null, ctx.classLoader(), false); } /** diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java index dc439b77d11c6..b8e5204d35bc3 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java @@ -96,7 +96,7 @@ public BinaryObjectOffheapImpl(BinaryContext ctx, long ptr, int start, int size) if (typeId == GridBinaryMarshaller.UNREGISTERED_TYPE_ID) { int off = start + GridBinaryMarshaller.DFLT_HDR_LEN; - String clsName = BinaryUtils.doReadClassName(BinaryStreams.inputStream(ptr + off, size)); + String clsName = BinaryImplUtils.doReadClassName(BinaryStreams.inputStream(ptr + off, size)); typeId = ctx.typeId(clsName); } @@ -128,7 +128,7 @@ public BinaryObjectOffheapImpl(BinaryContext ctx, long ptr, int start, int size) /** {@inheritDoc} */ @Override BinarySchema createSchema() { - return reader(null, false).getOrCreateSchema(); + return reader().getOrCreateSchema(); } /** {@inheritDoc} */ @@ -196,12 +196,12 @@ public BinaryObjectOffheapImpl(BinaryContext ctx, long ptr, int start, int size) /** {@inheritDoc} */ @Nullable @Override public F field(String fieldName) throws BinaryObjectException { - return (F)reader(null, false).unmarshalField(fieldName); + return (F)reader().unmarshalField(fieldName); } /** {@inheritDoc} */ @Nullable @Override public F field(int fieldId) throws BinaryObjectException { - return (F)reader(null, false).unmarshalField(fieldId); + return (F)reader().unmarshalField(fieldId); } /** {@inheritDoc} */ @@ -375,7 +375,7 @@ else if (fieldOffLen == BinaryImplUtils.OFFSET_2) stream.position(fieldPos); - val = BinaryUtils.unmarshal(stream, ctx, null); + val = new SimpleBinaryReader(ctx, stream, null).unmarshal(); break; } @@ -389,18 +389,18 @@ else if (fieldOffLen == BinaryImplUtils.OFFSET_2) } /** {@inheritDoc} */ - @Nullable @Override protected F field(BinaryReaderHandles rCtx, String fieldName) { - return (F)reader(rCtx, false).unmarshalField(fieldName); + @Nullable @Override protected F field(BinaryReaderHandles hnds, String fieldName) { + return (F)reader(hnds, ctx.classLoader(), false).unmarshalField(fieldName); } /** {@inheritDoc} */ @Override public boolean hasField(String fieldName) { - return reader(null, false).findFieldByName(fieldName); + return reader().findFieldByName(fieldName); } /** {@inheritDoc} */ @Nullable @Override public T deserialize(@Nullable ClassLoader ldr) throws BinaryObjectException { - if (ldr == null) + if (!ctx.isCustomLoader(ldr)) return deserialize(); Marshallers.USE_CACHE.set(Boolean.FALSE); @@ -415,7 +415,7 @@ else if (fieldOffLen == BinaryImplUtils.OFFSET_2) /** {@inheritDoc} */ @Nullable @Override public T deserialize() throws BinaryObjectException { - return (T)deserializeValue(); + return (T)reader(null, ctx.classLoader(), true).deserialize(); } /** {@inheritDoc} */ @@ -483,34 +483,24 @@ else if (fieldOffLen == BinaryImplUtils.OFFSET_2) return length(); } - /** - * @return Deserialized value. - */ - private Object deserializeValue() { - return reader(null, true).deserialize(); - } - /** * Create new reader for this object. * - * @param rCtx Reader context. - * @param forUnmarshal {@code True} if reader is needed to unmarshal object. * @return Reader. */ - private BinaryReaderExImpl reader(@Nullable BinaryReaderHandles rCtx, boolean forUnmarshal) { - return reader(rCtx, ctx.classLoader(), forUnmarshal); + private BinaryReaderExImpl reader() { + return reader(null, ctx.classLoader(), false); } /** * Create new reader for this object. * - * @param rCtx Reader context. + * @param hnds Reader context. * @param ldr Class loader. * @param forUnmarshal {@code True} if reader is needed to unmarshal object. * @return Reader. */ - private BinaryReaderExImpl reader(@Nullable BinaryReaderHandles rCtx, @Nullable ClassLoader ldr, - boolean forUnmarshal) { + private BinaryReaderExImpl reader(@Nullable BinaryReaderHandles hnds, @Nullable ClassLoader ldr, boolean forUnmarshal) { BinaryInputStream stream = BinaryStreams.inputStream(ptr, size); stream.position(start); @@ -518,7 +508,7 @@ private BinaryReaderExImpl reader(@Nullable BinaryReaderHandles rCtx, @Nullable return new BinaryReaderExImpl(ctx, stream, ldr, - rCtx, + hnds, false, forUnmarshal); } diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java index 7b49c16aa095c..57c6dd0a6b002 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java @@ -96,19 +96,7 @@ * Binary reader implementation. */ @SuppressWarnings("unchecked") -public class BinaryReaderExImpl implements BinaryReaderEx { - /** Binary context. */ - private final BinaryContext ctx; - - /** Input stream. */ - private final BinaryInputStream in; - - /** Class loaded. */ - private final ClassLoader ldr; - - /** Reader context which is constantly passed between objects. */ - private BinaryReaderHandles hnds; - +public class BinaryReaderExImpl extends SimpleBinaryReader implements BinaryReaderEx { /** */ private final int start; @@ -127,9 +115,6 @@ public class BinaryReaderExImpl implements BinaryReaderEx { /** Footer end. */ private final int footerLen; - /** Class descriptor. */ - private BinaryClassDescriptor desc; - /** Mapper. */ private final BinaryInternalMapper mapper; @@ -157,64 +142,27 @@ public class BinaryReaderExImpl implements BinaryReaderEx { /** Whether stream is in raw mode. */ private boolean raw; - /** - * Constructor. - * - * @param ctx Context. - * @param in Input stream. - * @param ldr Class loader. - * @param forUnmarshal {@code True} if reader is needed to unmarshal object. - */ - public BinaryReaderExImpl(BinaryContext ctx, BinaryInputStream in, ClassLoader ldr, boolean forUnmarshal) { - this(ctx, - in, - ldr, - null, - forUnmarshal); - } - - /** - * Constructor. - * - * @param ctx Context. - * @param in Input stream. - * @param ldr Class loader. - * @param hnds Context. - * @param forUnmarshal {@code True} if reader is need to unmarshal object. - */ - public BinaryReaderExImpl(BinaryContext ctx, - BinaryInputStream in, - ClassLoader ldr, - @Nullable BinaryReaderHandles hnds, - boolean forUnmarshal) { - this(ctx, - in, - ldr, - hnds, - false, - forUnmarshal); - } + /** Class descriptor. */ + private BinaryClassDescriptor desc; /** * Constructor. * * @param ctx Context. * @param in Input stream. - * @param ldr Class loader. - * @param hnds Context. + * @param ldr Custom class loader or {@code null} to use {@link BinaryContext#classLoader()}. + * @param hnds Reader handles or {@code null} to start a new handles context. * @param skipHdrCheck Whether to skip header check. * @param forUnmarshal {@code True} if reader is need to unmarshal object. */ public BinaryReaderExImpl(BinaryContext ctx, BinaryInputStream in, - ClassLoader ldr, + @Nullable ClassLoader ldr, @Nullable BinaryReaderHandles hnds, boolean skipHdrCheck, boolean forUnmarshal) { - // Initialize base members. - this.ctx = ctx; - this.in = in; - this.ldr = ldr; + super(ctx, in, ldr); + this.hnds = hnds; start = in.position(); @@ -222,7 +170,7 @@ public BinaryReaderExImpl(BinaryContext ctx, // Perform full header parsing in case of binary object. if (!skipHdrCheck && (in.readByte() == GridBinaryMarshaller.OBJ)) { // Ensure protocol is fine. - BinaryUtils.checkProtocolVersion(in.readByte()); + BinaryImplUtils.checkProtocolVersion(in.readByte()); // Read header content. short flags = in.readShort(); @@ -270,12 +218,12 @@ public BinaryReaderExImpl(BinaryContext ctx, if (forUnmarshal) { // Registers class by type ID, at least locally if the cache is not ready yet. - desc = ctx.registerClass(BinaryUtils.doReadClass(in, ctx, ldr, typeId0), true, false); + desc = ctx.registerClass(doReadClass(typeId0), true, false); typeId = desc.typeId(); } else - typeId = ctx.typeId(BinaryUtils.doReadClassName(in)); + typeId = ctx.typeId(BinaryImplUtils.doReadClassName(in)); int clsNameLen = in.position() - off; @@ -308,12 +256,12 @@ public BinaryReaderExImpl(BinaryContext ctx, } /** {@inheritDoc} */ - @Override public BinaryInputStream in() { + @Override public final BinaryInputStream in() { return in; } /** @return Descriptor. */ - public BinaryClassDescriptor descriptor() { + public final BinaryClassDescriptor descriptor() { if (desc == null) desc = ctx.descriptorForTypeId(userType, typeId, ldr, false); @@ -325,10 +273,10 @@ public BinaryClassDescriptor descriptor() { * @return Unmarshalled value. * @throws BinaryObjectException In case of error. */ - public Object unmarshal(int offset) throws BinaryObjectException { + public final Object unmarshal(int offset) throws BinaryObjectException { streamPosition(offset); - return in.position() >= 0 ? BinaryUtils.unmarshal(in, ctx, ldr, this) : null; + return in.position() >= 0 ? unmarshal() : null; } /** @@ -336,9 +284,9 @@ public Object unmarshal(int offset) throws BinaryObjectException { * @return Unmarshalled value. * @throws BinaryObjectException In case of error. */ - public Object unmarshalField(String fieldName) throws BinaryObjectException { + public final Object unmarshalField(String fieldName) throws BinaryObjectException { try { - return findFieldByName(fieldName) ? BinaryUtils.unmarshal(in, ctx, ldr, this) : null; + return findFieldByName(fieldName) ? unmarshal() : null; } catch (Exception ex) { throw wrapFieldException(fieldName, ex); @@ -350,8 +298,8 @@ public Object unmarshalField(String fieldName) throws BinaryObjectException { * @return Unmarshalled value. * @throws BinaryObjectException In case of error. */ - public Object unmarshalField(int fieldId) throws BinaryObjectException { - return findFieldById(fieldId) ? BinaryUtils.unmarshal(in, ctx, ldr, this) : null; + public final Object unmarshalField(int fieldId) throws BinaryObjectException { + return findFieldById(fieldId) ? unmarshal() : null; } /** @@ -359,7 +307,7 @@ public Object unmarshalField(int fieldId) throws BinaryObjectException { * @return Binary object. * @throws BinaryObjectException In case of error. */ - @Nullable BinaryObject readBinaryObject(int fieldId) throws BinaryObjectException { + @Nullable final BinaryObject readBinaryObject(int fieldId) throws BinaryObjectException { if (findFieldById(fieldId)) { if (checkFlag(BINARY_OBJ) == Flag.NULL) return null; @@ -375,35 +323,17 @@ public Object unmarshalField(int fieldId) throws BinaryObjectException { * @return Field class. * @throws BinaryObjectException In case of error. */ - @Nullable Class readClass(int fieldId) throws BinaryObjectException { + @Nullable final Class readClass(int fieldId) throws BinaryObjectException { if (findFieldById(fieldId)) { if (checkFlag(CLASS) == Flag.NULL) return null; - return BinaryUtils.doReadClass(in, ctx, ldr); + return doReadClass(); } return null; } - /** {@inheritDoc} */ - @Override public void setHandle(Object obj, int pos) { - handles().put(pos, obj); - } - - /** {@inheritDoc} */ - @Override public Object getHandle(int pos) { - return hnds != null ? hnds.get(pos) : null; - } - - /** {@inheritDoc} */ - @Override public BinaryReaderHandles handles() { - if (hnds == null) - hnds = new BinaryReaderHandles(); - - return hnds; - } - /** * Recreating field value from a handle. * @@ -411,7 +341,7 @@ public Object unmarshalField(int fieldId) throws BinaryObjectException { * @return Field. */ private T readHandleField() { - int handlePos = BinaryUtils.positionForHandle(in) - in.readInt(); + int handlePos = positionForHandle() - in.readInt(); Object obj = getHandle(handlePos); @@ -420,7 +350,7 @@ private T readHandleField() { streamPosition(handlePos); - obj = BinaryUtils.doReadObject(in, ctx, ldr, this); + obj = doReadObject(); streamPosition(retPos); } @@ -443,7 +373,7 @@ private BinaryObjectException wrapFieldException(String fieldName, Exception e) } /** {@inheritDoc} */ - @Override public byte readByte(String fieldName) throws BinaryObjectException { + @Override public final byte readByte(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) && checkFlagNoHandles(BYTE) == Flag.NORMAL ? in.readByte() : 0; } @@ -457,7 +387,7 @@ private BinaryObjectException wrapFieldException(String fieldName, Exception e) * @return Value. * @throws BinaryObjectException If failed. */ - byte readByte(int fieldId) throws BinaryObjectException { + final byte readByte(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(BYTE) == Flag.NORMAL ? in.readByte() : 0; } @@ -466,17 +396,17 @@ byte readByte(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Byte readByteNullable(int fieldId) throws BinaryObjectException { + @Nullable final Byte readByteNullable(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(BYTE) == Flag.NORMAL ? in.readByte() : null; } /** {@inheritDoc} */ - @Override public byte readByte() throws BinaryObjectException { + @Override public final byte readByte() throws BinaryObjectException { return in.readByte(); } /** {@inheritDoc} */ - @Nullable @Override public byte[] readByteArray(String fieldName) throws BinaryObjectException { + @Nullable @Override public final byte[] readByteArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readByteArray() : null; } @@ -490,12 +420,12 @@ byte readByte(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable byte[] readByteArray(int fieldId) throws BinaryObjectException { + @Nullable final byte[] readByteArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readByteArray() : null; } /** {@inheritDoc} */ - @Nullable @Override public byte[] readByteArray() throws BinaryObjectException { + @Nullable @Override public final byte[] readByteArray() throws BinaryObjectException { switch (checkFlag(BYTE_ARR)) { case NORMAL: return BinaryUtils.doReadByteArray(in); @@ -509,7 +439,7 @@ byte readByte(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override public boolean readBoolean(String fieldName) throws BinaryObjectException { + @Override public final boolean readBoolean(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) && checkFlagNoHandles(BOOLEAN) == Flag.NORMAL && in.readBoolean(); } @@ -523,7 +453,7 @@ byte readByte(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException If failed. */ - boolean readBoolean(int fieldId) throws BinaryObjectException { + final boolean readBoolean(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(BOOLEAN) == Flag.NORMAL && in.readBoolean(); } @@ -532,17 +462,17 @@ boolean readBoolean(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Boolean readBooleanNullable(int fieldId) throws BinaryObjectException { + @Nullable final Boolean readBooleanNullable(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(BOOLEAN) == Flag.NORMAL ? in.readBoolean() : null; } /** {@inheritDoc} */ - @Override public boolean readBoolean() throws BinaryObjectException { + @Override public final boolean readBoolean() throws BinaryObjectException { return in.readBoolean(); } /** {@inheritDoc} */ - @Nullable @Override public boolean[] readBooleanArray(String fieldName) throws BinaryObjectException { + @Nullable @Override public final boolean[] readBooleanArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readBooleanArray() : null; } @@ -556,15 +486,15 @@ boolean readBoolean(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable boolean[] readBooleanArray(int fieldId) throws BinaryObjectException { + @Nullable final boolean[] readBooleanArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readBooleanArray() : null; } /** {@inheritDoc} */ - @Nullable @Override public boolean[] readBooleanArray() throws BinaryObjectException { + @Nullable @Override public final boolean[] readBooleanArray() throws BinaryObjectException { switch (checkFlag(BOOLEAN_ARR)) { case NORMAL: - return BinaryUtils.doReadBooleanArray(in); + return doReadBooleanArray(); case HANDLE: return readHandleField(); @@ -575,7 +505,7 @@ boolean readBoolean(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override public short readShort(String fieldName) throws BinaryObjectException { + @Override public final short readShort(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) && checkFlagNoHandles(SHORT) == Flag.NORMAL ? in.readShort() : 0; } @@ -589,7 +519,7 @@ boolean readBoolean(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException If failed. */ - short readShort(int fieldId) throws BinaryObjectException { + final short readShort(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(SHORT) == Flag.NORMAL ? in.readShort() : 0; } @@ -598,17 +528,17 @@ short readShort(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Short readShortNullable(int fieldId) throws BinaryObjectException { + @Nullable final Short readShortNullable(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(SHORT) == Flag.NORMAL ? in.readShort() : null; } /** {@inheritDoc} */ - @Override public short readShort() throws BinaryObjectException { + @Override public final short readShort() throws BinaryObjectException { return in.readShort(); } /** {@inheritDoc} */ - @Nullable @Override public short[] readShortArray(String fieldName) throws BinaryObjectException { + @Nullable @Override public final short[] readShortArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readShortArray() : null; } @@ -622,15 +552,15 @@ short readShort(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable short[] readShortArray(int fieldId) throws BinaryObjectException { + @Nullable final short[] readShortArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readShortArray() : null; } /** {@inheritDoc} */ - @Nullable @Override public short[] readShortArray() throws BinaryObjectException { + @Nullable @Override public final short[] readShortArray() throws BinaryObjectException { switch (checkFlag(SHORT_ARR)) { case NORMAL: - return BinaryUtils.doReadShortArray(in); + return doReadShortArray(); case HANDLE: return readHandleField(); @@ -641,7 +571,7 @@ short readShort(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override public char readChar(String fieldName) throws BinaryObjectException { + @Override public final char readChar(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) && checkFlagNoHandles(CHAR) == Flag.NORMAL ? in.readChar() : 0; } @@ -655,7 +585,7 @@ short readShort(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException If failed. */ - char readChar(int fieldId) throws BinaryObjectException { + final char readChar(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(CHAR) == Flag.NORMAL ? in.readChar() : 0; } @@ -664,17 +594,17 @@ char readChar(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Character readCharNullable(int fieldId) throws BinaryObjectException { + @Nullable final Character readCharNullable(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(CHAR) == Flag.NORMAL ? in.readChar() : null; } /** {@inheritDoc} */ - @Override public char readChar() throws BinaryObjectException { + @Override public final char readChar() throws BinaryObjectException { return in.readChar(); } /** {@inheritDoc} */ - @Nullable @Override public char[] readCharArray(String fieldName) throws BinaryObjectException { + @Nullable @Override public final char[] readCharArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readCharArray() : null; } @@ -688,15 +618,15 @@ char readChar(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable char[] readCharArray(int fieldId) throws BinaryObjectException { + @Nullable final char[] readCharArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readCharArray() : null; } /** {@inheritDoc} */ - @Nullable @Override public char[] readCharArray() throws BinaryObjectException { + @Nullable @Override public final char[] readCharArray() throws BinaryObjectException { switch (checkFlag(CHAR_ARR)) { case NORMAL: - return BinaryUtils.doReadCharArray(in); + return doReadCharArray(); case HANDLE: return readHandleField(); @@ -707,7 +637,7 @@ char readChar(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override public int readInt(String fieldName) throws BinaryObjectException { + @Override public final int readInt(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) && checkFlagNoHandles(INT) == Flag.NORMAL ? in.readInt() : 0; } @@ -721,7 +651,7 @@ char readChar(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException If failed. */ - int readInt(int fieldId) throws BinaryObjectException { + final int readInt(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(INT) == Flag.NORMAL ? in.readInt() : 0; } @@ -730,17 +660,17 @@ int readInt(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Integer readIntNullable(int fieldId) throws BinaryObjectException { + @Nullable final Integer readIntNullable(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(INT) == Flag.NORMAL ? in.readInt() : null; } /** {@inheritDoc} */ - @Override public int readInt() throws BinaryObjectException { + @Override public final int readInt() throws BinaryObjectException { return in.readInt(); } /** {@inheritDoc} */ - @Nullable @Override public int[] readIntArray(String fieldName) throws BinaryObjectException { + @Nullable @Override public final int[] readIntArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readIntArray() : null; } @@ -754,15 +684,15 @@ int readInt(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable int[] readIntArray(int fieldId) throws BinaryObjectException { + @Nullable final int[] readIntArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readIntArray() : null; } /** {@inheritDoc} */ - @Nullable @Override public int[] readIntArray() throws BinaryObjectException { + @Nullable @Override public final int[] readIntArray() throws BinaryObjectException { switch (checkFlag(INT_ARR)) { case NORMAL: - return BinaryUtils.doReadIntArray(in); + return doReadIntArray(); case HANDLE: return readHandleField(); @@ -773,7 +703,7 @@ int readInt(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override public long readLong(String fieldName) throws BinaryObjectException { + @Override public final long readLong(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) && checkFlagNoHandles(LONG) == Flag.NORMAL ? in.readLong() : 0; } @@ -787,7 +717,7 @@ int readInt(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException If failed. */ - long readLong(int fieldId) throws BinaryObjectException { + final long readLong(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(LONG) == Flag.NORMAL ? in.readLong() : 0; } @@ -796,17 +726,17 @@ long readLong(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Long readLongNullable(int fieldId) throws BinaryObjectException { + @Nullable final Long readLongNullable(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(LONG) == Flag.NORMAL ? in.readLong() : null; } /** {@inheritDoc} */ - @Override public long readLong() throws BinaryObjectException { + @Override public final long readLong() throws BinaryObjectException { return in.readLong(); } /** {@inheritDoc} */ - @Nullable @Override public long[] readLongArray(String fieldName) throws BinaryObjectException { + @Nullable @Override public final long[] readLongArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readLongArray() : null; } @@ -820,15 +750,15 @@ long readLong(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable long[] readLongArray(int fieldId) throws BinaryObjectException { + @Nullable final long[] readLongArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readLongArray() : null; } /** {@inheritDoc} */ - @Nullable @Override public long[] readLongArray() throws BinaryObjectException { + @Nullable @Override public final long[] readLongArray() throws BinaryObjectException { switch (checkFlag(LONG_ARR)) { case NORMAL: - return BinaryUtils.doReadLongArray(in); + return doReadLongArray(); case HANDLE: return readHandleField(); @@ -839,7 +769,7 @@ long readLong(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override public float readFloat(String fieldName) throws BinaryObjectException { + @Override public final float readFloat(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) && checkFlagNoHandles(FLOAT) == Flag.NORMAL ? in.readFloat() : 0; } @@ -853,7 +783,7 @@ long readLong(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException If failed. */ - float readFloat(int fieldId) throws BinaryObjectException { + final float readFloat(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(FLOAT) == Flag.NORMAL ? in.readFloat() : 0; } @@ -862,17 +792,17 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Float readFloatNullable(int fieldId) throws BinaryObjectException { + @Nullable final Float readFloatNullable(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(FLOAT) == Flag.NORMAL ? in.readFloat() : null; } /** {@inheritDoc} */ - @Override public float readFloat() throws BinaryObjectException { + @Override public final float readFloat() throws BinaryObjectException { return in.readFloat(); } /** {@inheritDoc} */ - @Nullable @Override public float[] readFloatArray(String fieldName) throws BinaryObjectException { + @Nullable @Override public final float[] readFloatArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readFloatArray() : null; } @@ -886,15 +816,15 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable float[] readFloatArray(int fieldId) throws BinaryObjectException { + @Nullable final float[] readFloatArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readFloatArray() : null; } /** {@inheritDoc} */ - @Nullable @Override public float[] readFloatArray() throws BinaryObjectException { + @Nullable @Override public final float[] readFloatArray() throws BinaryObjectException { switch (checkFlag(FLOAT_ARR)) { case NORMAL: - return BinaryUtils.doReadFloatArray(in); + return doReadFloatArray(); case HANDLE: return readHandleField(); @@ -905,7 +835,7 @@ float readFloat(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override public double readDouble(String fieldName) throws BinaryObjectException { + @Override public final double readDouble(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) && checkFlagNoHandles(DOUBLE) == Flag.NORMAL ? in.readDouble() : 0; } @@ -919,7 +849,7 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException If failed. */ - double readDouble(int fieldId) throws BinaryObjectException { + final double readDouble(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(DOUBLE) == Flag.NORMAL ? in.readDouble() : 0; } @@ -928,17 +858,17 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Double readDoubleNullable(int fieldId) throws BinaryObjectException { + @Nullable final Double readDoubleNullable(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) && checkFlagNoHandles(DOUBLE) == Flag.NORMAL ? in.readDouble() : null; } /** {@inheritDoc} */ - @Override public double readDouble() throws BinaryObjectException { + @Override public final double readDouble() throws BinaryObjectException { return in.readDouble(); } /** {@inheritDoc} */ - @Nullable @Override public double[] readDoubleArray(String fieldName) throws BinaryObjectException { + @Nullable @Override public final double[] readDoubleArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readDoubleArray() : null; } @@ -952,15 +882,15 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable double[] readDoubleArray(int fieldId) throws BinaryObjectException { + @Nullable final double[] readDoubleArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readDoubleArray() : null; } /** {@inheritDoc} */ - @Nullable @Override public double[] readDoubleArray() throws BinaryObjectException { + @Nullable @Override public final double[] readDoubleArray() throws BinaryObjectException { switch (checkFlag(DOUBLE_ARR)) { case NORMAL: - return BinaryUtils.doReadDoubleArray(in); + return doReadDoubleArray(); case HANDLE: return readHandleField(); @@ -971,7 +901,7 @@ float readFloat(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override @Nullable public BigDecimal readDecimal(String fieldName) throws BinaryObjectException { + @Override @Nullable public final BigDecimal readDecimal(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readDecimal() : null; } @@ -985,17 +915,17 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable BigDecimal readDecimal(int fieldId) throws BinaryObjectException { + @Nullable final BigDecimal readDecimal(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readDecimal() : null; } /** {@inheritDoc} */ - @Override @Nullable public BigDecimal readDecimal() throws BinaryObjectException { - return checkFlagNoHandles(DECIMAL) == Flag.NORMAL ? BinaryUtils.doReadDecimal(in) : null; + @Override @Nullable public final BigDecimal readDecimal() throws BinaryObjectException { + return checkFlagNoHandles(DECIMAL) == Flag.NORMAL ? doReadDecimal() : null; } /** {@inheritDoc} */ - @Override @Nullable public BigDecimal[] readDecimalArray(String fieldName) throws BinaryObjectException { + @Override @Nullable public final BigDecimal[] readDecimalArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readDecimalArray() : null; } @@ -1009,15 +939,15 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable BigDecimal[] readDecimalArray(int fieldId) throws BinaryObjectException { + @Nullable final BigDecimal[] readDecimalArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readDecimalArray() : null; } /** {@inheritDoc} */ - @Override @Nullable public BigDecimal[] readDecimalArray() throws BinaryObjectException { + @Override @Nullable public final BigDecimal[] readDecimalArray() throws BinaryObjectException { switch (checkFlag(DECIMAL_ARR)) { case NORMAL: - return BinaryUtils.doReadDecimalArray(in); + return doReadDecimalArray(); case HANDLE: return readHandleField(); @@ -1028,7 +958,7 @@ float readFloat(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override @Nullable public String readString(String fieldName) throws BinaryObjectException { + @Override @Nullable public final String readString(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readString() : null; } @@ -1042,17 +972,17 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable String readString(int fieldId) throws BinaryObjectException { + @Nullable final String readString(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readString() : null; } /** {@inheritDoc} */ - @Override @Nullable public String readString() throws BinaryObjectException { + @Override @Nullable public final String readString() throws BinaryObjectException { return checkFlagNoHandles(STRING) == Flag.NORMAL ? BinaryUtils.doReadString(in) : null; } /** {@inheritDoc} */ - @Override @Nullable public String[] readStringArray(String fieldName) throws BinaryObjectException { + @Override @Nullable public final String[] readStringArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readStringArray() : null; } @@ -1066,12 +996,12 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable String[] readStringArray(int fieldId) throws BinaryObjectException { + @Nullable final String[] readStringArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readStringArray() : null; } /** {@inheritDoc} */ - @Override @Nullable public String[] readStringArray() throws BinaryObjectException { + @Override @Nullable public final String[] readStringArray() throws BinaryObjectException { switch (checkFlag(STRING_ARR)) { case NORMAL: return BinaryUtils.doReadStringArray(in); @@ -1085,7 +1015,7 @@ float readFloat(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override @Nullable public UUID readUuid(String fieldName) throws BinaryObjectException { + @Override @Nullable public final UUID readUuid(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readUuid() : null; } @@ -1099,17 +1029,17 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable UUID readUuid(int fieldId) throws BinaryObjectException { + @Nullable final UUID readUuid(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readUuid() : null; } /** {@inheritDoc} */ - @Override @Nullable public UUID readUuid() throws BinaryObjectException { - return checkFlagNoHandles(UUID) == Flag.NORMAL ? BinaryUtils.doReadUuid(in) : null; + @Override @Nullable public final UUID readUuid() throws BinaryObjectException { + return checkFlagNoHandles(UUID) == Flag.NORMAL ? doReadUuid() : null; } /** {@inheritDoc} */ - @Override @Nullable public UUID[] readUuidArray(String fieldName) throws BinaryObjectException { + @Override @Nullable public final UUID[] readUuidArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readUuidArray() : null; } @@ -1123,15 +1053,15 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable UUID[] readUuidArray(int fieldId) throws BinaryObjectException { + @Nullable final UUID[] readUuidArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readUuidArray() : null; } /** {@inheritDoc} */ - @Override @Nullable public UUID[] readUuidArray() throws BinaryObjectException { + @Override @Nullable public final UUID[] readUuidArray() throws BinaryObjectException { switch (checkFlag(UUID_ARR)) { case NORMAL: - return BinaryUtils.doReadUuidArray(in); + return doReadUuidArray(); case HANDLE: return readHandleField(); @@ -1142,7 +1072,7 @@ float readFloat(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override @Nullable public Date readDate(String fieldName) throws BinaryObjectException { + @Override @Nullable public final Date readDate(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readDate() : null; } @@ -1156,17 +1086,17 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Date readDate(int fieldId) throws BinaryObjectException { + @Nullable final Date readDate(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readDate() : null; } /** {@inheritDoc} */ - @Override @Nullable public Date readDate() throws BinaryObjectException { - return checkFlagNoHandles(DATE) == Flag.NORMAL ? BinaryUtils.doReadDate(in) : null; + @Override @Nullable public final Date readDate() throws BinaryObjectException { + return checkFlagNoHandles(DATE) == Flag.NORMAL ? doReadDate() : null; } /** {@inheritDoc} */ - @Override @Nullable public Date[] readDateArray(String fieldName) throws BinaryObjectException { + @Override @Nullable public final Date[] readDateArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readDateArray() : null; } @@ -1180,15 +1110,15 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Date[] readDateArray(int fieldId) throws BinaryObjectException { + @Nullable final Date[] readDateArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readDateArray() : null; } /** {@inheritDoc} */ - @Override @Nullable public Date[] readDateArray() throws BinaryObjectException { + @Override @Nullable public final Date[] readDateArray() throws BinaryObjectException { switch (checkFlag(DATE_ARR)) { case NORMAL: - return BinaryUtils.doReadDateArray(in); + return doReadDateArray(); case HANDLE: return readHandleField(); @@ -1199,7 +1129,7 @@ float readFloat(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override @Nullable public Timestamp readTimestamp(String fieldName) throws BinaryObjectException { + @Override @Nullable public final Timestamp readTimestamp(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readTimestamp() : null; } @@ -1213,17 +1143,17 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Timestamp readTimestamp(int fieldId) throws BinaryObjectException { + @Nullable final Timestamp readTimestamp(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readTimestamp() : null; } /** {@inheritDoc} */ - @Override @Nullable public Timestamp readTimestamp() throws BinaryObjectException { - return checkFlagNoHandles(TIMESTAMP) == Flag.NORMAL ? BinaryUtils.doReadTimestamp(in) : null; + @Override @Nullable public final Timestamp readTimestamp() throws BinaryObjectException { + return checkFlagNoHandles(TIMESTAMP) == Flag.NORMAL ? doReadTimestamp() : null; } /** {@inheritDoc} */ - @Override @Nullable public Timestamp[] readTimestampArray(String fieldName) throws BinaryObjectException { + @Override @Nullable public final Timestamp[] readTimestampArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readTimestampArray() : null; } @@ -1237,15 +1167,15 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Timestamp[] readTimestampArray(int fieldId) throws BinaryObjectException { + @Nullable final Timestamp[] readTimestampArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readTimestampArray() : null; } /** {@inheritDoc} */ - @Override @Nullable public Timestamp[] readTimestampArray() throws BinaryObjectException { + @Override @Nullable public final Timestamp[] readTimestampArray() throws BinaryObjectException { switch (checkFlag(TIMESTAMP_ARR)) { case NORMAL: - return BinaryUtils.doReadTimestampArray(in); + return doReadTimestampArray(); case HANDLE: return readHandleField(); @@ -1256,17 +1186,17 @@ float readFloat(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override @Nullable public Time readTime(String fieldName) throws BinaryObjectException { + @Override @Nullable public final Time readTime(String fieldName) throws BinaryObjectException { return findFieldByName(fieldName) ? this.readTime() : null; } /** {@inheritDoc} */ - @Override @Nullable public Time readTime() throws BinaryObjectException { - return checkFlagNoHandles(TIME) == Flag.NORMAL ? BinaryUtils.doReadTime(in) : null; + @Override @Nullable public final Time readTime() throws BinaryObjectException { + return checkFlagNoHandles(TIME) == Flag.NORMAL ? doReadTime() : null; } /** {@inheritDoc} */ - @Override @Nullable public Time[] readTimeArray(String fieldName) throws BinaryObjectException { + @Override @Nullable public final Time[] readTimeArray(String fieldName) throws BinaryObjectException { return findFieldByName(fieldName) ? this.readTimeArray() : null; } @@ -1275,7 +1205,7 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Time readTime(int fieldId) throws BinaryObjectException { + @Nullable final Time readTime(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readTime() : null; } @@ -1284,15 +1214,15 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Time[] readTimeArray(int fieldId) throws BinaryObjectException { + @Nullable final Time[] readTimeArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readTimeArray() : null; } /** {@inheritDoc} */ - @Override @Nullable public Time[] readTimeArray() throws BinaryObjectException { + @Override @Nullable public final Time[] readTimeArray() throws BinaryObjectException { switch (checkFlag(TIME_ARR)) { case NORMAL: - return BinaryUtils.doReadTimeArray(in); + return doReadTimeArray(); case HANDLE: return readHandleField(); default: @@ -1301,9 +1231,9 @@ float readFloat(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Nullable @Override public T readObject(String fieldName) throws BinaryObjectException { + @Nullable @Override public final T readObject(String fieldName) throws BinaryObjectException { try { - return findFieldByName(fieldName) ? (T)BinaryUtils.doReadObject(in, ctx, ldr, this) : null; + return findFieldByName(fieldName) ? (T)doReadObject() : null; } catch (Exception ex) { throw wrapFieldException(fieldName, ex); @@ -1315,27 +1245,36 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Object readObject(int fieldId) throws BinaryObjectException { - return findFieldById(fieldId) ? BinaryUtils.doReadObject(in, ctx, ldr, this) : null; + @Nullable final Object readObject(int fieldId) throws BinaryObjectException { + return findFieldById(fieldId) ? doReadObject() : null; } /** {@inheritDoc} */ - @Override public Object readObject() throws BinaryObjectException { - return BinaryUtils.doReadObject(in, ctx, ldr, this); + @Override public final Object readObject() throws BinaryObjectException { + return doReadObject(); } /** {@inheritDoc} */ - @Nullable @Override public Object readObjectDetached() throws BinaryObjectException { + @Nullable @Override public final Object readObjectDetached() throws BinaryObjectException { return readObjectDetached(false); } /** {@inheritDoc} */ - @Nullable @Override public Object readObjectDetached(boolean deserialize) throws BinaryObjectException { - return BinaryUtils.unmarshal(in, ctx, ldr, new BinaryReaderHandlesHolderImpl(), true, deserialize); + @Nullable @Override public final Object readObjectDetached(boolean deserialize) throws BinaryObjectException { + BinaryReaderHandles prevHnds = hnds; + + hnds = null; + + try { + return unmarshal(true, deserialize); + } + finally { + hnds = prevHnds; + } } /** {@inheritDoc} */ - @Nullable @Override public Object[] readObjectArray(String fieldName) throws BinaryObjectException { + @Nullable @Override public final Object[] readObjectArray(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? this.readObjectArray() : null; } @@ -1349,15 +1288,15 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Object[] readObjectArray(int fieldId) throws BinaryObjectException { + @Nullable final Object[] readObjectArray(int fieldId) throws BinaryObjectException { return findFieldById(fieldId) ? this.readObjectArray() : null; } /** {@inheritDoc} */ - @Nullable @Override public Object[] readObjectArray() throws BinaryObjectException { + @Nullable @Override public final Object[] readObjectArray() throws BinaryObjectException { switch (checkFlag(OBJ_ARR)) { case NORMAL: - return BinaryUtils.doReadObjectArray(in, ctx, ldr, this, false, true); + return doReadObjectArray(false, true); case HANDLE: Object arr = readHandleField(); @@ -1373,7 +1312,7 @@ float readFloat(int fieldId) throws BinaryObjectException { } /** {@inheritDoc} */ - @Nullable @Override public > T readEnum(String fieldName) throws BinaryObjectException { + @Nullable @Override public final > T readEnum(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? (T)readEnum0(null) : null; } @@ -1388,12 +1327,12 @@ float readFloat(int fieldId) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Enum readEnum(int fieldId, @Nullable Class cls) throws BinaryObjectException { + @Nullable final Enum readEnum(int fieldId, @Nullable Class cls) throws BinaryObjectException { return findFieldById(fieldId) ? readEnum0(cls) : null; } /** {@inheritDoc} */ - @Nullable @Override public > T readEnum() throws BinaryObjectException { + @Nullable @Override public final > T readEnum() throws BinaryObjectException { return (T)readEnum0(null); } @@ -1407,19 +1346,19 @@ float readFloat(int fieldId) throws BinaryObjectException { private Enum readEnum0(@Nullable Class cls) throws BinaryObjectException { if (checkFlagNoHandles(ENUM) == Flag.NORMAL) { // Read class even if we know it in advance to set correct stream position. - Class cls0 = BinaryUtils.doReadClass(in, ctx, ldr); + Class cls0 = doReadClass(); if (cls == null) cls = cls0; - return doReadEnum(in, cls); + return doReadEnum(cls); } else return null; } /** {@inheritDoc} */ - @Nullable @Override public > T[] readEnumArray(String fieldName) + @Nullable @Override public final > T[] readEnumArray(String fieldName) throws BinaryObjectException { try { @@ -1435,8 +1374,8 @@ private Enum readEnum0(@Nullable Class cls) throws BinaryObjectException { * @return Binary Enum * @throws BinaryObjectException If failed. */ - @Nullable BinaryObjectEx readBinaryEnum(int fieldId) throws BinaryObjectException { - return findFieldById(fieldId) ? doReadBinaryEnum(in, ctx) : null; + @Nullable final BinaryObjectEx readBinaryEnum(int fieldId) throws BinaryObjectException { + return findFieldById(fieldId) ? doReadBinaryEnum() : null; } /** @@ -1445,12 +1384,12 @@ private Enum readEnum0(@Nullable Class cls) throws BinaryObjectException { * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Object[] readEnumArray(int fieldId, @Nullable Class cls) throws BinaryObjectException { + @Nullable final Object[] readEnumArray(int fieldId, @Nullable Class cls) throws BinaryObjectException { return findFieldById(fieldId) ? readEnumArray0(cls) : null; } /** {@inheritDoc} */ - @Nullable @Override public > T[] readEnumArray() throws BinaryObjectException { + @Nullable @Override public final > T[] readEnumArray() throws BinaryObjectException { return (T[])readEnumArray0(null); } @@ -1465,12 +1404,12 @@ private Object[] readEnumArray0(@Nullable Class cls) throws BinaryObjectExcep switch (checkFlag(ENUM_ARR)) { case NORMAL: // Read class even if we know it in advance to set correct stream position. - Class cls0 = BinaryUtils.doReadClass(in, ctx, ldr); + Class cls0 = doReadClass(); if (cls == null) cls = cls0; - return doReadEnumArray(in, ctx, ldr, cls); + return doReadEnumArray(cls); case HANDLE: Object arr = readHandleField(); @@ -1486,7 +1425,7 @@ private Object[] readEnumArray0(@Nullable Class cls) throws BinaryObjectExcep } /** {@inheritDoc} */ - @Nullable @Override public Collection readCollection(String fieldName) throws BinaryObjectException { + @Nullable @Override public final Collection readCollection(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? (Collection)readCollection0(null) : null; } @@ -1496,7 +1435,7 @@ private Object[] readEnumArray0(@Nullable Class cls) throws BinaryObjectExcep } /** {@inheritDoc} */ - @Nullable @Override public Collection readCollection(String fieldName, BinaryCollectionFactory factory) + @Nullable @Override public final Collection readCollection(String fieldName, BinaryCollectionFactory factory) throws BinaryObjectException { try { @@ -1513,18 +1452,18 @@ private Object[] readEnumArray0(@Nullable Class cls) throws BinaryObjectExcep * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Collection readCollection(int fieldId, @Nullable BinaryCollectionFactory factory) + @Nullable final Collection readCollection(int fieldId, @Nullable BinaryCollectionFactory factory) throws BinaryObjectException { return findFieldById(fieldId) ? (Collection)readCollection0(factory) : null; } /** {@inheritDoc} */ - @Nullable @Override public Collection readCollection() throws BinaryObjectException { + @Nullable @Override public final Collection readCollection() throws BinaryObjectException { return readCollection0(null); } /** {@inheritDoc} */ - @Nullable @Override public Collection readCollection(BinaryCollectionFactory factory) + @Nullable @Override public final Collection readCollection(BinaryCollectionFactory factory) throws BinaryObjectException { return readCollection0(factory); } @@ -1540,10 +1479,10 @@ private Collection readCollection0(@Nullable BinaryCollectionFactory factory) throws BinaryObjectException { switch (checkFlag(COL)) { case NORMAL: - return (Collection)BinaryUtils.doReadCollection(in, ctx, ldr, this, false, true, factory); + return doReadCollection(false, true, factory); case HANDLE: { - int handlePos = BinaryUtils.positionForHandle(in) - in.readInt(); + int handlePos = positionForHandle() - in.readInt(); Object obj = getHandle(handlePos); @@ -1566,7 +1505,7 @@ private Collection readCollection0(@Nullable BinaryCollectionFactory factory) } /** {@inheritDoc} */ - @Nullable @Override public Map readMap(String fieldName) throws BinaryObjectException { + @Nullable @Override public final Map readMap(String fieldName) throws BinaryObjectException { try { return findFieldByName(fieldName) ? (Map)readMap0(null) : null; } @@ -1576,7 +1515,7 @@ private Collection readCollection0(@Nullable BinaryCollectionFactory factory) } /** {@inheritDoc} */ - @Nullable @Override public Map readMap(String fieldName, BinaryMapFactory factory) + @Nullable @Override public final Map readMap(String fieldName, BinaryMapFactory factory) throws BinaryObjectException { try { @@ -1593,17 +1532,17 @@ private Collection readCollection0(@Nullable BinaryCollectionFactory factory) * @return Value. * @throws BinaryObjectException In case of error. */ - @Nullable Map readMap(int fieldId, @Nullable BinaryMapFactory factory) throws BinaryObjectException { + @Nullable final Map readMap(int fieldId, @Nullable BinaryMapFactory factory) throws BinaryObjectException { return findFieldById(fieldId) ? readMap0(factory) : null; } /** {@inheritDoc} */ - @Nullable @Override public Map readMap() throws BinaryObjectException { + @Nullable @Override public final Map readMap() throws BinaryObjectException { return readMap0(null); } /** {@inheritDoc} */ - @Nullable @Override public Map readMap(BinaryMapFactory factory) + @Nullable @Override public final Map readMap(BinaryMapFactory factory) throws BinaryObjectException { return readMap0(factory); } @@ -1618,10 +1557,10 @@ private Collection readCollection0(@Nullable BinaryCollectionFactory factory) private Map readMap0(@Nullable BinaryMapFactory factory) throws BinaryObjectException { switch (checkFlag(MAP)) { case NORMAL: - return (Map)BinaryUtils.doReadMap(in, ctx, ldr, this, false, true, factory); + return doReadMap(false, true, factory); case HANDLE: { - int handlePos = BinaryUtils.positionForHandle(in) - in.readInt(); + int handlePos = positionForHandle() - in.readInt(); Object obj = getHandle(handlePos); @@ -1660,7 +1599,7 @@ else if (flag == NULL) else if (flag == HANDLE) return Flag.HANDLE; - int pos = BinaryUtils.positionForHandle(in); + int pos = positionForHandle(); throw new BinaryObjectException("Unexpected field type [pos=" + pos + ", expected=" + fieldFlagName(expFlag) + ", actual=" + fieldFlagName(flag) + ']'); @@ -1681,7 +1620,7 @@ private Flag checkFlagNoHandles(byte expFlag) { else if (flag == NULL) return Flag.NULL; - int pos = BinaryUtils.positionForHandle(in); + int pos = positionForHandle(); throw new BinaryObjectException("Unexpected field type [pos=" + pos + ", expected=" + fieldFlagName(expFlag) + ", actual=" + fieldFlagName(flag) + ']'); @@ -1700,7 +1639,7 @@ private String fieldFlagName(byte flag) { } /** {@inheritDoc} */ - @Override public BinaryRawReader rawReader() { + @Override public final BinaryRawReader rawReader() { if (!raw) { streamPositionRandom(rawOff); @@ -1750,7 +1689,7 @@ private String fieldFlagName(byte flag) { streamPosition(handlePos); - obj = BinaryUtils.doReadObject(in, ctx, ldr, this); + obj = doReadObject(); streamPosition(retPos); } @@ -1813,7 +1752,7 @@ private String fieldFlagName(byte flag) { break; case DECIMAL: - obj = BinaryUtils.doReadDecimal(in); + obj = doReadDecimal(); break; @@ -1823,22 +1762,22 @@ private String fieldFlagName(byte flag) { break; case UUID: - obj = BinaryUtils.doReadUuid(in); + obj = doReadUuid(); break; case DATE: - obj = BinaryUtils.doReadDate(in); + obj = doReadDate(); break; case TIMESTAMP: - obj = BinaryUtils.doReadTimestamp(in); + obj = doReadTimestamp(); break; case TIME: - obj = BinaryUtils.doReadTime(in); + obj = doReadTime(); break; @@ -1848,42 +1787,42 @@ private String fieldFlagName(byte flag) { break; case SHORT_ARR: - obj = BinaryUtils.doReadShortArray(in); + obj = doReadShortArray(); break; case INT_ARR: - obj = BinaryUtils.doReadIntArray(in); + obj = doReadIntArray(); break; case LONG_ARR: - obj = BinaryUtils.doReadLongArray(in); + obj = doReadLongArray(); break; case FLOAT_ARR: - obj = BinaryUtils.doReadFloatArray(in); + obj = doReadFloatArray(); break; case DOUBLE_ARR: - obj = BinaryUtils.doReadDoubleArray(in); + obj = doReadDoubleArray(); break; case CHAR_ARR: - obj = BinaryUtils.doReadCharArray(in); + obj = doReadCharArray(); break; case BOOLEAN_ARR: - obj = BinaryUtils.doReadBooleanArray(in); + obj = doReadBooleanArray(); break; case DECIMAL_ARR: - obj = BinaryUtils.doReadDecimalArray(in); + obj = doReadDecimalArray(); break; @@ -1893,74 +1832,74 @@ private String fieldFlagName(byte flag) { break; case UUID_ARR: - obj = BinaryUtils.doReadUuidArray(in); + obj = doReadUuidArray(); break; case DATE_ARR: - obj = BinaryUtils.doReadDateArray(in); + obj = doReadDateArray(); break; case TIMESTAMP_ARR: - obj = BinaryUtils.doReadTimestampArray(in); + obj = doReadTimestampArray(); break; case TIME_ARR: - obj = BinaryUtils.doReadTimeArray(in); + obj = doReadTimeArray(); break; case OBJ_ARR: - obj = BinaryUtils.doReadObjectArray(in, ctx, ldr, this, false, true); + obj = doReadObjectArray(false, true); break; case COL: - obj = BinaryUtils.doReadCollection(in, ctx, ldr, this, false, true, null); + obj = doReadCollection(false, true, null); break; case MAP: - obj = BinaryUtils.doReadMap(in, ctx, ldr, this, false, true, null); + obj = doReadMap(false, true, null); break; case BINARY_OBJ: - obj = BinaryUtils.doReadBinaryObject(in, ctx, false); + obj = doReadBinaryObject(false); ((BinaryObjectImpl)obj).context(ctx); break; case ENUM: - obj = doReadEnum(in, BinaryUtils.doReadClass(in, ctx, ldr)); + obj = doReadEnum(doReadClass()); break; case ENUM_ARR: - obj = doReadEnumArray(in, ctx, ldr, BinaryUtils.doReadClass(in, ctx, ldr)); + obj = doReadEnumArray(doReadClass()); break; case BINARY_ENUM: - obj = doReadBinaryEnum(in, ctx); + obj = doReadBinaryEnum(); break; case CLASS: - obj = BinaryUtils.doReadClass(in, ctx, ldr); + obj = doReadClass(); break; case PROXY: - obj = BinaryUtils.doReadProxy(in, ctx, ldr, this); + obj = doReadProxy(); break; case OPTM_MARSH: - obj = BinaryUtils.doReadOptimized(in, ctx, ldr); + obj = BinaryImplUtils.doReadOptimized(in, ctx, ldr); break; @@ -1976,11 +1915,11 @@ private String fieldFlagName(byte flag) { * @return Deserialized object. * @throws BinaryObjectException If failed. */ - @Nullable Object readField(int fieldId) throws BinaryObjectException { + @Nullable final Object readField(int fieldId) throws BinaryObjectException { if (!findFieldById(fieldId)) return null; - return BinaryUtils.reader(ctx, in, ldr, hnds, false, true).deserialize(); + return new BinaryReaderExImpl(ctx, in, ldr, hnds, false, true).deserialize(); } /** @@ -1998,7 +1937,7 @@ private int fieldId(String name) { * * @return Schema. */ - public BinarySchema getOrCreateSchema() { + public final BinarySchema getOrCreateSchema() { BinarySchema schema = ctx.schemaRegistry(typeId).schema(schemaId); if (schema == null) { @@ -2049,7 +1988,7 @@ public BinarySchema getOrCreateSchema() { } /** {@inheritDoc} */ - @Override public Object unmarshallJdbc(byte type, boolean binObjAllow, boolean deserialize) { + @Override public final Object unmarshallJdbc(byte type, boolean binObjAllow, boolean deserialize) { switch (type) { case GridBinaryMarshaller.NULL: return null; @@ -2082,61 +2021,61 @@ public BinarySchema getOrCreateSchema() { return BinaryUtils.doReadString(in()); case GridBinaryMarshaller.DECIMAL: - return BinaryUtils.doReadDecimal(in()); + return doReadDecimal(); case GridBinaryMarshaller.UUID: - return BinaryUtils.doReadUuid(in()); + return doReadUuid(); case GridBinaryMarshaller.TIME: - return BinaryUtils.doReadTime(in()); + return doReadTime(); case GridBinaryMarshaller.TIMESTAMP: - return BinaryUtils.doReadTimestamp(in()); + return doReadTimestamp(); case GridBinaryMarshaller.DATE: - return BinaryUtils.doReadDate(in()); + return doReadDate(); case GridBinaryMarshaller.BOOLEAN_ARR: - return BinaryUtils.doReadBooleanArray(in()); + return doReadBooleanArray(); case GridBinaryMarshaller.BYTE_ARR: return BinaryUtils.doReadByteArray(in()); case GridBinaryMarshaller.CHAR_ARR: - return BinaryUtils.doReadCharArray(in()); + return doReadCharArray(); case GridBinaryMarshaller.SHORT_ARR: - return BinaryUtils.doReadShortArray(in()); + return doReadShortArray(); case GridBinaryMarshaller.INT_ARR: - return BinaryUtils.doReadIntArray(in()); + return doReadIntArray(); case GridBinaryMarshaller.LONG_ARR: - return BinaryUtils.doReadLongArray(in()); + return doReadLongArray(); case GridBinaryMarshaller.FLOAT_ARR: - return BinaryUtils.doReadFloatArray(in()); + return doReadFloatArray(); case GridBinaryMarshaller.DOUBLE_ARR: - return BinaryUtils.doReadDoubleArray(in()); + return doReadDoubleArray(); case GridBinaryMarshaller.STRING_ARR: return BinaryUtils.doReadStringArray(in()); case GridBinaryMarshaller.DECIMAL_ARR: - return BinaryUtils.doReadDecimalArray(in()); + return doReadDecimalArray(); case GridBinaryMarshaller.UUID_ARR: - return BinaryUtils.doReadUuidArray(in()); + return doReadUuidArray(); case GridBinaryMarshaller.TIME_ARR: - return BinaryUtils.doReadTimeArray(in()); + return doReadTimeArray(); case GridBinaryMarshaller.TIMESTAMP_ARR: - return BinaryUtils.doReadTimestampArray(in()); + return doReadTimestampArray(); case GridBinaryMarshaller.DATE_ARR: - return BinaryUtils.doReadDateArray(in()); + return doReadDateArray(); default: in().position(in().position() - 1); @@ -2183,7 +2122,7 @@ private BinarySchema createSchema() { * @param name Field name. * @return Offset. */ - public boolean findFieldByName(String name) { + public final boolean findFieldByName(String name) { if (raw) throw new BinaryObjectException("Failed to read named field because reader is in raw mode."); @@ -2370,17 +2309,17 @@ private void streamPositionRandom(int pos) { } /** {@inheritDoc} */ - @Override public int readUnsignedByte() throws IOException { + @Override public final int readUnsignedByte() throws IOException { return readByte() & 0xff; } /** {@inheritDoc} */ - @Override public int readUnsignedShort() throws IOException { + @Override public final int readUnsignedShort() throws IOException { return readShort() & 0xffff; } /** {@inheritDoc} */ - @Override public String readLine() throws IOException { + @Override public final String readLine() throws IOException { SB sb = new SB(); int b; @@ -2412,17 +2351,17 @@ private void streamPositionRandom(int pos) { /** {@inheritDoc} */ @SuppressWarnings("ConstantConditions") - @NotNull @Override public String readUTF() throws IOException { + @NotNull @Override public final String readUTF() throws IOException { return readString(); } /** {@inheritDoc} */ - @Override public void readFully(byte[] b) throws IOException { + @Override public final void readFully(byte[] b) throws IOException { readFully(b, 0, b.length); } /** {@inheritDoc} */ - @Override public void readFully(byte[] b, int off, int len) throws IOException { + @Override public final void readFully(byte[] b, int off, int len) throws IOException { int cnt = in.read(b, off, len); if (cnt < len) @@ -2430,7 +2369,7 @@ private void streamPositionRandom(int pos) { } /** {@inheritDoc} */ - @Override public int skipBytes(int n) throws IOException { + @Override public final int skipBytes(int n) throws IOException { int toSkip = Math.min(in.remaining(), n); streamPositionRandom(in.position() + toSkip); @@ -2439,44 +2378,39 @@ private void streamPositionRandom(int pos) { } /** {@inheritDoc} */ - @Override public int read() throws IOException { + @Override public final int read() throws IOException { return readByte(); } /** {@inheritDoc} */ - @Override public int read(byte[] b) throws IOException { + @Override public final int read(byte[] b) throws IOException { return read(b, 0, b.length); } /** {@inheritDoc} */ - @Override public int read(byte[] b, int off, int len) throws IOException { + @Override public final int read(byte[] b, int off, int len) throws IOException { return in.read(b, off, len); } /** {@inheritDoc} */ - @Override public long skip(long n) throws IOException { + @Override public final long skip(long n) throws IOException { return skipBytes((int)n); } /** {@inheritDoc} */ - @Override public int available() throws IOException { + @Override public final int available() throws IOException { return in.remaining(); } /** {@inheritDoc} */ - @Override public boolean isEmpty() { - return hnds == null || hnds.isEmpty(); - } - - /** {@inheritDoc} */ - @Override public void close() throws IOException { + @Override public final void close() throws IOException { // No-op. } /** * @return Binary context. */ - public BinaryContext context() { + public final BinaryContext context() { return ctx; } @@ -2664,7 +2598,7 @@ private void readField(Object obj, BinaryFieldDescriptor fld) { * @return Read value. * @throws BinaryObjectException If failed to read value from the stream. */ - protected Object readFixedType(BinaryFieldDescriptor fld) throws BinaryObjectException { + protected final Object readFixedType(BinaryFieldDescriptor fld) throws BinaryObjectException { Object val = null; switch (fld.mode) { @@ -2864,19 +2798,17 @@ protected Object readFixedType(BinaryFieldDescriptor fld) throws BinaryObjectExc /** * Read binary enum. * - * @param in Input stream. - * @param ctx Binary context. * @return Enum. */ - private static BinaryObjectEx doReadBinaryEnum(BinaryInputStream in, BinaryContext ctx) { - return BinaryUtils.doReadBinaryEnum(in, ctx, BinaryUtils.doReadEnumType(in)); + private BinaryObjectEx doReadBinaryEnum() { + return doReadBinaryEnum(doReadEnumType()); } /** * @param cls Enum class. * @return Value. */ - private static Object[] doReadEnumArray(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr, Class cls) + private Object[] doReadEnumArray(Class cls) throws BinaryObjectException { int len = in.readInt(); @@ -2888,7 +2820,7 @@ private static Object[] doReadEnumArray(BinaryInputStream in, BinaryContext ctx, if (flag == GridBinaryMarshaller.NULL) arr[i] = null; else - arr[i] = doReadEnum(in, BinaryUtils.doReadClass(in, ctx, ldr)); + arr[i] = doReadEnum(doReadClass()); } return arr; @@ -2900,7 +2832,7 @@ private static Object[] doReadEnumArray(BinaryInputStream in, BinaryContext ctx, * @param cls Enum class. * @return Value. */ - private static Enum doReadEnum(BinaryInputStream in, Class cls) throws BinaryObjectException { + private Enum doReadEnum(Class cls) throws BinaryObjectException { assert cls != null; if (!cls.isEnum()) @@ -2963,4 +2895,5 @@ private enum Flag { /** Null. */ NULL } + } diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java index 1356fe89f2c43..c11f2fc7ef9ce 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java @@ -107,7 +107,7 @@ public class BinaryWriterExImpl implements BinaryWriterEx { * @param failIfUnregistered Flag to fail while writing object of unregistered type. * @param typeId Type id. */ - public BinaryWriterExImpl( + BinaryWriterExImpl( BinaryContext ctx, BinaryOutputStream out, @Nullable BinaryWriterSchemaHolder schema, diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/CrossObjectReferenceResolver.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/CrossObjectReferenceResolver.java index d5c06d7032e44..5e55c55de901f 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/CrossObjectReferenceResolver.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/CrossObjectReferenceResolver.java @@ -31,8 +31,8 @@ import static org.apache.ignite.internal.binary.BinaryImplUtils.hasRaw; import static org.apache.ignite.internal.binary.BinaryImplUtils.hasSchema; import static org.apache.ignite.internal.binary.BinaryImplUtils.isCompactFooter; +import static org.apache.ignite.internal.binary.BinaryImplUtils.length; import static org.apache.ignite.internal.binary.BinaryImplUtils.rawOffsetAbsolute; -import static org.apache.ignite.internal.binary.BinaryUtils.length; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.DFLT_HDR_LEN; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.FLAGS_POS; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.HASH_CODE_POS; diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/ObjectDetachHelper.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/ObjectDetachHelper.java index d5e40860186e0..75f925b28d5c1 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/ObjectDetachHelper.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/ObjectDetachHelper.java @@ -22,8 +22,8 @@ import org.apache.ignite.internal.binary.streams.BinaryStreams; import static org.apache.ignite.internal.binary.BinaryImplUtils.dataStartRelative; +import static org.apache.ignite.internal.binary.BinaryImplUtils.length; import static org.apache.ignite.internal.binary.BinaryImplUtils.rawOffsetAbsolute; -import static org.apache.ignite.internal.binary.BinaryUtils.length; /** */ class ObjectDetachHelper { diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/RawBinaryObjectExtractor.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/RawBinaryObjectExtractor.java index b75f6a53d9c1e..d8d4fb9231770 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/RawBinaryObjectExtractor.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/RawBinaryObjectExtractor.java @@ -90,7 +90,7 @@ void skipObject() { break; case GridBinaryMarshaller.OBJ: - skipBytes(BinaryUtils.length(in, objStartPos) - /** Object type. */ Byte.BYTES); + skipBytes(BinaryImplUtils.length(in, objStartPos) - /** Object type. */ Byte.BYTES); break; diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/SimpleBinaryReader.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/SimpleBinaryReader.java new file mode 100644 index 0000000000000..2d60ef264b586 --- /dev/null +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/SimpleBinaryReader.java @@ -0,0 +1,940 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.internal.binary; + +import java.lang.reflect.Array; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedList; +import java.util.Map; +import java.util.UUID; +import org.apache.ignite.binary.BinaryCollectionFactory; +import org.apache.ignite.binary.BinaryInvalidTypeException; +import org.apache.ignite.binary.BinaryMapFactory; +import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.internal.binary.streams.BinaryInputStream; +import org.apache.ignite.internal.marshaller.ClassLoaderUtils; +import org.apache.ignite.internal.util.CommonUtils; +import org.apache.ignite.internal.util.MutableSingletonList; +import org.apache.ignite.marshaller.Marshallers; +import org.jetbrains.annotations.Nullable; + +/** + * Reader that unmarshals a binary stream without parsing an object header. + * Holds only the state the {@link #unmarshal()} family needs, so it can be allocated + * cheaply on the paths that merely wrap bytes into a {@link org.apache.ignite.binary.BinaryObject}. + * {@link BinaryReaderExImpl} extends it with full header, schema and field access. + */ +class SimpleBinaryReader { + /** Binary context. */ + final BinaryContext ctx; + + /** Input stream. */ + final BinaryInputStream in; + + /** + * Class loader to resolve classes with: custom loader or {@link BinaryContext#classLoader()}, resolved once here. + * {@code null} only when {@link #ctx} is {@code null}; such readers can read primitives only. + */ + final ClassLoader ldr; + + /** Reader context which is constantly passed between objects. */ + BinaryReaderHandles hnds; + + /** + * @param ctx Context. + * @param in Input stream. + * @param ldr Custom class loader or {@code null} to use {@link BinaryContext#classLoader()}. + */ + SimpleBinaryReader(BinaryContext ctx, BinaryInputStream in, @Nullable ClassLoader ldr) { + this.ctx = ctx; + this.in = in; + this.ldr = ctx == null ? ldr : ctx.resolveClassLoader(ldr); + } + + /** + * Set handle. + * + * @param obj Object. + * @param pos Position. + */ + final void setHandle(Object obj, int pos) { + handles().put(pos, obj); + } + + /** + * Get handle. + * + * @param pos Position. + * @return Handle. + */ + final Object getHandle(int pos) { + return hnds != null ? hnds.get(pos) : null; + } + + /** + * Get all handles. + * + * @return Handles. + */ + public final BinaryReaderHandles handles() { + if (hnds == null) + hnds = new BinaryReaderHandles(); + + return hnds; + } + + /** + * @return Value. + */ + final boolean[] doReadBooleanArray() { + int len = in.readInt(); + + return in.readBooleanArray(len); + } + + /** + * @return Value. + */ + final short[] doReadShortArray() { + int len = in.readInt(); + + return in.readShortArray(len); + } + + /** + * @return Value. + */ + final char[] doReadCharArray() { + int len = in.readInt(); + + return in.readCharArray(len); + } + + /** + * @return Value. + */ + final int[] doReadIntArray() { + int len = in.readInt(); + + return in.readIntArray(len); + } + + /** + * @return Value. + */ + final long[] doReadLongArray() { + int len = in.readInt(); + + return in.readLongArray(len); + } + + /** + * @return Value. + */ + final float[] doReadFloatArray() { + int len = in.readInt(); + + return in.readFloatArray(len); + } + + /** + * @return Value. + */ + final double[] doReadDoubleArray() { + int len = in.readInt(); + + return in.readDoubleArray(len); + } + + /** + * @return Value. + */ + final BigDecimal doReadDecimal() { + int scale = in.readInt(); + byte[] mag = BinaryUtils.doReadByteArray(in); + + boolean negative = mag[0] < 0; + + if (negative) + mag[0] &= 0x7F; + + BigInteger intVal = new BigInteger(mag); + + if (negative) + intVal = intVal.negate(); + + return new BigDecimal(intVal, scale); + } + + /** + * @return Value. + */ + final UUID doReadUuid() { + return new UUID(in.readLong(), in.readLong()); + } + + /** + * @return Value. + */ + final Date doReadDate() { + long time = in.readLong(); + + return new Date(time); + } + + /** + * @return Value. + */ + final Timestamp doReadTimestamp() { + long time = in.readLong(); + int nanos = in.readInt(); + + Timestamp ts = new Timestamp(time); + + ts.setNanos(ts.getNanos() + nanos); + + return ts; + } + + /** + * @return Value. + */ + final Time doReadTime() { + long time = in.readLong(); + + return new Time(time); + } + + /** + * @return Value. + * @throws BinaryObjectException In case of error. + */ + final BigDecimal[] doReadDecimalArray() throws BinaryObjectException { + int len = in.readInt(); + + BigDecimal[] arr = new BigDecimal[len]; + + for (int i = 0; i < len; i++) { + byte flag = in.readByte(); + + if (flag == GridBinaryMarshaller.NULL) + arr[i] = null; + else { + if (flag != GridBinaryMarshaller.DECIMAL) + throw new BinaryObjectException("Invalid flag value: " + flag); + + arr[i] = doReadDecimal(); + } + } + + return arr; + } + + /** + * @return Value. + * @throws BinaryObjectException In case of error. + */ + final UUID[] doReadUuidArray() throws BinaryObjectException { + int len = in.readInt(); + + UUID[] arr = new UUID[len]; + + for (int i = 0; i < len; i++) { + byte flag = in.readByte(); + + if (flag == GridBinaryMarshaller.NULL) + arr[i] = null; + else { + if (flag != GridBinaryMarshaller.UUID) + throw new BinaryObjectException("Invalid flag value: " + flag); + + arr[i] = doReadUuid(); + } + } + + return arr; + } + + /** + * @return Value. + * @throws BinaryObjectException In case of error. + */ + final Date[] doReadDateArray() throws BinaryObjectException { + int len = in.readInt(); + + Date[] arr = new Date[len]; + + for (int i = 0; i < len; i++) { + byte flag = in.readByte(); + + if (flag == GridBinaryMarshaller.NULL) + arr[i] = null; + else { + if (flag != GridBinaryMarshaller.DATE) + throw new BinaryObjectException("Invalid flag value: " + flag); + + arr[i] = doReadDate(); + } + } + + return arr; + } + + /** + * @return Value. + * @throws BinaryObjectException In case of error. + */ + final Timestamp[] doReadTimestampArray() throws BinaryObjectException { + int len = in.readInt(); + + Timestamp[] arr = new Timestamp[len]; + + for (int i = 0; i < len; i++) { + byte flag = in.readByte(); + + if (flag == GridBinaryMarshaller.NULL) + arr[i] = null; + else { + if (flag != GridBinaryMarshaller.TIMESTAMP) + throw new BinaryObjectException("Invalid flag value: " + flag); + + arr[i] = doReadTimestamp(); + } + } + + return arr; + } + + /** + * @return Value. + * @throws BinaryObjectException In case of error. + */ + final Time[] doReadTimeArray() throws BinaryObjectException { + int len = in.readInt(); + + Time[] arr = new Time[len]; + + for (int i = 0; i < len; i++) { + byte flag = in.readByte(); + + if (flag == GridBinaryMarshaller.NULL) + arr[i] = null; + else { + if (flag != GridBinaryMarshaller.TIME) + throw new BinaryObjectException("Invalid flag value: " + flag); + + arr[i] = doReadTime(); + } + } + + return arr; + } + + /** + * @return Value. + */ + final BinaryObject doReadBinaryObject(boolean detach) { + if (in.offheapPointer() > 0) { + int len = in.readInt(); + + int pos = in.position(); + + in.position(in.position() + len); + + int start = in.readInt(); + + return BinaryUtils.binariesFactory.binaryOffheapObject(ctx, in.offheapPointer() + pos, start, len); + } + else { + byte[] arr = BinaryUtils.doReadByteArray(in); + int start = in.readInt(); + + BinaryObject binO = BinaryUtils.binariesFactory.binaryObject(ctx, arr, start); + + if (detach) + return BinaryUtils.detach(binO); + + return binO; + } + } + + /** + * @return Class object specified at the input stream. + * @throws BinaryObjectException If failed. + */ + final Class doReadClass() + throws BinaryObjectException { + return doReadClass(true); + } + + /** + * @param deserialize Doesn't load the class when the flag is {@code false}. Class information is skipped. + * @return Class object specified at the input stream if {@code deserialize == true}. Otherwise returns {@code null} + * @throws BinaryObjectException If failed. + */ + final Class doReadClass(boolean deserialize) + throws BinaryObjectException { + int typeId = in.readInt(); + + if (!deserialize) { + // Skip class name at the stream. + if (typeId == GridBinaryMarshaller.UNREGISTERED_TYPE_ID) + BinaryImplUtils.doReadClassName(in); + + return null; + } + + return doReadClass(typeId); + } + + /** + * @return Value. + */ + @SuppressWarnings("ConstantConditions") + final Object doReadProxy() { + Class[] intfs = new Class[in.readInt()]; + + for (int i = 0; i < intfs.length; i++) + intfs[i] = doReadClass(); + + InvocationHandler ih = (InvocationHandler)doReadObject(); + + return Proxy.newProxyInstance(ldr, intfs, ih); + } + + /** + * Read plain type. + * + * @return Plain type. + */ + final EnumType doReadEnumType() { + int typeId = in.readInt(); + + if (typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID) + return new EnumType(typeId, null); + else { + String clsName = BinaryImplUtils.doReadClassName(in); + + return new EnumType(GridBinaryMarshaller.UNREGISTERED_TYPE_ID, clsName); + } + } + + /** + * @param typeId Type id. + * @return Class object specified at the input stream. + * @throws BinaryObjectException If failed. + */ + final Class doReadClass(int typeId) + throws BinaryObjectException { + Class cls; + + if (typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID) + cls = ctx.descriptorForTypeId(true, typeId, ldr, false).describedClass(); + else { + String clsName = BinaryImplUtils.doReadClassName(in); + + try { + cls = ClassLoaderUtils.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 + if (Marshallers.USE_CACHE.get()) + ctx.registerType(cls, false, false); + } + + return cls; + } + + /** + * Read binary enum. + * + * @param type Plain type. + * @return Enum. + */ + final BinaryObjectEx doReadBinaryEnum(EnumType type) { + return BinaryUtils.binariesFactory.binaryEnum(ctx, type.typeId, type.clsName, in.readInt()); + } + + /** + * Read binary enum array. + * + * @return Enum array. + */ + private Object[] doReadBinaryEnumArray() { + int len = in.readInt(); + + Object[] arr = (Object[])Array.newInstance(BinaryUtils.binariesFactory.binaryEnumClass(), len); + + for (int i = 0; i < len; i++) { + byte flag = in.readByte(); + + if (flag == GridBinaryMarshaller.NULL) + arr[i] = null; + else + arr[i] = doReadBinaryEnum(doReadEnumType()); + } + + return arr; + } + + /** + * @return Object. + * @throws BinaryObjectException In case of error. + */ + @Nullable final Object doReadObject() throws BinaryObjectException { + return new BinaryReaderExImpl(ctx, in, ldr, handles(), false, true).deserialize(); + } + + /** + * @return Unmarshalled value. + * @throws BinaryObjectException In case of error. + */ + @Nullable final Object unmarshal() throws BinaryObjectException { + return unmarshal(false, false); + } + + /** + * @return Unmarshalled value. + * @throws BinaryObjectException In case of error. + */ + @Nullable final Object unmarshal(boolean detach, boolean deserialize) throws BinaryObjectException { + int start = in.position(); + + byte flag = in.readByte(); + + switch (flag) { + case GridBinaryMarshaller.NULL: + return null; + + case GridBinaryMarshaller.HANDLE: { + int handlePos = start - in.readInt(); + + Object obj = getHandle(handlePos); + + if (obj == null) { + int retPos = in.position(); + + in.position(handlePos); + + obj = unmarshal(detach, deserialize); + + in.position(retPos); + } + + return obj; + } + + case GridBinaryMarshaller.OBJ: { + BinaryImplUtils.checkProtocolVersion(in.readByte()); + + int len = BinaryImplUtils.length(in, start); + + BinaryObjectEx po; + + if (detach) { + BinaryObjectEx binObj = BinaryUtils.binariesFactory.binaryObject(ctx, in.array(), start); + + binObj.detachAllowed(true); + + po = binObj.detach(hnds != null && !hnds.isEmpty()); + } + else { + if (in.offheapPointer() == 0) + po = BinaryUtils.binariesFactory.binaryObject(ctx, in.array(), start); + else + po = BinaryUtils.binariesFactory.binaryOffheapObject(ctx, in.offheapPointer(), start, + in.remaining() + in.position()); + } + + in.position(start + len); + + setHandle(po, start); + + return po; + } + + case GridBinaryMarshaller.BYTE: + return in.readByte(); + + case GridBinaryMarshaller.SHORT: + return in.readShort(); + + case GridBinaryMarshaller.INT: + return in.readInt(); + + case GridBinaryMarshaller.LONG: + return in.readLong(); + + case GridBinaryMarshaller.FLOAT: + return in.readFloat(); + + case GridBinaryMarshaller.DOUBLE: + return in.readDouble(); + + case GridBinaryMarshaller.CHAR: + return in.readChar(); + + case GridBinaryMarshaller.BOOLEAN: + return in.readBoolean(); + + case GridBinaryMarshaller.DECIMAL: + return doReadDecimal(); + + case GridBinaryMarshaller.STRING: + return BinaryUtils.doReadString(in); + + case GridBinaryMarshaller.UUID: + return doReadUuid(); + + case GridBinaryMarshaller.DATE: + return doReadDate(); + + case GridBinaryMarshaller.TIMESTAMP: + return doReadTimestamp(); + + case GridBinaryMarshaller.TIME: + return doReadTime(); + + case GridBinaryMarshaller.BYTE_ARR: + return BinaryUtils.doReadByteArray(in); + + case GridBinaryMarshaller.SHORT_ARR: + return doReadShortArray(); + + case GridBinaryMarshaller.INT_ARR: + return doReadIntArray(); + + case GridBinaryMarshaller.LONG_ARR: + return doReadLongArray(); + + case GridBinaryMarshaller.FLOAT_ARR: + return doReadFloatArray(); + + case GridBinaryMarshaller.DOUBLE_ARR: + return doReadDoubleArray(); + + case GridBinaryMarshaller.CHAR_ARR: + return doReadCharArray(); + + case GridBinaryMarshaller.BOOLEAN_ARR: + return doReadBooleanArray(); + + case GridBinaryMarshaller.DECIMAL_ARR: + return doReadDecimalArray(); + + case GridBinaryMarshaller.STRING_ARR: + return BinaryUtils.doReadStringArray(in); + + case GridBinaryMarshaller.UUID_ARR: + return doReadUuidArray(); + + case GridBinaryMarshaller.DATE_ARR: + return doReadDateArray(); + + case GridBinaryMarshaller.TIMESTAMP_ARR: + return doReadTimestampArray(); + + case GridBinaryMarshaller.TIME_ARR: + return doReadTimeArray(); + + case GridBinaryMarshaller.OBJ_ARR: + if (BinaryUtils.useBinaryArrays() && !deserialize) + return doReadBinaryArray(detach, deserialize, false); + else + return doReadObjectArray(detach, deserialize); + + case GridBinaryMarshaller.COL: + return doReadCollection(detach, deserialize, null); + + case GridBinaryMarshaller.MAP: + return doReadMap(detach, deserialize, null); + + case GridBinaryMarshaller.BINARY_OBJ: + return doReadBinaryObject(detach); + + case GridBinaryMarshaller.ENUM: + case GridBinaryMarshaller.BINARY_ENUM: + return doReadBinaryEnum(doReadEnumType()); + + case GridBinaryMarshaller.ENUM_ARR: + if (BinaryUtils.useBinaryArrays() && !deserialize) + return doReadBinaryArray(detach, deserialize, true); + else { + doReadEnumType(); // Simply skip this part as we do not need it. + + return doReadBinaryEnumArray(); + } + + case GridBinaryMarshaller.CLASS: + return doReadClass(); + + case GridBinaryMarshaller.PROXY: + return doReadProxy(); + + case GridBinaryMarshaller.OPTM_MARSH: + return BinaryImplUtils.doReadOptimized(in, ctx, ldr); + + default: + throw new BinaryObjectException("Invalid flag value: " + flag); + } + } + + /** + * @param detach Detach flag. + * @param deserialize Deep flag. + * @return Value. + * @throws BinaryObjectException In case of error. + */ + final Object[] doReadObjectArray(boolean detach, boolean deserialize) throws BinaryObjectException { + int hPos = positionForHandle(); + + Class compType = doReadClass(deserialize); + + int len = in.readInt(); + + Object[] arr = (deserialize && !BinaryObject.class.isAssignableFrom(compType)) + ? (Object[])Array.newInstance(compType, len) + : new Object[len]; + + setHandle(arr, hPos); + + for (int i = 0; i < len; i++) { + Object res = deserializeOrUnmarshal(detach, deserialize); + + if (deserialize && BinaryUtils.useBinaryArrays() && res instanceof BinaryObject) + arr[i] = ((BinaryObject)res).deserialize(ldr); + else + arr[i] = res; + } + + return arr; + } + + /** + * @param detach Detach flag. + * @param deserialize Deep flag. + * @return Value. + * @throws BinaryObjectException In case of error. + */ + private BinaryArray doReadBinaryArray(boolean detach, boolean deserialize, boolean isEnumArray) { + int hPos = positionForHandle(); + + int compTypeId = in.readInt(); + String compClsName = null; + + if (compTypeId == GridBinaryMarshaller.UNREGISTERED_TYPE_ID) + compClsName = BinaryImplUtils.doReadClassName(in); + + int len = in.readInt(); + + Object[] arr = new Object[len]; + + BinaryArray res = isEnumArray + ? new BinaryEnumArray(ctx, compTypeId, compClsName, arr) + : new BinaryArray(ctx, compTypeId, compClsName, arr); + + setHandle(res, hPos); + + for (int i = 0; i < len; i++) + arr[i] = deserializeOrUnmarshal(detach, deserialize); + + return res; + } + + /** + * @param deserialize Deep flag. + * @param factory Collection factory. + * @return Value. + * @throws BinaryObjectException In case of error. + */ + @SuppressWarnings("unchecked") + final Collection doReadCollection(boolean detach, boolean deserialize, BinaryCollectionFactory factory) + throws BinaryObjectException { + int hPos = positionForHandle(); + + int size = in.readInt(); + + assert size >= 0; + + byte colType = in.readByte(); + + Collection col; + + if (factory != null) + col = factory.create(size); + else { + switch (colType) { + case GridBinaryMarshaller.ARR_LIST: + col = new ArrayList<>(size); + + break; + + case GridBinaryMarshaller.LINKED_LIST: + col = new LinkedList<>(); + + break; + + case GridBinaryMarshaller.SINGLETON_LIST: + col = new MutableSingletonList<>(); + + break; + + case GridBinaryMarshaller.HASH_SET: + col = CommonUtils.newHashSet(size); + + break; + + case GridBinaryMarshaller.LINKED_HASH_SET: + col = CommonUtils.newLinkedHashSet(size); + + break; + + case GridBinaryMarshaller.USER_SET: + col = CommonUtils.newHashSet(size); + + break; + + case GridBinaryMarshaller.USER_COL: + col = new ArrayList<>(size); + + break; + + default: + throw new BinaryObjectException("Invalid collection type: " + colType); + } + } + + setHandle(col, hPos); + + for (int i = 0; i < size; i++) + col.add(deserializeOrUnmarshal(detach, deserialize)); + + return colType == GridBinaryMarshaller.SINGLETON_LIST ? CommonUtils.convertToSingletonList(col) : col; + } + + /** + * @param deserialize Deep flag. + * @param factory Map factory. + * @return Value. + * @throws BinaryObjectException In case of error. + */ + @SuppressWarnings("unchecked") + final Map doReadMap(boolean detach, boolean deserialize, BinaryMapFactory factory) + throws BinaryObjectException { + int hPos = positionForHandle(); + + int size = in.readInt(); + + assert size >= 0; + + byte mapType = in.readByte(); + + Map map; + + if (factory != null) + map = factory.create(size); + else { + switch (mapType) { + case GridBinaryMarshaller.HASH_MAP: + map = CommonUtils.newHashMap(size); + + break; + + case GridBinaryMarshaller.LINKED_HASH_MAP: + map = CommonUtils.newLinkedHashMap(size); + + break; + + case GridBinaryMarshaller.USER_COL: + map = CommonUtils.newHashMap(size); + + break; + + default: + throw new BinaryObjectException("Invalid map type: " + mapType); + } + } + + setHandle(map, hPos); + + for (int i = 0; i < size; i++) { + Object key = deserializeOrUnmarshal(detach, deserialize); + Object val = deserializeOrUnmarshal(detach, deserialize); + + map.put(key, val); + } + + return map; + } + + /** + * Deserialize or unmarshal the object. + * + * @param deserialize Deserialize. + * @return Result. + */ + private Object deserializeOrUnmarshal(boolean detach, boolean deserialize) { + return deserialize ? doReadObject() : unmarshal(detach, deserialize); + } + + /** + * Get position to be used for handle. We assume here that the hdr byte was read, hence subtract -1. + * + * @return Position for handle. + */ + final int positionForHandle() { + return in.position() - 1; + } + + /** + * Enum type. + */ + static class EnumType { + /** Type ID. */ + private final int typeId; + + /** Class name. */ + private final String clsName; + + /** + * Constructor. + * + * @param typeId Type ID. + * @param clsName Class name. + */ + public EnumType(int typeId, @Nullable String clsName) { + assert typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID && clsName == null || + typeId == GridBinaryMarshaller.UNREGISTERED_TYPE_ID && clsName != null; + + this.typeId = typeId; + this.clsName = clsName; + } + } +} diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java index c6360be745b58..52119de5f15d7 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java @@ -24,17 +24,16 @@ import java.util.Map; import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.internal.binary.BinaryContext; +import org.apache.ignite.internal.binary.BinaryImplUtils; import org.apache.ignite.internal.binary.BinaryObjectEx; import org.apache.ignite.internal.binary.BinaryObjectImpl; import org.apache.ignite.internal.binary.BinaryPositionReadable; import org.apache.ignite.internal.binary.BinaryPrimitives; import org.apache.ignite.internal.binary.BinaryReaderExImpl; -import org.apache.ignite.internal.binary.BinaryUtils; import org.apache.ignite.internal.binary.BinaryWriterExImpl; import org.apache.ignite.internal.binary.GridBinaryMarshaller; import org.apache.ignite.internal.binary.streams.BinaryInputStream; import org.apache.ignite.internal.binary.streams.BinaryStreams; -import org.apache.ignite.internal.util.CommonUtils; import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.ignite.internal.binary.builder.BinaryObjectBuildersFactoryImpl.unwrapLazy; @@ -70,7 +69,9 @@ class BinaryBuilderReader implements BinaryPositionReadable { reader = new BinaryReaderExImpl(ctx, BinaryStreams.inputStream(arr, pos), - ctx.classLoader(), + null, + null, + false, false); objMap = new HashMap<>(); @@ -91,6 +92,7 @@ class BinaryBuilderReader implements BinaryPositionReadable { BinaryStreams.inputStream(arr, start), null, other.reader.handles(), + false, false); this.objMap = other.objMap; @@ -492,7 +494,7 @@ public Object getValueQuickly(int pos, int len) { case GridBinaryMarshaller.OPTM_MARSH: { final BinaryInputStream bin = BinaryStreams.inputStream(arr, pos + 1); - final Object obj = BinaryUtils.doReadOptimized(bin, ctx, CommonUtils.resolveClassLoader(null, ctx.classLoader())); + final Object obj = BinaryImplUtils.doReadOptimized(bin, ctx, null); return obj; } @@ -844,7 +846,7 @@ else if (flag == GridBinaryMarshaller.DECIMAL) { case GridBinaryMarshaller.OPTM_MARSH: { final BinaryInputStream bin = BinaryStreams.inputStream(arr, pos); - final Object obj = BinaryUtils.doReadOptimized(bin, ctx, CommonUtils.resolveClassLoader(null, ctx.classLoader())); + final Object obj = BinaryImplUtils.doReadOptimized(bin, ctx, null); pos = bin.position(); diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java index 3b4451ec861a5..c0a66261d5b65 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java @@ -138,7 +138,7 @@ public BinaryObjectBuilderImpl(BinaryObjectEx obj) { byte ver = reader.readBytePositioned(start + GridBinaryMarshaller.PROTO_VER_POS); - BinaryUtils.checkProtocolVersion(ver); + BinaryImplUtils.checkProtocolVersion(ver); int typeId = reader.readIntPositioned(start + GridBinaryMarshaller.TYPE_ID_POS); ctx = reader.binaryContext(); @@ -333,7 +333,7 @@ else if (readCache == null) { } // Shift reader to the end of the object. - reader.position(start + BinaryUtils.length(reader, start)); + reader.position(start + BinaryImplUtils.length(reader, start)); } writer.postWrite(true, registeredType); diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerImpl.java index 6a5c4e0d1cc9d..6da379afaf557 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerImpl.java @@ -27,6 +27,7 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.internal.marshaller.ClassLoaderUtils; +import org.apache.ignite.internal.util.CommonUtils; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.marshaller.AbstractNodeNameAwareMarshaller; import org.apache.ignite.marshaller.Marshallers; @@ -83,7 +84,7 @@ */ public class OptimizedMarshallerImpl extends AbstractNodeNameAwareMarshaller implements OptimizedMarshaller { /** Default class loader. */ - private final ClassLoader dfltClsLdr = getClass().getClassLoader(); + private final ClassLoader dfltClsLdr = CommonUtils.gridClassLoader(); /** Whether or not to require an object to be serializable in order to be marshalled. */ private final boolean requireSer; diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java index e1a41bda6ba53..6fe80a6ec938b 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java @@ -43,7 +43,6 @@ import java.util.concurrent.ConcurrentMap; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.marshaller.ClassLoaderUtils; -import org.apache.ignite.internal.util.CommonUtils; import org.apache.ignite.internal.util.GridUnsafe; import org.apache.ignite.internal.util.io.GridDataInput; import org.apache.ignite.internal.util.typedef.internal.SB; @@ -330,7 +329,7 @@ private Object readObject0() throws ClassNotFoundException, IOException { InvocationHandler ih = (InvocationHandler)readObject(); - return Proxy.newProxyInstance(clsLdr != null ? clsLdr : CommonUtils.gridClassLoader(), intfs, ih); + return Proxy.newProxyInstance(clsLdr, intfs, ih); case ENUM: case EXTERNALIZABLE: diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java index e2f6d37bb9acb..1451be43174d4 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java @@ -116,9 +116,6 @@ else if (!(objFilter instanceof IgniteObjectInputFilter)) { @Override protected T unmarshal0(InputStream in, @Nullable ClassLoader clsLdr) throws IgniteCheckedException { assert in != null; - if (clsLdr == null) - clsLdr = getClass().getClassLoader(); - try (ObjectInputStream objIn = new JdkMarshallerObjectInputStream(new JdkMarshallerInputStreamWrapper(in), clsLdr)) { return (T)objIn.readObject(); } diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java index 6a5c5cb6fbdb4..15705c559e67a 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java @@ -22,13 +22,14 @@ import java.io.ObjectInputStream; import java.io.ObjectStreamClass; import org.apache.ignite.internal.marshaller.ClassLoaderUtils; +import org.jetbrains.annotations.Nullable; /** * This class defines custom JDK object input stream. */ class JdkMarshallerObjectInputStream extends ObjectInputStream { /** */ - private final ClassLoader clsLdr; + private final @Nullable ClassLoader clsLdr; /** * @param in Parent input stream. @@ -38,8 +39,6 @@ class JdkMarshallerObjectInputStream extends ObjectInputStream { JdkMarshallerObjectInputStream(InputStream in, ClassLoader clsLdr) throws IOException { super(in); - assert clsLdr != null; - this.clsLdr = clsLdr; enableResolveObject(true); diff --git a/modules/core/src/main/java/org/apache/ignite/dump/DumpReader.java b/modules/core/src/main/java/org/apache/ignite/dump/DumpReader.java index 039b7941fd350..6a4381928482a 100644 --- a/modules/core/src/main/java/org/apache/ignite/dump/DumpReader.java +++ b/modules/core/src/main/java/org/apache/ignite/dump/DumpReader.java @@ -321,7 +321,7 @@ private IgniteBiTuple, List> readStored public static List metadata(File dumpDir) { JdkMarshaller marsh = Marshallers.jdk(); - ClassLoader clsLdr = U.resolveClassLoader(new IgniteConfiguration()); + ClassLoader clsLdr = U.gridClassLoader(); // First filter only specific file to exclude overlapping with other nodes making dump on the local host. File[] files = dumpDir.listFiles(SnapshotFileTree::snapshotMetaFile); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java index c6f42c948b450..9188a7b0e6329 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java @@ -344,7 +344,7 @@ private HandshakeResult handshake(ClientListenerProtocolVersion ver) throws IOEx send(writer); - BinaryReaderEx reader = BinaryUtils.reader(ctx, BinaryStreams.inputStream(read()), null, false); + BinaryReaderEx reader = BinaryUtils.reader(ctx, BinaryStreams.inputStream(read()), false); boolean accepted = reader.readBoolean(); @@ -449,7 +449,7 @@ private HandshakeResult handshake_2_1_0() throws IOException, SQLException { send(writer); - BinaryReaderEx reader = BinaryUtils.reader(null, BinaryStreams.inputStream(read()), null, false); + BinaryReaderEx reader = BinaryUtils.reader(null, BinaryStreams.inputStream(read()), false); boolean accepted = reader.readBoolean(); @@ -538,7 +538,7 @@ void sendCancelRequest(JdbcQueryCancelRequest cancellationReq) throws IOExceptio * @throws IOException In case of IO error. */ JdbcResponse readResponse() throws IOException { - BinaryReaderEx reader = BinaryUtils.reader(ctx, BinaryStreams.inputStream(read()), null, true); + BinaryReaderEx reader = BinaryUtils.reader(ctx, BinaryStreams.inputStream(read()), true); JdbcResponse res = new JdbcResponse(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java index f9ccc8e3eb2a6..1d2dd384531e5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java @@ -403,7 +403,7 @@ public byte[] marshal(@Nullable Object obj) throws BinaryObjectException { if (!BinaryUtils.useBinaryArrays()) return pArr; - return binaryCtx.createBinaryArray(obj.getClass().getComponentType(), pArr); + return BinaryUtils.binariesFactory.binaryArray(binaryCtx, obj.getClass().getComponentType(), pArr); } if (obj instanceof IgniteBiTuple) { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java index 7bc2f4cdb15c4..4f6d1315c004a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java @@ -356,7 +356,7 @@ private void onHandshake(GridNioSession ses, ClientMessage msg) { marsh.setContext(new MarshallerContextImpl(null)); - BinaryReaderEx reader = BinaryUtils.reader(U.binaryContext(marsh), BinaryStreams.inputStream(msg.payload()), null, true); + BinaryReaderEx reader = BinaryUtils.reader(U.binaryContext(marsh), BinaryStreams.inputStream(msg.payload()), true); byte cmd = reader.readByte(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMessageParser.java index 26524a84ee785..a34403e34fb01 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMessageParser.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMessageParser.java @@ -63,7 +63,7 @@ public JdbcMessageParser(GridKernalContext ctx, JdbcProtocolContext protoCtx) { protected BinaryReaderEx createReader(ClientMessage msg) { BinaryInputStream stream = BinaryStreams.inputStream(msg.payload()); - return BinaryUtils.reader(binCtx, stream, ctx.config().getClassLoader(), true); + return BinaryUtils.reader(binCtx, stream, true); } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java index ee82742d4bbf2..4e1f0b703ab24 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java @@ -83,7 +83,7 @@ public OdbcMessageParser(GridKernalContext ctx, ClientListenerProtocolVersion ve BinaryInputStream stream = BinaryStreams.inputStream(msg.payload()); - BinaryReaderEx reader = BinaryUtils.reader(marsh.context(), stream, ctx.config().getClassLoader(), true); + BinaryReaderEx reader = BinaryUtils.reader(marsh.context(), stream, true); byte cmd = reader.readByte(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java index 2be1c9303b71d..7d803b37a94cc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java @@ -47,7 +47,6 @@ import org.apache.ignite.internal.binary.BinaryTypeImpl; import org.apache.ignite.internal.binary.BinaryUtils; import org.apache.ignite.internal.binary.BinaryWriterEx; -import org.apache.ignite.internal.binary.GridBinaryMarshaller; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture; @@ -95,7 +94,7 @@ public class PlatformContextImpl implements PlatformContext, PartitionsExchangeA private final GridKernalContext ctx; /** Marshaller. */ - private final GridBinaryMarshaller marsh; + private final BinaryContext bctx; /** Memory manager. */ private final PlatformMemoryManagerImpl mem; @@ -153,7 +152,7 @@ public PlatformContextImpl(GridKernalContext ctx, PlatformCallbackGateway gate, cacheObjProc = (CacheObjectBinaryProcessorImpl)ctx.cacheObjects(); - marsh = cacheObjProc.marshaller(); + bctx = cacheObjProc.binaryContext(); ctx.cache().context().exchange().registerExchangeAwareComponent(this); } @@ -180,11 +179,7 @@ public PlatformContextImpl(GridKernalContext ctx, PlatformCallbackGateway gate, /** {@inheritDoc} */ @Override public BinaryReaderEx reader(PlatformInputStream in) { - return BinaryUtils.reader(marsh.context(), - in, - ctx.config().getClassLoader(), - true, - true); + return BinaryUtils.reader(bctx, in); } /** {@inheritDoc} */ @@ -194,7 +189,7 @@ public PlatformContextImpl(GridKernalContext ctx, PlatformCallbackGateway gate, /** {@inheritDoc} */ @Override public BinaryWriterEx writer(PlatformOutputStream out) { - return marsh.writer(out); + return BinaryUtils.writer(bctx, out); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java index d0f54ef2136ba..9770619626305 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java @@ -17,14 +17,13 @@ package org.apache.ignite.internal.processors.platform.client; +import org.apache.ignite.internal.binary.BinaryContext; import org.apache.ignite.internal.binary.BinaryReaderEx; import org.apache.ignite.internal.binary.BinaryUtils; import org.apache.ignite.internal.binary.BinaryWriterEx; -import org.apache.ignite.internal.binary.GridBinaryMarshaller; import org.apache.ignite.internal.binary.streams.BinaryInputStream; import org.apache.ignite.internal.binary.streams.BinaryOutputStream; import org.apache.ignite.internal.binary.streams.BinaryStreams; -import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl; import org.apache.ignite.internal.processors.odbc.ClientListenerMessageParser; import org.apache.ignite.internal.processors.odbc.ClientListenerRequest; import org.apache.ignite.internal.processors.odbc.ClientListenerResponse; @@ -415,7 +414,7 @@ public class ClientMessageParser implements ClientListenerMessageParser { private static final short OP_STOP_WARMUP = 10000; /** Marshaller. */ - private final GridBinaryMarshaller marsh; + private final BinaryContext bctx; /** Client connection context */ private final ClientConnectionContext ctx; @@ -432,9 +431,7 @@ public class ClientMessageParser implements ClientListenerMessageParser { this.ctx = ctx; this.protocolCtx = protocolCtx; - - CacheObjectBinaryProcessorImpl cacheObjProc = (CacheObjectBinaryProcessorImpl)ctx.kernalContext().cacheObjects(); - marsh = cacheObjProc.marshaller(); + this.bctx = ctx.kernalContext().cacheObjects().binaryContext(); } /** {@inheritDoc} */ @@ -444,7 +441,7 @@ public class ClientMessageParser implements ClientListenerMessageParser { BinaryInputStream inStream = BinaryStreams.inputStream(msg.payload()); // skipHdrCheck must be true (we have 103 op code). - BinaryReaderEx reader = BinaryUtils.reader(marsh.context(), inStream, null, true, true); + BinaryReaderEx reader = BinaryUtils.reader(bctx, inStream); ClientListenerRequest req = decode(reader); @@ -749,7 +746,7 @@ public ClientListenerRequest decode(BinaryReaderEx reader) { BinaryOutputStream outStream = BinaryStreams.createPooledOutputStream(32, false); - BinaryWriterEx writer = marsh.writer(outStream); + BinaryWriterEx writer = BinaryUtils.writer(bctx, outStream); assert resp instanceof ClientOutgoingMessage : "Unexpected response type: " + resp.getClass(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationClosure.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationClosure.java index 6f3c8f599d200..31d67a47adfa8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationClosure.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetConfigurationClosure.java @@ -23,9 +23,10 @@ import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.PlatformConfiguration; +import org.apache.ignite.internal.binary.BinaryContext; import org.apache.ignite.internal.binary.BinaryReaderEx; +import org.apache.ignite.internal.binary.BinaryUtils; import org.apache.ignite.internal.binary.BinaryWriterEx; -import org.apache.ignite.internal.binary.GridBinaryMarshaller; import org.apache.ignite.internal.logger.platform.PlatformLogger; import org.apache.ignite.internal.processors.platform.PlatformAbstractConfigurationClosure; import org.apache.ignite.internal.processors.platform.lifecycle.PlatformLifecycleBean; @@ -119,8 +120,8 @@ private void prepare(IgniteConfiguration igniteCfg, PlatformDotNetConfigurationE try (PlatformMemory inMem = memMgr.allocate()) { PlatformOutputStream out = outMem.output(); - GridBinaryMarshaller marshaller = PlatformUtils.marshaller(); - BinaryWriterEx writer = marshaller.writer(out); + BinaryContext bctx = PlatformUtils.binaryContext(); + BinaryWriterEx writer = BinaryUtils.writer(bctx, out); PlatformConfigurationUtils.writeDotNetConfiguration(writer, interopCfg.unwrap()); @@ -149,7 +150,7 @@ private void prepare(IgniteConfiguration igniteCfg, PlatformDotNetConfigurationE gate.extensionCallbackInLongLongOutLong( PlatformUtils.OP_PREPARE_DOT_NET, outMem.pointer(), inMem.pointer()); - processPrepareResult(marshaller.reader(inMem.input())); + processPrepareResult(BinaryUtils.reader(bctx, inMem.input(), true)); } } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java index 68d3501764b2e..0d6e9af90f579 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java @@ -43,13 +43,13 @@ import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.IgniteKernal; import org.apache.ignite.internal.MarshallerContextImpl; +import org.apache.ignite.internal.binary.BinaryContext; import org.apache.ignite.internal.binary.BinaryFieldMetadata; import org.apache.ignite.internal.binary.BinaryMarshaller; import org.apache.ignite.internal.binary.BinaryMetadata; import org.apache.ignite.internal.binary.BinaryReaderEx; import org.apache.ignite.internal.binary.BinaryUtils; import org.apache.ignite.internal.binary.BinaryWriterEx; -import org.apache.ignite.internal.binary.GridBinaryMarshaller; import org.apache.ignite.internal.binary.streams.BinaryInputStream; import org.apache.ignite.internal.marshaller.ClassLoaderUtils; import org.apache.ignite.internal.processors.cache.CacheObject; @@ -878,12 +878,12 @@ public static Object readInvocationResult(PlatformContext ctx, BinaryReaderEx re * * @return Marshaller. */ - public static GridBinaryMarshaller marshaller() { + public static BinaryContext binaryContext() { BinaryMarshaller marsh = new BinaryMarshaller(); marsh.setContext(new MarshallerContextImpl(null)); - return new GridBinaryMarshaller(U.binaryContext(BinaryUtils.noopMetadataHandler(), marsh)); + return U.binaryContext(BinaryUtils.noopMetadataHandler(), marsh); } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 40779934a03ad..f0c4b094aa9de 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -124,7 +124,6 @@ import java.util.zip.Deflater; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import javax.management.DynamicMBean; import javax.management.JMException; @@ -6317,32 +6316,6 @@ public static T unmarshal(Marshaller marsh, InputStream in, @Nullable ClassL } } - /** - * @param marsh Marshaller. - * @param zipBytes Zip-compressed bytes. - * @param clsLdr Class loader to use. - * @return Unmarshalled object. - * @throws IgniteCheckedException - */ - public static T unmarshalZip(Marshaller marsh, byte[] zipBytes, @Nullable ClassLoader clsLdr) throws IgniteCheckedException { - assert marsh != null; - assert zipBytes != null; - - try { - ZipInputStream in = new ZipInputStream(new ByteArrayInputStream(zipBytes)); - - in.getNextEntry(); - - return marsh.unmarshal(in, clsLdr); - } - catch (IgniteCheckedException e) { - throw e; - } - catch (Exception e) { - throw new IgniteCheckedException(e); - } - } - /** * Unmarshals object from the input stream using given class loader. * This method should not close given input stream. diff --git a/modules/core/src/main/java/org/apache/ignite/spi/checkpoint/sharedfs/SharedFsCheckpointSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/checkpoint/sharedfs/SharedFsCheckpointSpi.java index eb7143f3e0aa8..3a945e72a9219 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/checkpoint/sharedfs/SharedFsCheckpointSpi.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/checkpoint/sharedfs/SharedFsCheckpointSpi.java @@ -35,7 +35,7 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.SB; import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.marshaller.jdk.JdkMarshaller; import org.apache.ignite.resources.IgniteInstanceResource; import org.apache.ignite.resources.LoggerResource; import org.apache.ignite.spi.IgniteSpiAdapter; @@ -171,7 +171,7 @@ public class SharedFsCheckpointSpi extends IgniteSpiAdapter implements Checkpoin private CheckpointListener lsnr; /** Marshaller. */ - private Marshaller marsh; + private JdkMarshaller marsh; /** * Initializes default directory paths. diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java index 32c4cbc9b51d6..30da46e0c1694 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java @@ -3260,13 +3260,13 @@ private void testReadDetachObjectProperly(Object obj, IgniteThrowableConsumer unmarshalMetrics = U.unmarshalZip(marshaller, zipMarshal, null); + HashMap unmarshalMetrics = unmarshalZip(marshaller, zipMarshal); assertTrue(isMetricsEquals(metrics.get(1), unmarshalMetrics.get(1))); @@ -90,4 +93,29 @@ private OptimizedMarshaller marshaller() { return marsh; } + + /** + * @param marsh Marshaller. + * @param zipBytes Zip-compressed bytes. + * @return Unmarshalled object. + * @throws IgniteCheckedException + */ + private static T unmarshalZip(Marshaller marsh, byte[] zipBytes) throws IgniteCheckedException { + assert marsh != null; + assert zipBytes != null; + + try { + ZipInputStream in = new ZipInputStream(new ByteArrayInputStream(zipBytes)); + + in.getNextEntry(); + + return marsh.unmarshal(in, null); + } + catch (IgniteCheckedException e) { + throw e; + } + catch (Exception e) { + throw new IgniteCheckedException(e); + } + } } diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java index 38ee2eb4d9df0..3a66112f7d96a 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java @@ -414,10 +414,8 @@ private GridQueryFieldsResult executeSelectLocal( // Convert parameters into BinaryObjects. BinaryMarshaller m = ctx.marshaller(); byte[] paramsBytes = U.marshal(m, qryParams.arguments()); - final ClassLoader ldr = U.resolveClassLoader(ctx.config()); - Object[] params = BinaryUtils.rawArrayFromBinary(m.binaryMarshaller() - .unmarshal(paramsBytes, ldr)); + Object[] params = BinaryUtils.rawArrayFromBinary(m.binaryMarshaller().unmarshal(paramsBytes, null)); H2Utils.bindParameters(stmt, F.asList(params)); diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlRequest.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlRequest.java index 725bdaf6ecc21..7d165a200775b 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlRequest.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlRequest.java @@ -354,10 +354,8 @@ public GridH2DmlRequest queryInitiatorId(String qryInitiatorId) { assert paramsBytes != null; - final ClassLoader ldr = U.resolveClassLoader(ctx.config()); - // To avoid deserializing of enum types. - params = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(paramsBytes, ldr)); + params = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(paramsBytes, null)); } diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlResponse.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlResponse.java index 128ba7cfe4d8c..462551216df0b 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlResponse.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlResponse.java @@ -125,10 +125,8 @@ public String error() { if (errKeys != null || errKeysBytes == null) return; - final ClassLoader ldr = U.resolveClassLoader(ctx.config()); - // To avoid deserializing of enum types. - errKeys = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(errKeysBytes, ldr)); + errKeys = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(errKeysBytes, null)); } /** {@inheritDoc} */ diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java index 3c97585f609d1..76df9dd0066c2 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java @@ -543,10 +543,8 @@ public static Boolean isDataPageScanEnabled(int flags) { @Override public void unmarshall(GridKernalContext ctx) { assert paramsBytes != null; - final ClassLoader ldr = U.resolveClassLoader(ctx.config()); - // To avoid deserializing of enum types. - params = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(paramsBytes, ldr)); + params = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(paramsBytes, null)); } diff --git a/modules/json/src/main/java/org/apache/ignite/internal/binary/BinaryArraySerializer.java b/modules/json/src/main/java/org/apache/ignite/internal/binary/BinaryArraySerializer.java index 114e8aab4a6ac..f06c99e3dfb53 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/binary/BinaryArraySerializer.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/binary/BinaryArraySerializer.java @@ -23,11 +23,11 @@ import com.fasterxml.jackson.databind.SerializerProvider; /** - * Custom serializer for {@link BinaryArray}. + * Custom serializer for binary arrays. */ -class BinaryArraySerializer extends JsonSerializer { +class BinaryArraySerializer extends JsonSerializer { /** {@inheritDoc} */ - @Override public void serialize(BinaryArray val, JsonGenerator gen, SerializerProvider serializers) throws IOException { + @Override public void serialize(BinaryObjectEx val, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeStartArray(); for (Object o : val.array()) diff --git a/modules/json/src/main/java/org/apache/ignite/internal/binary/BinarySerializers.java b/modules/json/src/main/java/org/apache/ignite/internal/binary/BinarySerializers.java index 0ebbd14c88e81..701d9270e8d4c 100644 --- a/modules/json/src/main/java/org/apache/ignite/internal/binary/BinarySerializers.java +++ b/modules/json/src/main/java/org/apache/ignite/internal/binary/BinarySerializers.java @@ -26,6 +26,6 @@ public class BinarySerializers { /** Adds binary serializers to module. */ public static void init(SimpleModule module) { module.addSerializer((Class)BinaryUtils.binariesFactory.binaryObjectImplClass(), new BinaryObjectImplSerializer()); - module.addSerializer(BinaryArray.class, new BinaryArraySerializer()); + module.addSerializer((Class)BinaryUtils.binariesFactory.binaryArrayClass(), new BinaryArraySerializer()); } } diff --git a/modules/thin-client/impl/src/main/java/org/apache/ignite/internal/client/thin/ClientUtils.java b/modules/thin-client/impl/src/main/java/org/apache/ignite/internal/client/thin/ClientUtils.java index c79247b5d2778..439c4ff09aa3e 100644 --- a/modules/thin-client/impl/src/main/java/org/apache/ignite/internal/client/thin/ClientUtils.java +++ b/modules/thin-client/impl/src/main/java/org/apache/ignite/internal/client/thin/ClientUtils.java @@ -624,7 +624,7 @@ BinaryReaderEx createBinaryReader(BinaryInputStream in) { * @param in Input stream. */ static BinaryReaderEx createBinaryReader(@Nullable BinaryContext binaryCtx, BinaryInputStream in) { - return BinaryUtils.reader(binaryCtx, in, null, true, true); + return BinaryUtils.reader(binaryCtx, in); } /** Read Ignite binary object from input stream. */