Return-Path: X-Original-To: apmail-ignite-commits-archive@minotaur.apache.org Delivered-To: apmail-ignite-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0CD86185D6 for ; Mon, 30 Nov 2015 09:25:55 +0000 (UTC) Received: (qmail 7030 invoked by uid 500); 30 Nov 2015 09:25:54 -0000 Delivered-To: apmail-ignite-commits-archive@ignite.apache.org Received: (qmail 6851 invoked by uid 500); 30 Nov 2015 09:25:54 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 6377 invoked by uid 99); 30 Nov 2015 09:25:54 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 Nov 2015 09:25:54 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 606E5E002C; Mon, 30 Nov 2015 09:25:54 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sboikov@apache.org To: commits@ignite.apache.org Date: Mon, 30 Nov 2015 09:26:08 -0000 Message-Id: In-Reply-To: <6c7165248491445d8c065305807d0887@git.apache.org> References: <6c7165248491445d8c065305807d0887@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [15/49] ignite git commit: IGNITE-1956: Added binary enums support. IGNITE-1956: Added binary enums support. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/663e78dc Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/663e78dc Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/663e78dc Branch: refs/heads/ignite-1537 Commit: 663e78dc65dcf6d8369f13ef8bf6c4aeacb6299d Parents: 30c9b8d Author: vozerov-gridgain Authored: Fri Nov 27 12:37:27 2015 +0300 Committer: vozerov-gridgain Committed: Fri Nov 27 12:37:27 2015 +0300 ---------------------------------------------------------------------- .../java/org/apache/ignite/IgniteBinary.java | 9 + .../org/apache/ignite/binary/BinaryObject.java | 8 + .../org/apache/ignite/binary/BinaryType.java | 7 + .../ignite/binary/BinaryTypeConfiguration.java | 21 + .../communication/GridIoMessageFactory.java | 8 +- .../internal/portable/BinaryEnumObjectImpl.java | 311 +++++++++++++ .../internal/portable/BinaryMetadata.java | 16 +- .../internal/portable/BinaryObjectExImpl.java | 5 + .../internal/portable/BinaryObjectImpl.java | 3 - .../internal/portable/BinaryTypeImpl.java | 9 +- .../internal/portable/BinaryWriteMode.java | 3 + .../internal/portable/BinaryWriterExImpl.java | 19 + .../portable/PortableClassDescriptor.java | 23 +- .../internal/portable/PortableContext.java | 39 +- .../ignite/internal/portable/PortableUtils.java | 147 +++++- .../builder/BinaryObjectBuilderImpl.java | 2 +- .../builder/PortableBuilderSerializer.java | 10 +- .../internal/processors/cache/CacheObject.java | 3 + .../processors/cache/CacheObjectContext.java | 19 + .../portable/CacheObjectBinaryProcessor.java | 11 +- .../CacheObjectBinaryProcessorImpl.java | 18 +- .../cache/portable/IgniteBinaryImpl.java | 12 + .../processors/cacheobject/NoOpBinary.java | 5 + .../platform/PlatformContextImpl.java | 53 ++- .../transactions/PlatformTransactions.java | 4 +- .../platform/utils/PlatformUtils.java | 1 + .../PlatformDotNetBinaryTypeConfiguration.java | 23 + .../internal/portable/BinaryEnumsSelfTest.java | 446 +++++++++++++++++++ .../portable/BinaryMarshallerSelfTest.java | 37 +- .../platform/PlatformComputeEchoTask.java | 4 +- .../IgnitePortableObjectsTestSuite.java | 2 + .../impl/binary/binary_type_updater_impl.cpp | 4 +- .../Binary/BinaryBuilderSelfTest.cs | 97 ++-- .../Binary/BinarySelfTest.cs | 48 +- .../Cache/CacheAbstractTest.cs | 17 +- .../Compute/ComputeApiTest.cs | 6 + .../Config/Compute/compute-grid1.xml | 3 +- .../Config/native-client-test-cache-store.xml | 1 + .../Services/ServiceProxyTest.cs | 22 +- .../Apache.Ignite.Core.csproj | 5 +- .../Binary/BinaryTypeConfiguration.cs | 16 +- .../dotnet/Apache.Ignite.Core/Binary/IBinary.cs | 136 ++++++ .../Apache.Ignite.Core/Binary/IBinaryObject.cs | 23 +- .../Apache.Ignite.Core/Binary/IBinaryType.cs | 13 + .../Apache.Ignite.Core/Binary/IIgniteBinary.cs | 120 ----- .../dotnet/Apache.Ignite.Core/IIgnite.cs | 6 +- .../Apache.Ignite.Core/Impl/Binary/Binary.cs | 216 +++++++++ .../Impl/Binary/BinaryEnum.cs | 134 ++++++ .../Impl/Binary/BinaryFullTypeDescriptor.cs | 14 +- .../Impl/Binary/BinaryObject.cs | 29 ++ .../Impl/Binary/BinaryObjectBuilder.cs | 44 +- .../Impl/Binary/BinaryReader.cs | 51 ++- .../Binary/BinarySurrogateTypeDescriptor.cs | 6 + .../Impl/Binary/BinarySystemHandlers.cs | 34 +- .../Impl/Binary/BinaryUtils.cs | 96 ++-- .../Impl/Binary/BinaryWriter.cs | 104 +++-- .../Impl/Binary/IBinaryTypeDescriptor.cs | 50 +-- .../Impl/Binary/IgniteBinary.cs | 192 -------- .../Impl/Binary/Marshaller.cs | 88 ++-- .../Impl/Binary/Metadata/BinaryType.cs | 184 ++++---- .../Impl/Binary/Metadata/BinaryTypeHolder.cs | 34 +- .../Binary/Structure/BinaryStructureTracker.cs | 2 +- .../dotnet/Apache.Ignite.Core/Impl/Ignite.cs | 11 +- .../Apache.Ignite.Core/Impl/IgniteProxy.cs | 2 +- .../Apache.Ignite.Core/Impl/PlatformTarget.cs | 11 +- .../Impl/Transactions/TransactionsImpl.cs | 4 +- .../examples/Config/example-cache-query.xml | 9 +- .../dotnet/examples/Config/example-cache.xml | 9 +- 68 files changed, 2354 insertions(+), 765 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java b/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java index 30db9d9..a1c656b 100644 --- a/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java +++ b/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java @@ -351,4 +351,13 @@ public interface IgniteBinary { * @throws org.apache.ignite.binary.BinaryObjectException In case of error. */ public Collection types() throws BinaryObjectException; + + /** + * Create enum object. + * + * @param typeName Type name. + * @param ord Ordinal. + * @return Enum object. + */ + public BinaryObject buildEnum(String typeName, int ord); } http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java index 249daab..f4afd8d 100644 --- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java +++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java @@ -139,4 +139,12 @@ public interface BinaryObject extends Serializable, Cloneable { * @return Copy of this binary object. */ public BinaryObject clone() throws CloneNotSupportedException; + + /** + * Get ordinal for this enum object. Use {@link BinaryType#isEnum()} to check if object is of enum type. + * + * @return Ordinal. + * @throws BinaryObjectException If object is not enum. + */ + public int enumOrdinal() throws BinaryObjectException; } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java index debd7e5..f184a8c 100644 --- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java +++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java @@ -72,4 +72,11 @@ public interface BinaryType { * @return Affinity key field name. */ public String affinityKeyFieldName(); + + /** + * Check whether type represents enum or not. + * + * @return {@code True} if type is enum. + */ + public boolean isEnum(); } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java index d216866..a694eaf 100644 --- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java +++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java @@ -38,6 +38,9 @@ public class BinaryTypeConfiguration { /** Serializer. */ private BinarySerializer serializer; + /** Enum flag. */ + private boolean isEnum; + /** */ public BinaryTypeConfiguration() { @@ -105,6 +108,24 @@ public class BinaryTypeConfiguration { this.serializer = serializer; } + /** + * Gets whether this is enum type. + * + * @return {@code True} if enum. + */ + public boolean isEnum() { + return isEnum; + } + + /** + * Sets whether this is enum type. + * + * @param isEnum {@code True} if enum. + */ + public void setEnum(boolean isEnum) { + this.isEnum = isEnum; + } + /** {@inheritDoc} */ @Override public String toString() { return S.toString(BinaryTypeConfiguration.class, this, super.toString()); http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java index 02bd5ec..c9b8e27 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java @@ -31,6 +31,7 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean; import org.apache.ignite.internal.managers.deployment.GridDeploymentRequest; import org.apache.ignite.internal.managers.deployment.GridDeploymentResponse; import org.apache.ignite.internal.managers.eventstorage.GridEventStorageMessage; +import org.apache.ignite.internal.portable.BinaryEnumObjectImpl; import org.apache.ignite.internal.portable.BinaryObjectImpl; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryInfoCollection; @@ -714,7 +715,12 @@ public class GridIoMessageFactory implements MessageFactory { break; - // [-3..118] - this + case 119: + msg = new BinaryEnumObjectImpl(); + + break; + + // [-3..119] - this // [120..123] - DR // [-4..-22] - SQL default: http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java new file mode 100644 index 0000000..e13c076 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java @@ -0,0 +1,311 @@ +/* + * 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.portable; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.binary.BinaryType; +import org.apache.ignite.internal.GridDirectTransient; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.processors.cache.portable.CacheObjectBinaryProcessorImpl; +import org.apache.ignite.internal.util.typedef.internal.SB; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.jetbrains.annotations.Nullable; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.nio.ByteBuffer; + +/** + * Binary enum object. + */ +public class BinaryEnumObjectImpl implements BinaryObjectEx, Externalizable, CacheObject { + /** */ + private static final long serialVersionUID = 0L; + + /** Context. */ + @GridDirectTransient + private PortableContext ctx; + + /** Type ID. */ + private int typeId; + + /** Raw data. */ + private String clsName; + + /** Ordinal. */ + private int ord; + + /** + * {@link Externalizable} support. + */ + public BinaryEnumObjectImpl() { + // No-op. + } + + /** + * Constructor. + * + * @param ctx Context. + * @param typeId Type ID. + * @param clsName Class name. + * @param ord Ordinal. + */ + public BinaryEnumObjectImpl(PortableContext ctx, int typeId, @Nullable String clsName, int ord) { + assert ctx != null; + + this.ctx = ctx; + this.typeId = typeId; + this.clsName = clsName; + this.ord = ord; + } + + /** + * @return Class name. + */ + @Nullable public String className() { + return clsName; + } + + /** {@inheritDoc} */ + @Override public int typeId() { + return typeId; + } + + /** {@inheritDoc} */ + @Override public BinaryType type() throws BinaryObjectException { + return ctx.metadata(typeId()); + } + + /** {@inheritDoc} */ + @Override public F field(String fieldName) throws BinaryObjectException { + return null; + } + + /** {@inheritDoc} */ + @Override public boolean hasField(String fieldName) { + return false; + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public T deserialize() throws BinaryObjectException { + Class cls = PortableUtils.resolveClass(ctx, typeId, clsName, null); + + return BinaryEnumCache.get(cls, ord); + } + + /** {@inheritDoc} */ + @Override public BinaryObject clone() throws CloneNotSupportedException { + return (BinaryObject)super.clone(); + } + + /** {@inheritDoc} */ + @Override public int enumOrdinal() throws BinaryObjectException { + return ord; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return 31 * typeId + ord; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object obj) { + if (obj != null && (obj instanceof BinaryEnumObjectImpl)) { + BinaryEnumObjectImpl other = (BinaryEnumObjectImpl)obj; + + return typeId == other.typeId && ord == other.ord; + } + + return false; + } + + /** {@inheritDoc} */ + @Override public String toString() { + // 1. Try deserializing the object. + try { + Object val = deserialize(); + + return new SB().a(val).toString(); + } + catch (Exception e) { + // No-op. + } + + // 2. Try getting meta. + BinaryType type; + + try { + type = type(); + } + catch (Exception e) { + type = null; + } + + if (type != null) { + return type.typeName() + "[ordinal=" + ord + ']'; + } + else { + if (typeId == GridPortableMarshaller.UNREGISTERED_TYPE_ID) + return "BinaryEnum[clsName=" + clsName + ", ordinal=" + ord + ']'; + else + return "BinaryEnum[typeId=" + typeId + ", ordinal=" + ord + ']'; + } + } + + /** {@inheritDoc} */ + @Override public void writeExternal(ObjectOutput out) throws IOException { + out.writeObject(ctx); + + out.writeInt(typeId); + out.writeObject(clsName); + out.writeInt(ord); + } + + /** {@inheritDoc} */ + @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + ctx = (PortableContext)in.readObject(); + + typeId = in.readInt(); + clsName = (String)in.readObject(); + ord = in.readInt(); + } + + /** {@inheritDoc} */ + @Nullable @Override public T value(CacheObjectContext ctx, boolean cpy) { + return deserialize(); + } + + /** {@inheritDoc} */ + @Override public byte[] valueBytes(CacheObjectContext cacheCtx) throws IgniteCheckedException { + return ctx.marshaller().marshal(this); + } + + /** {@inheritDoc} */ + @Override public byte cacheObjectType() { + return TYPE_BINARY; + } + + /** {@inheritDoc} */ + @Override public boolean isPlatformType() { + return false; + } + + /** {@inheritDoc} */ + @Override public CacheObject prepareForCache(CacheObjectContext ctx) { + return this; + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(CacheObjectContext ctx, ClassLoader ldr) throws IgniteCheckedException { + this.ctx = ((CacheObjectBinaryProcessorImpl)ctx.processor()).portableContext(); + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(CacheObjectContext ctx) throws IgniteCheckedException { + // No-op. + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 119; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 3; + } + + /** {@inheritDoc} */ + @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) { + writer.setBuffer(buf); + + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(directType(), fieldsCount())) + return false; + + writer.onHeaderWritten(); + } + + switch (writer.state()) { + case 0: + if (!writer.writeString("clsName", clsName)) + return false; + + writer.incrementState(); + + case 1: + if (!writer.writeInt("ord", ord)) + return false; + + writer.incrementState(); + + case 2: + if (!writer.writeInt("typeId", typeId)) + return false; + + writer.incrementState(); + + } + + return true; + } + + /** {@inheritDoc} */ + @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) { + reader.setBuffer(buf); + + if (!reader.beforeMessageRead()) + return false; + + switch (reader.state()) { + case 0: + clsName = reader.readString("clsName"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 1: + ord = reader.readInt("ord"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 2: + typeId = reader.readInt("typeId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(BinaryEnumObjectImpl.class); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryMetadata.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryMetadata.java index a464d6e..8ba2e23 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryMetadata.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryMetadata.java @@ -52,6 +52,9 @@ public class BinaryMetadata implements Externalizable { /** Schemas associated with type. */ private Collection schemas; + /** Whether this is enum type. */ + private boolean isEnum; + /** * For {@link Externalizable}. */ @@ -67,9 +70,10 @@ public class BinaryMetadata implements Externalizable { * @param fields Fields map. * @param affKeyFieldName Affinity key field name. * @param schemas Schemas. + * @param isEnum Enum flag. */ public BinaryMetadata(int typeId, String typeName, @Nullable Map fields, - @Nullable String affKeyFieldName, @Nullable Collection schemas) { + @Nullable String affKeyFieldName, @Nullable Collection schemas, boolean isEnum) { assert typeName != null; this.typeId = typeId; @@ -77,6 +81,7 @@ public class BinaryMetadata implements Externalizable { this.fields = fields; this.affKeyFieldName = affKeyFieldName; this.schemas = schemas; + this.isEnum = isEnum; } /** @@ -132,6 +137,13 @@ public class BinaryMetadata implements Externalizable { } /** + * @return {@code True} if this is enum type. + */ + public boolean isEnum() { + return isEnum; + } + + /** * Wrap metadata into binary type. * * @param ctx Portable context. @@ -148,6 +160,7 @@ public class BinaryMetadata implements Externalizable { U.writeMap(out, fields); U.writeString(out, affKeyFieldName); U.writeCollection(out, schemas); + out.writeBoolean(isEnum); } /** {@inheritDoc} */ @@ -157,6 +170,7 @@ public class BinaryMetadata implements Externalizable { fields = U.readMap(in); affKeyFieldName = U.readString(in); schemas = U.readCollection(in); + isEnum = in.readBoolean(); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectExImpl.java index 7497bd3..2ea71ec 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectExImpl.java @@ -66,6 +66,11 @@ public abstract class BinaryObjectExImpl implements BinaryObjectEx { */ @Nullable public abstract F field(int fieldId) throws BinaryObjectException; + /** {@inheritDoc} */ + @Override public int enumOrdinal() throws BinaryObjectException { + throw new BinaryObjectException("Object is not enum."); + } + /** * Get field by offset. * http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java index f683ed9..87a03dc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java @@ -66,9 +66,6 @@ import static org.apache.ignite.internal.portable.GridPortableMarshaller.UUID; @IgniteCodeGeneratingFail // Fields arr and start should not be generated by MessageCodeGenerator. public final class BinaryObjectImpl extends BinaryObjectExImpl implements Externalizable, KeyCacheObject { /** */ - public static final byte TYPE_BINARY = 100; - - /** */ private static final long serialVersionUID = 0L; /** */ http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryTypeImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryTypeImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryTypeImpl.java index c3fee7e..9512cdb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryTypeImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryTypeImpl.java @@ -72,9 +72,12 @@ public class BinaryTypeImpl implements BinaryType { return meta.affinityKeyFieldName(); } - /** - * @return Portable context. - */ + /** {@inheritDoc} */ + @Override public boolean isEnum() { + return meta.isEnum(); + } + + /** {@inheritDoc} */ public PortableContext context() { return ctx; } http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriteMode.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriteMode.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriteMode.java index a26b741..bd73ad0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriteMode.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriteMode.java @@ -141,6 +141,9 @@ public enum BinaryWriteMode { /** */ ENUM(GridPortableMarshaller.ENUM), + /** Portable enum. */ + PORTABLE_ENUM(GridPortableMarshaller.ENUM), + /** */ ENUM_ARR(GridPortableMarshaller.ENUM_ARR), http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java index ec47f57..9d1d037 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java @@ -803,6 +803,25 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje } /** + * @param val Value. + */ + void doWritePortableEnum(BinaryEnumObjectImpl val) { + assert val != null; + + int typeId = val.typeId(); + + out.unsafeEnsure(1 + 4); + + out.unsafeWriteByte(ENUM); + out.unsafeWriteInt(typeId); + + if (typeId == UNREGISTERED_TYPE_ID) + doWriteString(val.className()); + + out.writeInt(val.enumOrdinal()); + } + + /** * @param val Array. */ void doWriteEnumArray(@Nullable Object[] val) { http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java index fa6ea3a..dba15f5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java @@ -161,8 +161,12 @@ public class PortableClassDescriptor { if (excluded) mode = BinaryWriteMode.EXCLUSION; - else - mode = serializer != null ? BinaryWriteMode.PORTABLE : PortableUtils.mode(cls); + else { + if (cls == BinaryEnumObjectImpl.class) + mode = BinaryWriteMode.PORTABLE_ENUM; + else + mode = serializer != null ? BinaryWriteMode.PORTABLE : PortableUtils.mode(cls); + } switch (mode) { case P_BYTE: @@ -205,6 +209,7 @@ public class PortableClassDescriptor { case MAP_ENTRY: case PORTABLE_OBJ: case ENUM: + case PORTABLE_ENUM: case ENUM_ARR: case CLASS: case EXCLUSION: @@ -286,6 +291,13 @@ public class PortableClassDescriptor { } /** + * @return {@code True} if enum. + */ + boolean isEnum() { + return mode == BinaryWriteMode.ENUM; + } + + /** * @return Described class. */ Class describedClass() { @@ -534,6 +546,11 @@ public class PortableClassDescriptor { break; + case PORTABLE_ENUM: + writer.doWritePortableEnum((BinaryEnumObjectImpl)obj); + + break; + case ENUM_ARR: writer.doWriteEnumArray((Object[])obj); @@ -576,7 +593,7 @@ public class PortableClassDescriptor { PortableSchema newSchema = collector.schema(); BinaryMetadata meta = new BinaryMetadata(typeId, typeName, collector.meta(), - affKeyFieldName, Collections.singleton(newSchema)); + affKeyFieldName, Collections.singleton(newSchema), false); ctx.updateMetadata(typeId, meta); http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java index ab96ed1..ae0d940 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java @@ -117,6 +117,9 @@ public class PortableContext implements Externalizable { /** */ private BinaryMetadataHandler metaHnd; + /** Actual marshaller. */ + private BinaryMarshaller marsh; + /** */ private MarshallerContext marshCtx; @@ -222,6 +225,13 @@ public class PortableContext implements Externalizable { } /** + * @return Marshaller. + */ + public BinaryMarshaller marshaller() { + return marsh; + } + + /** * @param marsh Portable marshaller. * @throws org.apache.ignite.binary.BinaryObjectException In case of error. */ @@ -229,6 +239,8 @@ public class PortableContext implements Externalizable { if (marsh == null) return; + this.marsh = marsh; + marshCtx = marsh.getContext(); BinaryConfiguration binaryCfg = cfg.getBinaryConfiguration(); @@ -293,16 +305,16 @@ public class PortableContext implements Externalizable { for (String clsName0 : classesInPackage(pkgName)) descs.add(clsName0, idMapper, serializer, affFields.get(clsName0), - true); + typeCfg.isEnum(), true); } else descs.add(clsName, idMapper, serializer, affFields.get(clsName), - false); + typeCfg.isEnum(), false); } } for (TypeDescriptor desc : descs.descriptors()) { - registerUserType(desc.clsName, desc.idMapper, desc.serializer, desc.affKeyFieldName); + registerUserType(desc.clsName, desc.idMapper, desc.serializer, desc.affKeyFieldName, desc.isEnum); } BinaryInternalIdMapper dfltMapper = BinaryInternalIdMapper.create(globalIdMapper); @@ -535,7 +547,8 @@ public class PortableContext implements Externalizable { Collection schemas = desc.schema() != null ? Collections.singleton(desc.schema()) : null; - metaHnd.addMeta(typeId, new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, schemas).wrap(this)); + metaHnd.addMeta(typeId, + new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, schemas, desc.isEnum()).wrap(this)); // perform put() instead of putIfAbsent() because "registered" flag might have been changed or class loader // might have reloaded described class. @@ -628,7 +641,7 @@ public class PortableContext implements Externalizable { * @return Affinity field name or {@code null} if field name was not found. */ private String affinityFieldName(Class cls) { - for (; cls != Object.class; cls = cls.getSuperclass()) { + for (; cls != Object.class && cls != null; cls = cls.getSuperclass()) { for (Field f : cls.getDeclaredFields()) { if (f.getAnnotation(AffinityKeyMapped.class) != null) return f.getName(); @@ -701,13 +714,15 @@ public class PortableContext implements Externalizable { * @param idMapper ID mapper. * @param serializer Serializer. * @param affKeyFieldName Affinity key field name. + * @param isEnum If enum. * @throws org.apache.ignite.binary.BinaryObjectException In case of error. */ @SuppressWarnings("ErrorNotRethrown") public void registerUserType(String clsName, BinaryIdMapper idMapper, @Nullable BinarySerializer serializer, - @Nullable String affKeyFieldName) + @Nullable String affKeyFieldName, + boolean isEnum) throws BinaryObjectException { assert idMapper != null; @@ -765,7 +780,7 @@ public class PortableContext implements Externalizable { descByCls.put(cls, desc); } - metaHnd.addMeta(id, new BinaryMetadata(id, typeName, fieldsMeta, affKeyFieldName, schemas).wrap(this)); + metaHnd.addMeta(id, new BinaryMetadata(id, typeName, fieldsMeta, affKeyFieldName, schemas, isEnum).wrap(this)); } /** @@ -940,6 +955,7 @@ public class PortableContext implements Externalizable { * @param idMapper ID mapper. * @param serializer Serializer. * @param affKeyFieldName Affinity key field name. + * @param isEnum Enum flag. * @param canOverride Whether this descriptor can be override. * @throws org.apache.ignite.binary.BinaryObjectException If failed. */ @@ -947,12 +963,14 @@ public class PortableContext implements Externalizable { BinaryIdMapper idMapper, BinarySerializer serializer, String affKeyFieldName, + boolean isEnum, boolean canOverride) throws BinaryObjectException { TypeDescriptor desc = new TypeDescriptor(clsName, idMapper, serializer, affKeyFieldName, + isEnum, canOverride); TypeDescriptor oldDesc = descs.get(clsName); @@ -989,6 +1007,9 @@ public class PortableContext implements Externalizable { /** Affinity key field name. */ private String affKeyFieldName; + /** Enum flag. */ + private boolean isEnum; + /** Whether this descriptor can be override. */ private boolean canOverride; @@ -999,14 +1020,16 @@ public class PortableContext implements Externalizable { * @param idMapper ID mapper. * @param serializer Serializer. * @param affKeyFieldName Affinity key field name. + * @param isEnum Enum type. * @param canOverride Whether this descriptor can be override. */ private TypeDescriptor(String clsName, BinaryIdMapper idMapper, BinarySerializer serializer, - String affKeyFieldName, boolean canOverride) { + String affKeyFieldName, boolean isEnum, boolean canOverride) { this.clsName = clsName; this.idMapper = idMapper; this.serializer = serializer; this.affKeyFieldName = affKeyFieldName; + this.isEnum = isEnum; this.canOverride = canOverride; } http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java index a83405d..e543c41 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java @@ -877,6 +877,16 @@ public class PortableUtils { ); } + // Check enum flag. + if (oldMeta.isEnum() != newMeta.isEnum()) { + if (oldMeta.isEnum()) + throw new BinaryObjectException("Binary type already registered as enum: " + + newMeta.typeName()); + else + throw new BinaryObjectException("Binary type already registered as non-enum: " + + newMeta.typeName()); + } + // Check and merge fields. boolean changed = false; @@ -908,7 +918,7 @@ public class PortableUtils { // Return either old meta if no changes detected, or new merged meta. return changed ? new BinaryMetadata(oldMeta.typeId(), oldMeta.typeName(), mergedFields, - oldMeta.affinityKeyFieldName(), mergedSchemas) : oldMeta; + oldMeta.affinityKeyFieldName(), mergedSchemas, oldMeta.isEnum()) : oldMeta; } } @@ -1314,6 +1324,37 @@ public class PortableUtils { } /** + * Read plain type. + * + * @param in Input stream. + * @return Plain type. + */ + private static EnumType doReadEnumType(PortableInputStream in) { + int typeId = in.readInt(); + + if (typeId != UNREGISTERED_TYPE_ID) + return new EnumType(typeId, null); + else { + String clsName = doReadClassName(in); + + return new EnumType(UNREGISTERED_TYPE_ID, clsName); + } + } + + /** + * @param in Input stream. + * @return Class name. + */ + private static String doReadClassName(PortableInputStream in) { + byte flag = in.readByte(); + + if (flag != STRING) + throw new BinaryObjectException("Failed to read class name [position=" + (in.position() - 1) + ']'); + + return doReadString(in); + } + + /** * @param typeId Type id. * @return Value. */ @@ -1327,13 +1368,41 @@ public class PortableUtils { if (typeId != UNREGISTERED_TYPE_ID) cls = ctx.descriptorForTypeId(true, typeId, ldr).describedClass(); else { - byte flag = in.readByte(); + String clsName = doReadClassName(in); + + try { + cls = U.forName(clsName, ldr); + } + catch (ClassNotFoundException e) { + throw new BinaryInvalidTypeException("Failed to load the class: " + clsName, e); + } - if (flag != STRING) - throw new BinaryObjectException("No class definition for typeId: " + typeId); + // forces registering of class by type id, at least locally + ctx.descriptorForClass(cls); + } + + return cls; + } + + /** + * Resolve the class. + * + * @param ctx Portable context. + * @param typeId Type ID. + * @param clsName Class name. + * @param ldr Class loaded. + * @return Resovled class. + */ + public static Class resolveClass(PortableContext ctx, int typeId, @Nullable String clsName, + @Nullable ClassLoader ldr) { + Class cls; - String clsName = doReadString(in); + if (typeId == OBJECT_TYPE_ID) + return Object.class; + if (typeId != UNREGISTERED_TYPE_ID) + cls = ctx.descriptorForTypeId(true, typeId, ldr).describedClass(); + else { try { cls = U.forName(clsName, ldr); } @@ -1349,6 +1418,43 @@ public class PortableUtils { } /** + * Read portable enum. + * + * @param in Input stream. + * @param ctx Portable context. + * @param type Plain type. + * @return Enum. + */ + private static BinaryEnumObjectImpl doReadPortableEnum(PortableInputStream in, PortableContext ctx, + EnumType type) { + return new BinaryEnumObjectImpl(ctx, type.typeId, type.clsName, in.readInt()); + } + + /** + * Read portable enum array. + * + * @param in Input stream. + * @param ctx Portable context. + * @return Enum array. + */ + private static Object[] doReadPortableEnumArray(PortableInputStream in, PortableContext ctx) { + int len = in.readInt(); + + Object[] arr = (Object[]) Array.newInstance(BinaryObject.class, len); + + for (int i = 0; i < len; i++) { + byte flag = in.readByte(); + + if (flag == NULL) + arr[i] = null; + else + arr[i] = doReadPortableEnum(in, ctx, doReadEnumType(in)); + } + + return arr; + } + + /** * Having target class in place we simply read ordinal and create final representation. * * @param cls Enum class. @@ -1589,10 +1695,12 @@ public class PortableUtils { return doReadPortableObject(in, ctx); case ENUM: - return doReadEnum(in, doReadClass(in, ctx, ldr)); + return doReadPortableEnum(in, ctx, doReadEnumType(in)); case ENUM_ARR: - return doReadEnumArray(in, ctx, ldr, doReadClass(in, ctx, ldr)); + doReadEnumType(in); // Simply skip this part as we do not need it. + + return doReadPortableEnumArray(in, ctx); case CLASS: return doReadClass(in, ctx, ldr); @@ -1843,4 +1951,29 @@ public class PortableUtils { public static int positionForHandle(PortableInputStream in) { return in.position() - 1; } + + /** + * 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 != UNREGISTERED_TYPE_ID && clsName == null || + typeId == UNREGISTERED_TYPE_ID && clsName != null; + + this.typeId = typeId; + this.clsName = clsName; + } + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java index d330c72..5c2c713 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java @@ -377,7 +377,7 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { PortableSchema curSchema = writer.currentSchema(); ctx.updateMetadata(typeId, new BinaryMetadata(typeId, typeName, fieldsMeta, - ctx.affinityKeyFieldName(typeId), Collections.singleton(curSchema))); + ctx.affinityKeyFieldName(typeId), Collections.singleton(curSchema), false)); schemaReg.addSchema(curSchema.schemaId(), curSchema); } http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderSerializer.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderSerializer.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderSerializer.java index ee7bd65..52f84c6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderSerializer.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderSerializer.java @@ -18,8 +18,10 @@ package org.apache.ignite.internal.portable.builder; import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.internal.portable.BinaryMetadata; import org.apache.ignite.internal.portable.GridPortableMarshaller; import org.apache.ignite.internal.portable.BinaryObjectExImpl; +import org.apache.ignite.internal.portable.PortableContext; import org.apache.ignite.internal.portable.PortableUtils; import org.apache.ignite.internal.portable.BinaryWriterExImpl; import org.apache.ignite.internal.util.*; @@ -97,8 +99,14 @@ class PortableBuilderSerializer { } if (val.getClass().isEnum()) { + String typeName = PortableContext.typeName(val.getClass().getName()); + int typeId = writer.context().typeId(typeName); + + BinaryMetadata meta = new BinaryMetadata(typeId, typeName, null, null, null, true); + writer.context().updateMetadata(typeId, meta); + writer.writeByte(GridPortableMarshaller.ENUM); - writer.writeInt(writer.context().typeId(val.getClass().getName())); + writer.writeInt(typeId); writer.writeInt(((Enum)val).ordinal()); return; http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObject.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObject.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObject.java index 81129bd..2385335 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObject.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObject.java @@ -31,6 +31,9 @@ public interface CacheObject extends Message { /** */ public static final byte TYPE_BYTE_ARR = 2; + /** */ + public static final byte TYPE_BINARY = 100; + /** * @param ctx Context. * @param cpy If {@code true} need to copy value. http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java index b4ac5f4..b99c99f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java @@ -176,6 +176,23 @@ import org.apache.ignite.internal.util.typedef.F; } /** + * Unwrap array of portables if needed. + * + * @param arr Array. + * @param keepPortable Keep portable flag. + * @param cpy Copy. + * @return Result. + */ + public Object[] unwrapPortablesInArrayIfNeeded(Object[] arr, boolean keepPortable, boolean cpy) { + Object[] res = new Object[arr.length]; + + for (int i = 0; i < arr.length; i++) + res[i] = unwrapPortable(arr[i], keepPortable, cpy); + + return res; + } + + /** * Unwraps map. * * @param map Map to unwrap. @@ -252,6 +269,8 @@ import org.apache.ignite.internal.util.typedef.F; return unwrapPortablesIfNeeded((Collection)o, keepPortable, cpy); else if (o instanceof Map) return unwrapPortablesIfNeeded((Map)o, keepPortable, cpy); + else if (o instanceof Object[]) + return unwrapPortablesInArrayIfNeeded((Object[])o, keepPortable, cpy); else if (o instanceof CacheObject) { CacheObject co = (CacheObject)o; http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessor.java index e4db77c..7ef4b91 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessor.java @@ -57,10 +57,11 @@ public interface CacheObjectBinaryProcessor extends IgniteCacheObjectProcessor { * @param typeName Type name. * @param affKeyFieldName Affinity key field name. * @param fieldTypeIds Fields map. + * @param isEnum Enum flag. * @throws IgniteException In case of error. */ public void updateMetadata(int typeId, String typeName, @Nullable String affKeyFieldName, - Map fieldTypeIds) throws IgniteException; + Map fieldTypeIds, boolean isEnum) throws IgniteException; /** * @param typeId Type ID. @@ -83,6 +84,14 @@ public interface CacheObjectBinaryProcessor extends IgniteCacheObjectProcessor { public Collection metadata() throws IgniteException; /** + * @param typeName Type name. + * @param ord ordinal. + * @return Enum object. + * @throws IgniteException If failed. + */ + public BinaryObject buildEnum(String typeName, int ord) throws IgniteException; + + /** * @return Portables interface. * @throws IgniteException If failed. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessorImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessorImpl.java index eef39be..5b70f2a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessorImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessorImpl.java @@ -30,6 +30,7 @@ import org.apache.ignite.cluster.ClusterTopologyException; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException; +import org.apache.ignite.internal.portable.BinaryEnumObjectImpl; import org.apache.ignite.internal.portable.BinaryMetadata; import org.apache.ignite.internal.portable.BinaryMetadataHandler; import org.apache.ignite.internal.portable.BinaryObjectEx; @@ -467,8 +468,10 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm /** {@inheritDoc} */ @Override public void updateMetadata(int typeId, String typeName, @Nullable String affKeyFieldName, - Map fieldTypeIds) throws BinaryObjectException { - portableCtx.updateMetadata(typeId, new BinaryMetadata(typeId, typeName, fieldTypeIds, affKeyFieldName, null)); + Map fieldTypeIds, boolean isEnum) throws BinaryObjectException { + BinaryMetadata meta = new BinaryMetadata(typeId, typeName, fieldTypeIds, affKeyFieldName, null, isEnum); + + portableCtx.updateMetadata(typeId, meta); } /** {@inheritDoc} */ @@ -555,6 +558,17 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm } /** {@inheritDoc} */ + @Override public BinaryObject buildEnum(String typeName, int ord) throws IgniteException { + typeName = PortableContext.typeName(typeName); + + int typeId = portableCtx.typeId(typeName); + + updateMetadata(typeId, typeName, null, null, true); + + return new BinaryEnumObjectImpl(portableCtx, typeId, null, ord); + } + + /** {@inheritDoc} */ @Override public IgniteBinary binary() throws IgniteException { return portables; } http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/IgniteBinaryImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/IgniteBinaryImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/IgniteBinaryImpl.java index 41aa68c..7008502 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/IgniteBinaryImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/IgniteBinaryImpl.java @@ -143,6 +143,18 @@ public class IgniteBinaryImpl implements IgniteBinary { } } + /** {@inheritDoc} */ + @Override public BinaryObject buildEnum(String typeName, int ord) { + guard(); + + try { + return proc.buildEnum(typeName, ord); + } + finally { + unguard(); + } + } + /** * @return Portable processor. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java index 252baed..80e7b39 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java @@ -69,6 +69,11 @@ public class NoOpBinary implements IgniteBinary { } /** {@inheritDoc} */ + @Override public BinaryObject buildEnum(String typeName, int ord) { + throw unsupported(); + } + + /** {@inheritDoc} */ private BinaryObjectException unsupported() { return new BinaryObjectException("Binary marshaller is not configured."); } http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java ---------------------------------------------------------------------- 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 7db752a..71f42e2 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 @@ -69,7 +69,6 @@ import org.apache.ignite.internal.processors.platform.utils.PlatformReaderBiClos import org.apache.ignite.internal.processors.platform.utils.PlatformReaderClosure; import org.apache.ignite.internal.processors.platform.utils.PlatformUtils; import org.apache.ignite.internal.util.typedef.F; -import org.apache.ignite.internal.util.typedef.T4; import org.apache.ignite.lang.IgniteBiTuple; import org.jetbrains.annotations.Nullable; @@ -341,9 +340,9 @@ public class PlatformContextImpl implements PlatformContext { /** {@inheritDoc} */ @SuppressWarnings("ConstantConditions") @Override public void processMetadata(BinaryRawReaderEx reader) { - Collection>> metas = PlatformUtils.readCollection(reader, - new PlatformReaderClosure>>() { - @Override public T4> read(BinaryRawReaderEx reader) { + Collection metas = PlatformUtils.readCollection(reader, + new PlatformReaderClosure() { + @Override public Metadata read(BinaryRawReaderEx reader) { int typeId = reader.readInt(); String typeName = reader.readString(); String affKey = reader.readString(); @@ -355,13 +354,15 @@ public class PlatformContextImpl implements PlatformContext { } }); - return new T4<>(typeId, typeName, affKey, fields); + boolean isEnum = reader.readBoolean(); + + return new Metadata(typeId, typeName, affKey, fields, isEnum); } } ); - for (T4> meta : metas) - cacheObjProc.updateMetadata(meta.get1(), meta.get2(), meta.get3(), meta.get4()); + for (Metadata meta : metas) + cacheObjProc.updateMetadata(meta.typeId, meta.typeName, meta.affKey, meta.fields, meta.isEnum); } /** {@inheritDoc} */ @@ -398,6 +399,7 @@ public class PlatformContextImpl implements PlatformContext { writer.writeString(meta.typeName()); writer.writeString(meta.affinityKeyFieldName()); writer.writeMap(fields); + writer.writeBoolean(meta.isEnum()); } } @@ -615,4 +617,41 @@ public class PlatformContextImpl implements PlatformContext { @Override public PlatformClusterNodeFilter createClusterNodeFilter(Object filter) { return new PlatformClusterNodeFilterImpl(filter, this); } + + /** + * Metadata holder. + */ + private static class Metadata { + /** Type ID. */ + private final int typeId; + + /** Type name. */ + private final String typeName; + + /** Affinity key. */ + private final String affKey; + + /** Fields map. */ + private final Map fields; + + /** Enum flag. */ + private final boolean isEnum; + + /** + * Constructor. + * + * @param typeId Type ID. + * @param typeName Type name. + * @param affKey Affinity key. + * @param fields Fields. + * @param isEnum Enum flag. + */ + public Metadata(int typeId, String typeName, String affKey, Map fields, boolean isEnum) { + this.typeId = typeId; + this.typeName = typeName; + this.affKey = affKey; + this.fields = fields; + this.isEnum = isEnum; + } + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/transactions/PlatformTransactions.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/transactions/PlatformTransactions.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/transactions/PlatformTransactions.java index 5f5f5c3..d97e071 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/transactions/PlatformTransactions.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/transactions/PlatformTransactions.java @@ -236,8 +236,8 @@ public class PlatformTransactions extends PlatformAbstractTarget { case OP_CACHE_CONFIG_PARAMETERS: TransactionConfiguration txCfg = platformCtx.kernalContext().config().getTransactionConfiguration(); - writer.writeEnum(txCfg.getDefaultTxConcurrency()); - writer.writeEnum(txCfg.getDefaultTxIsolation()); + writer.writeInt(txCfg.getDefaultTxConcurrency().ordinal()); + writer.writeInt(txCfg.getDefaultTxIsolation().ordinal()); writer.writeLong(txCfg.getDefaultTxTimeout()); break; http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java ---------------------------------------------------------------------- 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 14c040c..6572764 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 @@ -787,6 +787,7 @@ public class PlatformUtils { writer.writeString(typ.getSerializer()); writer.writeString(typ.getAffinityKeyFieldName()); writer.writeObject(typ.getKeepDeserialized()); + writer.writeBoolean(typ.isEnum()); } }); http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/main/java/org/apache/ignite/platform/dotnet/PlatformDotNetBinaryTypeConfiguration.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/platform/dotnet/PlatformDotNetBinaryTypeConfiguration.java b/modules/core/src/main/java/org/apache/ignite/platform/dotnet/PlatformDotNetBinaryTypeConfiguration.java index df28aef..cae5760 100644 --- a/modules/core/src/main/java/org/apache/ignite/platform/dotnet/PlatformDotNetBinaryTypeConfiguration.java +++ b/modules/core/src/main/java/org/apache/ignite/platform/dotnet/PlatformDotNetBinaryTypeConfiguration.java @@ -42,6 +42,9 @@ public class PlatformDotNetBinaryTypeConfiguration { /** Whether to cache deserialized value. */ private Boolean keepDeserialized; + /** Enum flag. */ + private boolean isEnum; + /** * Default constructor. */ @@ -60,6 +63,7 @@ public class PlatformDotNetBinaryTypeConfiguration { serializer = cfg.getSerializer(); affinityKeyFieldName = cfg.getAffinityKeyFieldName(); keepDeserialized = cfg.isKeepDeserialized(); + isEnum = cfg.isEnum(); } /** @@ -164,6 +168,25 @@ public class PlatformDotNetBinaryTypeConfiguration { this.keepDeserialized = keepDeserialized; } + /** + * Gets whether this is enum type. + * + * @return {@code True} if enum. + */ + public boolean isEnum() { + return isEnum; + } + + /** + * Sets whether this is enum type. + * + * @param isEnum {@code True} if enum. + */ + public void setEnum(boolean isEnum) { + this.isEnum = isEnum; + } + + /** {@inheritDoc} */ @Override public String toString() { return S.toString(PlatformDotNetBinaryTypeConfiguration.class, this); http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryEnumsSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryEnumsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryEnumsSelfTest.java new file mode 100644 index 0000000..3bc3922 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryEnumsSelfTest.java @@ -0,0 +1,446 @@ +/* + * 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.portable; + +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.binary.BinaryTypeConfiguration; +import org.apache.ignite.cache.CacheMode; +import org.apache.ignite.configuration.BinaryConfiguration; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +import java.io.Serializable; +import java.util.Arrays; + +/** + * Contains tests for binary enums. + */ +@SuppressWarnings("unchecked") +public class BinaryEnumsSelfTest extends GridCommonAbstractTest { + /** Cache name. */ + private static String CACHE_NAME = "cache"; + + /** Whether to register types or not. */ + private boolean register; + + /** Node 1. */ + private Ignite node1; + + /** Node 2. */ + private Ignite node2; + + /** Cache 1. */ + private IgniteCache cache1; + + /** Cache 2. */ + private IgniteCache cache2; + + /** Binary cache 1. */ + private IgniteCache cacheBinary1; + + /** Binary cache 2. */ + private IgniteCache cacheBinary2; + + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + register = false; + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + stopAllGrids(); + } + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + if (register) { + BinaryConfiguration bCfg = new BinaryConfiguration(); + + BinaryTypeConfiguration enumCfg = new BinaryTypeConfiguration(EnumType.class.getName()); + enumCfg.setEnum(true); + + bCfg.setTypeConfigurations(Arrays.asList(enumCfg, new BinaryTypeConfiguration(EnumHolder.class.getName()))); + + cfg.setBinaryConfiguration(bCfg); + } + + cfg.setMarshaller(new BinaryMarshaller()); + + CacheConfiguration ccfg = new CacheConfiguration(); + ccfg.setName(CACHE_NAME); + ccfg.setCacheMode(CacheMode.PARTITIONED); + + cfg.setCacheConfiguration(ccfg); + + return cfg; + } + + /** + * Start up routine. + * + * @throws Exception If failed. + */ + private void startUp(boolean register) throws Exception { + this.register = register; + + node1 = startGrid(0); + cache1 = node1.cache(CACHE_NAME); + cacheBinary1 = cache1.withKeepBinary(); + + node2 = startGrid(1); + cache2 = node2.cache(CACHE_NAME); + cacheBinary2 = cache2.withKeepBinary(); + } + + /** + * Test operations on simple type which is registered in advance. + * + * @throws Exception If failed. + */ + public void testSimpleRegistered() throws Exception { + checkSimple(true); + } + + /** + * Test operations on simple type which is not registered in advance. + * + * @throws Exception If failed. + */ + public void testSimpleNotRegistered() throws Exception { + checkSimple(false); + } + + /** + * Test operations when enum is nested into an object (registered). + * + * @throws Exception If failed. + */ + public void testNestedRegistered() throws Exception { + checkNested(true); + } + + /** + * Test operations when enum is nested into an object (not registered). + * + * @throws Exception If failed. + */ + public void testNestedNotRegistered() throws Exception { + checkNested(false); + } + + /** + * Test builder operations on simple type which is registered in advance. + * + * @throws Exception If failed. + */ + public void testSimpleBuilderRegistered() throws Exception { + checkSimpleBuilder(true); + } + + /** + * Test builder operations on simple type which is not registered in advance. + * + * @throws Exception If failed. + */ + public void testSimpleBuilderNotRegistered() throws Exception { + checkSimpleBuilder(false); + } + + /** + * Test builder operations when enum is nested into an object (registered). + * + * @throws Exception If failed. + */ + public void testNestedBuilderRegistered() throws Exception { + checkNestedBuilder(true); + } + + /** + * Test builder operations when enum is nested into an object (not registered). + * + * @throws Exception If failed. + */ + public void testNestedBuilderNotRegistered() throws Exception { + checkNestedBuilder(false); + } + + /** + * Check simple serialization - deserialization. + * + * @param registered If type should be registered in advance. + * @throws Exception If failed. + */ + public void checkSimple(boolean registered) throws Exception { + startUp(registered); + + cache1.put(1, EnumType.ONE); + + validateSimple(1, EnumType.ONE, registered); + } + + /** + * Check nested serialization - deserialization. + * + * @param registered If type should be registered in advance. + * @throws Exception If failed. + */ + private void checkNested(boolean registered) throws Exception { + startUp(registered); + + cache1.put(1, new EnumHolder(EnumType.ONE)); + + validateNested(1, EnumType.ONE, registered); + } + + /** + * Check nested builder serialization - deserialization. + * + * @param registered If type should be registered in advance. + * @throws Exception If failed. + */ + private void checkNestedBuilder(boolean registered) throws Exception { + startUp(registered); + + BinaryObject obj = node1.binary().builder("EnumHolder").setField("val", EnumType.ONE).build(); + + assert node1.binary().type("EnumHolder") != null; + assert node1.binary().type("EnumType") != null; + + cacheBinary1.put(1, obj); + + validateNested(1, EnumType.ONE, registered); + + obj = (BinaryObject)cacheBinary1.get(1); + obj = node1.binary().builder(obj).setField("val", EnumType.TWO).build(); + + cacheBinary1.put(1, obj); + + validateNested(1, EnumType.TWO, registered); + } + + /** + * Validate nested object. + * + * @param key Key. + * @param val Value. + * @param registered Registered flag. + * @throws Exception If failed. + */ + private void validateNested(int key, EnumType val, boolean registered) throws Exception { + if (registered) { + EnumHolder res1 = (EnumHolder) cache1.get(key); + EnumHolder res2 = (EnumHolder) cache2.get(key); + + assertEquals(val, res1.val); + assertEquals(val, res2.val); + } + + BinaryObject resBinary1 = (BinaryObject)cacheBinary1.get(key); + BinaryObject resBinary2 = (BinaryObject)cacheBinary2.get(key); + + validate((BinaryObject)resBinary1.field("val"), val); + validate((BinaryObject)resBinary2.field("val"), val); + } + + /** + * Check simple serialization - deserialization using builder. + * + * @param registered If type should be registered in advance. + * @throws Exception If failed. + */ + public void checkSimpleBuilder(boolean registered) throws Exception { + startUp(registered); + + BinaryObject binary = node1.binary().buildEnum(EnumType.class.getSimpleName(), EnumType.ONE.ordinal()); + + cacheBinary1.put(1, binary); + + validateSimple(1, EnumType.ONE, registered); + } + + /** + * Test enum array (registered). + * + * @throws Exception If failed. + */ + public void testSimpleArrayRegistered() throws Exception { + checkSimpleArray(true); + } + + /** + * Test enum array (not registered). + * + * @throws Exception If failed. + */ + public void testSimpleArrayNotRegistered() throws Exception { + checkSimpleArray(false); + } + + /** + * Test enum array created using builder (registered). + * + * @throws Exception If failed. + */ + public void testSimpleBuilderArrayRegistered() throws Exception { + checkSimpleBuilderArray(true); + } + + /** + * Test enum array created using builder (not registered). + * + * @throws Exception If failed. + */ + public void testSimpleBuilderArrayNotRegistered() throws Exception { + checkSimpleBuilderArray(false); + } + + /** + * Check arrays with builder. + * + * @param registered Registered flag. + * @throws Exception If failed. + */ + public void checkSimpleArray(boolean registered) throws Exception { + startUp(registered); + + cache1.put(1, new EnumType[] { EnumType.ONE, EnumType.TWO }); + + validateSimpleArray(registered); + } + + /** + * Check arrays with builder. + * + * @param registered Registered flag. + * @throws Exception If failed. + */ + public void checkSimpleBuilderArray(boolean registered) throws Exception { + startUp(registered); + + BinaryObject binaryOne = node1.binary().buildEnum(EnumType.class.getSimpleName(), EnumType.ONE.ordinal()); + BinaryObject binaryTwo = node1.binary().buildEnum(EnumType.class.getSimpleName(), EnumType.TWO.ordinal()); + + cacheBinary1.put(1, new BinaryObject[] { binaryOne, binaryTwo }); + + validateSimpleArray(registered); + } + + /** + * Validate simple array. + * + * @param registered Registered flag. + */ + private void validateSimpleArray(boolean registered) { + if (registered) { + Object[] arr1 = (Object[])cache1.get(1); + Object[] arr2 = (Object[])cache2.get(1); + + assertEquals(2, arr1.length); + assertEquals(2, arr2.length); + + assertEquals(EnumType.ONE, arr1[0]); + assertEquals(EnumType.TWO, arr1[1]); + + assertEquals(EnumType.ONE, arr2[0]); + assertEquals(EnumType.TWO, arr2[1]); + } + + Object[] arrBinary1 = (Object[])cacheBinary1.get(1); + Object[] arrBinary2 = (Object[])cacheBinary2.get(1); + + assertEquals(2, arrBinary1.length); + assertEquals(2, arrBinary2.length); + + validate((BinaryObject) arrBinary1[0], EnumType.ONE); + validate((BinaryObject) arrBinary1[1], EnumType.TWO); + + validate((BinaryObject) arrBinary2[0], EnumType.ONE); + validate((BinaryObject) arrBinary2[1], EnumType.TWO); + } + + /** + * Internal check routine for simple scenario. + * + * @param key Key. + * @param val Value. + * @param registered Registered flag. + * @throws Exception If failed. + */ + private void validateSimple(int key, EnumType val, boolean registered) throws Exception { + if (registered) { + assertEquals(val, cache1.get(key)); + assertEquals(val, cache2.get(key)); + } + + validate((BinaryObject) cacheBinary1.get(key), val); + validate((BinaryObject) cacheBinary2.get(key), val); + } + + /** + * Validate single value. + * + * @param obj Binary value. + * @param val Expected value. + */ + private void validate(BinaryObject obj, EnumType val) { + assertTrue(obj.type().isEnum()); + + assertEquals(node1.binary().typeId(EnumType.class.getName()), obj.type().typeId()); + assertEquals(node2.binary().typeId(EnumType.class.getName()), obj.type().typeId()); + + assertEquals(val.ordinal(), obj.enumOrdinal()); + } + + /** + * Enumeration holder. + */ + public static class EnumHolder implements Serializable { + /** Value. */ + public EnumType val; + + /** + * Default constructor. + */ + @SuppressWarnings("UnusedDeclaration") + public EnumHolder() { + // No-op. + } + + /** + * Constructor. + * + * @param val Value. + */ + public EnumHolder(EnumType val) { + this.val = val; + } + } + + /** + * Enumeration for tests. + */ + public static enum EnumType { + ONE, + TWO + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java index 655582e..9f7822c 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java @@ -487,8 +487,8 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { assertArrayEquals(obj.objArr, (Object[])po.field("objArr")); assertEquals(obj.col, po.field("col")); assertEquals(obj.map, po.field("map")); - assertEquals(new Integer(obj.enumVal.ordinal()), new Integer(((Enum)po.field("enumVal")).ordinal())); - assertArrayEquals(ordinals(obj.enumArr), ordinals((Enum[])po.field("enumArr"))); + assertEquals(new Integer(obj.enumVal.ordinal()), new Integer(((BinaryObject)po.field("enumVal")).enumOrdinal())); + assertArrayEquals(ordinals(obj.enumArr), ordinals((BinaryObject[])po.field("enumArr"))); assertNull(po.field("unknown")); BinaryObject innerPo = po.field("inner"); @@ -523,8 +523,8 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { assertEquals(obj.inner.col, innerPo.field("col")); assertEquals(obj.inner.map, innerPo.field("map")); assertEquals(new Integer(obj.inner.enumVal.ordinal()), - new Integer(((Enum)innerPo.field("enumVal")).ordinal())); - assertArrayEquals(ordinals(obj.inner.enumArr), ordinals((Enum[])innerPo.field("enumArr"))); + new Integer(((BinaryObject)innerPo.field("enumVal")).enumOrdinal())); + assertArrayEquals(ordinals(obj.inner.enumArr), ordinals((BinaryObject[])innerPo.field("enumArr"))); assertNull(innerPo.field("inner")); assertNull(innerPo.field("unknown")); } @@ -572,8 +572,8 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { assertArrayEquals(obj.objArr, (Object[])po.field("_objArr")); assertEquals(obj.col, po.field("_col")); assertEquals(obj.map, po.field("_map")); - assertEquals(new Integer(obj.enumVal.ordinal()), new Integer(((Enum)po.field("_enumVal")).ordinal())); - assertArrayEquals(ordinals(obj.enumArr), ordinals((Enum[])po.field("_enumArr"))); + assertEquals(new Integer(obj.enumVal.ordinal()), new Integer(((BinaryObject)po.field("_enumVal")).enumOrdinal())); + assertArrayEquals(ordinals(obj.enumArr), ordinals((BinaryObject[])po.field("_enumArr"))); assertNull(po.field("unknown")); BinaryObject simplePo = po.field("_simple"); @@ -608,8 +608,8 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { assertEquals(obj.simple.col, simplePo.field("col")); assertEquals(obj.simple.map, simplePo.field("map")); assertEquals(new Integer(obj.simple.enumVal.ordinal()), - new Integer(((Enum)simplePo.field("enumVal")).ordinal())); - assertArrayEquals(ordinals(obj.simple.enumArr), ordinals((Enum[])simplePo.field("enumArr"))); + new Integer(((BinaryObject)simplePo.field("enumVal")).enumOrdinal())); + assertArrayEquals(ordinals(obj.simple.enumArr), ordinals((BinaryObject[])simplePo.field("enumArr"))); assertNull(simplePo.field("simple")); assertNull(simplePo.field("portable")); assertNull(simplePo.field("unknown")); @@ -645,8 +645,8 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { assertEquals(obj.portable.col, portablePo.field("_col")); assertEquals(obj.portable.map, portablePo.field("_map")); assertEquals(new Integer(obj.portable.enumVal.ordinal()), - new Integer(((Enum)portablePo.field("_enumVal")).ordinal())); - assertArrayEquals(ordinals(obj.portable.enumArr), ordinals((Enum[])portablePo.field("_enumArr"))); + new Integer(((BinaryObject)portablePo.field("_enumVal")).enumOrdinal())); + assertArrayEquals(ordinals(obj.portable.enumArr), ordinals((BinaryObject[])portablePo.field("_enumArr"))); assertNull(portablePo.field("_simple")); assertNull(portablePo.field("_portable")); assertNull(portablePo.field("unknown")); @@ -684,8 +684,8 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { assertArrayEquals(obj.objArr, (Object[])po.field("objArr")); assertEquals(obj.col, po.field("col")); assertEquals(obj.map, po.field("map")); - assertEquals(new Integer(obj.enumVal.ordinal()), new Integer(((Enum)po.field("enumVal")).ordinal())); - assertArrayEquals(ordinals(obj.enumArr), ordinals((Enum[])po.field("enumArr"))); + assertEquals(new Integer(obj.enumVal.ordinal()), new Integer(((BinaryObject)po.field("enumVal")).enumOrdinal())); + assertArrayEquals(ordinals(obj.enumArr), ordinals((BinaryObject[])po.field("enumArr"))); assertNull(po.field("unknown")); assertEquals(obj, po.deserialize()); @@ -2203,6 +2203,19 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { } /** + * @param enumArr Enum array. + * @return Ordinals. + */ + private > Integer[] ordinals(BinaryObject[] enumArr) { + Integer[] ords = new Integer[enumArr.length]; + + for (int i = 0; i < enumArr.length; i++) + ords[i] = enumArr[i].enumOrdinal(); + + return ords; + } + + /** * @param po Portable object. * @param off Offset. * @return Value. http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java b/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java index c464945..a284883 100644 --- a/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java +++ b/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java @@ -194,9 +194,9 @@ public class PlatformComputeEchoTask extends ComputeTaskAdapter case TYPE_ENUM_FIELD: IgniteCache cache = ignite.cache(null).withKeepBinary(); BinaryObject obj = cache.get(TYPE_ENUM_FIELD); - PlatformComputeEnum val = obj.field("interopEnum"); + BinaryObject val = obj.field("interopEnum"); - return val; + return val.deserialize(); default: throw new IgniteException("Unknown type: " + type); http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePortableObjectsTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePortableObjectsTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePortableObjectsTestSuite.java index 16eeb2b..629835b 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePortableObjectsTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePortableObjectsTestSuite.java @@ -18,6 +18,7 @@ package org.apache.ignite.testsuites; import junit.framework.TestSuite; +import org.apache.ignite.internal.portable.BinaryEnumsSelfTest; import org.apache.ignite.internal.portable.GridPortableAffinityKeySelfTest; import org.apache.ignite.internal.portable.BinaryObjectBuilderAdditionalSelfTest; import org.apache.ignite.internal.portable.BinaryObjectBuilderSelfTest; @@ -72,6 +73,7 @@ public class IgnitePortableObjectsTestSuite extends TestSuite { suite.addTestSuite(BinaryFieldsOffheapSelfTest.class); suite.addTestSuite(BinaryFooterOffsetsHeapSelfTest.class); suite.addTestSuite(BinaryFooterOffsetsOffheapSelfTest.class); + suite.addTestSuite(BinaryEnumsSelfTest.class); suite.addTestSuite(GridPortableMetaDataSelfTest.class); suite.addTestSuite(GridPortableAffinityKeySelfTest.class); suite.addTestSuite(GridPortableWildcardsSelfTest.class); http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp b/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp index 2e86ccd..6c3bf7f 100644 --- a/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp +++ b/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp @@ -32,7 +32,7 @@ namespace ignite { namespace binary { - /** Operation: Clear. */ + /** Operation: metadata update. */ const int32_t OP_METADATA = -1; BinaryTypeUpdaterImpl::BinaryTypeUpdaterImpl(SharedPointer env, @@ -78,6 +78,8 @@ namespace ignite else rawWriter.WriteInt32(0); + rawWriter.WriteBool(false); // Enums are not supported for now. + out.Synchronize(); long long res = env.Get()->Context()->TargetInStreamOutLong(javaRef, OP_METADATA, mem.Get()->PointerLong(), &jniErr);