http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryJavaFilterTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryJavaFilterTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryJavaFilterTest.cs new file mode 100644 index 0000000..9cb0907 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryJavaFilterTest.cs @@ -0,0 +1,286 @@ +/* + * 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. + */ + +// ReSharper disable UnusedAutoPropertyAccessor.Local +#pragma warning disable 618 // SpringConfigUrl +namespace Apache.Ignite.Core.Tests.Cache.Query.Continuous +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using System.Threading; + using Apache.Ignite.Core.Binary; + using Apache.Ignite.Core.Cache.Event; + using Apache.Ignite.Core.Cache.Query.Continuous; + using Apache.Ignite.Core.Common; + using Apache.Ignite.Core.Impl; + using Apache.Ignite.Core.Interop; + using NUnit.Framework; + + /// <summary> + /// Tests query in a cluster with Java-only and .NET nodes. + /// </summary> + public class ContinuousQueryJavaFilterTest + { + /** */ + private const string SpringConfig = @"Config\Compute\compute-grid1.xml"; + + /** */ + private const string SpringConfig2 = @"Config\Compute\compute-grid2.xml"; + + /** */ + private const string StartTask = "org.apache.ignite.platform.PlatformStartIgniteTask"; + + /** */ + private const string StopTask = "org.apache.ignite.platform.PlatformStopIgniteTask"; + + /** */ + private IIgnite _ignite; + + /** */ + private string _javaNodeName; + + /** */ + private static volatile ICacheEntryEvent<int, string> _lastEvent; + + /// <summary> + /// Fixture set up. + /// </summary> + [TestFixtureSetUp] + public void FixtureSetUp() + { + // Main .NET nodes + IList<String> jvmOpts = TestUtils.TestJavaOptions(); + + _ignite = Ignition.Start(new IgniteConfiguration + { + JvmClasspath = TestUtils.CreateTestClasspath(), + JvmOptions = jvmOpts, + SpringConfigUrl = SpringConfig, + BinaryConfiguration = new BinaryConfiguration + { + TypeConfigurations = new List<BinaryTypeConfiguration> + { + new BinaryTypeConfiguration(typeof(TestBinary)) + } + } + }); + + // Second .NET node + Ignition.Start(new IgniteConfigurationEx + { + JvmClasspath = TestUtils.CreateTestClasspath(), + JvmOptions = jvmOpts, + SpringConfigUrl = SpringConfig2, + GridName = "dotNet2" + }); + + // Java-only node + _javaNodeName = _ignite.GetCompute().ExecuteJavaTask<string>(StartTask, SpringConfig2); + + Assert.IsTrue(_ignite.WaitTopology(3, 5000)); + } + + /// <summary> + /// Fixture tear down. + /// </summary> + [TestFixtureTearDown] + public void FixtureTearDown() + { + _ignite.GetCompute().ExecuteJavaTask<object>(StopTask, _javaNodeName); + Ignition.StopAll(true); + } + + /// <summary> + /// Tests the filter. + /// </summary> + [Test] + public void TestFilter() + { + var javaObj = new JavaObject("org.apache.ignite.platform.PlatformCacheEntryEventFilter") + { + Properties = + { + {"startsWith", "valid"}, + {"charField", 'a'}, + {"byteField", (byte) 1}, + {"sbyteField", (sbyte) 2}, + {"shortField", (short) 3}, + {"ushortField", (ushort) 4}, + {"intField", 5}, + {"uintField", (uint) 6}, + {"longField", (long) 7}, + {"ulongField", (ulong) 8}, + {"floatField", (float) 9.99}, + {"doubleField", 10.123}, + {"decimalField", (decimal) 11.245}, + {"boolField", true}, + {"guidField", Guid.Parse("1c579241-509d-47c6-a1a0-87462ae31e59")}, + { + "objField", new TestBinary + { + Int = 1, + String = "2" + } + }, + {"charArr", new[] {'a'}}, + {"byteArr", new[] {(byte) 1}}, + {"sbyteArr", new[] {(sbyte) 2}}, + {"shortArr", new[] {(short) 3}}, + {"ushortArr", new[] {(ushort) 4}}, + {"intArr", new[] {5}}, + {"uintArr", new[] {(uint) 6}}, + {"longArr", new[] {(long) 7}}, + {"ulongArr", new[] {(ulong) 8}}, + {"floatArr", new[] {(float) 9.99}}, + {"doubleArr", new[] {10.123}}, + {"boolArr", new[] {true}}, + { + "objArr", new object[] + { + new TestBinary + { + Int = 1, + String = "2" + } + } + }, + {"arrayList", new ArrayList {"x"}}, + {"hashTable", new Hashtable {{1, "2"}}} + } + }; + + var filter = javaObj.ToCacheEntryEventFilter<int, string>(); + + TestFilter(filter); + } + + /// <summary> + /// Tests the factory class. + /// </summary> + [Test] + public void TestFactory() + { + var javaObj = new JavaObject("org.apache.ignite.platform.PlatformCacheEntryEventFilterFactory", + new Dictionary<string, object> {{"startsWith", "valid"}}); + + var filter = javaObj.ToCacheEntryEventFilter<int, string>(); + + TestFilter(filter); + } + + /// <summary> + /// Tests the invalid class name + /// </summary> + [Test] + public void TestInvalidClassName() + { + var filter = new JavaObject("blabla").ToCacheEntryEventFilter<int, string>(); + + var ex = Assert.Throws<IgniteException>(() => TestFilter(filter)); + + Assert.IsTrue(ex.Message.StartsWith("Java object/factory class is not found")); + } + + /// <summary> + /// Tests the invalid class name + /// </summary> + [Test] + public void TestInvalidProperty() + { + var javaObject = new JavaObject("org.apache.ignite.platform.PlatformCacheEntryEventFilter") + { + Properties = {{"invalidProp", "123"}} + }; + + var filter = javaObject.ToCacheEntryEventFilter<int, string>(); + + var ex = Assert.Throws<IgniteException>(() => TestFilter(filter)); + + Assert.IsTrue(ex.Message.StartsWith("Java object/factory class field is not found")); + } + + /// <summary> + /// Tests the specified filter. + /// </summary> + private void TestFilter(ICacheEntryEventFilter<int, string> pred) + { + TestFilter(pred, false); + TestFilter(pred, true); + } + + /// <summary> + /// Tests the specified filter. + /// </summary> + private void TestFilter(ICacheEntryEventFilter<int, string> pred, bool local) + { + var cache = _ignite.GetOrCreateCache<int, string>("qry"); + var qry = new ContinuousQuery<int, string>(new QueryListener(), pred, local); + var aff = _ignite.GetAffinity("qry"); + var localNode = _ignite.GetCluster().GetLocalNode(); + + // Get one key per node + var keyMap = aff.MapKeysToNodes(Enumerable.Range(1, 100)); + Assert.AreEqual(3, keyMap.Count); + var keys = local + ? keyMap[localNode].Take(1) + : keyMap.Select(x => x.Value.First()); + + using (cache.QueryContinuous(qry)) + { + // Run on many keys to test all nodes + foreach (var key in keys) + { + _lastEvent = null; + cache[key] = "validValue"; + + TestUtils.WaitForCondition(() => _lastEvent != null, 2000); + Assert.IsNotNull(_lastEvent); + Assert.AreEqual(cache[key], _lastEvent.Value); + + _lastEvent = null; + cache[key] = "invalidValue"; + + Thread.Sleep(2000); + Assert.IsNull(_lastEvent); + } + } + } + + /// <summary> + /// Test listener. + /// </summary> + private class QueryListener : ICacheEntryEventListener<int, string> + { + /** <inheritdoc /> */ + public void OnEvent(IEnumerable<ICacheEntryEvent<int, string>> evts) + { + _lastEvent = evts.FirstOrDefault(); + } + } + + /// <summary> + /// Test binary object. + /// </summary> + private class TestBinary + { + public int Int { get; set; } + public string String { get; set; } + } + } +}
http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml index 3061773..78a30a8 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml @@ -69,7 +69,6 @@ </bean> </list> </property> - </bean> </property> http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid2.xml ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid2.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid2.xml index ef29a89..f32e0bb 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid2.xml +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid2.xml @@ -62,7 +62,16 @@ </bean> </list> </property> - + <property name="idMapper"> + <bean class="org.apache.ignite.binary.BinaryBasicIdMapper"> + <constructor-arg value="true"/> + </bean> + </property> + <property name="nameMapper"> + <bean class="org.apache.ignite.binary.BinaryBasicNameMapper"> + <constructor-arg value="true"/> + </bean> + </property> </bean> </property> http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj index 12404be..05a7fa7 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj @@ -80,6 +80,7 @@ <Compile Include="Cache\IMutableCacheEntry.cs" /> <Compile Include="Cache\Package-Info.cs" /> <Compile Include="Cache\Query\Continuous\ContinuousQuery.cs" /> + <Compile Include="Cache\Query\Continuous\ContinuousQueryExtensions.cs" /> <Compile Include="Cache\Query\Continuous\IContinuousQueryHandle.cs" /> <Compile Include="Cache\Query\Continuous\Package-Info.cs" /> <Compile Include="Cache\Query\IQueryCursor.cs" /> @@ -107,6 +108,8 @@ <Compile Include="Common\IgniteFutureCancelledException.cs" /> <Compile Include="Common\IgniteGuid.cs" /> <Compile Include="Common\Package-Info.cs" /> + <Compile Include="Impl\Cache\Event\JavaCacheEntryEventFilter.cs" /> + <Compile Include="Impl\Common\PlatformJavaObjectFactoryProxy.cs" /> <Compile Include="Compute\ComputeExecutionRejectedException.cs" /> <Compile Include="Compute\ComputeJobAdapter.cs" /> <Compile Include="Compute\ComputeJobFailoverException.cs" /> @@ -324,6 +327,7 @@ <Compile Include="Impl\Unmanaged\UnmanagedNonReleaseableTarget.cs" /> <Compile Include="Impl\Unmanaged\UnmanagedTarget.cs" /> <Compile Include="Impl\Unmanaged\UnmanagedUtils.cs" /> + <Compile Include="Interop\JavaObject.cs" /> <Compile Include="Lifecycle\Package-Info.cs" /> <Compile Include="Messaging\Package-Info.cs" /> <Compile Include="Package-Info.cs" /> @@ -399,6 +403,9 @@ <ItemGroup> <None Include="Apache.Ignite.Core.snk" /> </ItemGroup> + <ItemGroup> + <Folder Include="Impl\Common\JavaObjects\" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. @@ -407,4 +414,4 @@ <Target Name="AfterBuild"> </Target> --> -</Project> \ No newline at end of file +</Project> http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQueryExtensions.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQueryExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQueryExtensions.cs new file mode 100644 index 0000000..50cbe9f --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQueryExtensions.cs @@ -0,0 +1,39 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache.Query.Continuous +{ + using Apache.Ignite.Core.Cache.Event; + using Apache.Ignite.Core.Impl.Cache.Event; + using Apache.Ignite.Core.Interop; + + /// <summary> + /// Extensions for continuous queries. + /// </summary> + public static class ContinuousQueryExtensions + { + /// <summary> + /// Creates the cache event filter that delegates to the corresponding Java object. + /// </summary> + /// <typeparam name="TK">Key type.</typeparam> + /// <typeparam name="TV">Value type.</typeparam> + public static ICacheEntryEventFilter<TK, TV> ToCacheEntryEventFilter<TK, TV>(this JavaObject javaObject) + { + return new JavaCacheEntryEventFilter<TK, TV>(javaObject.ClassName, javaObject.Properties); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs index 1c85e31..80e5b26 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs @@ -187,6 +187,9 @@ namespace Apache.Ignite.Core.Impl.Binary /** Type: stream receiver holder. */ public const byte TypeStreamReceiverHolder = 94; + /** Type: platform object proxy. */ + public const byte TypePlatformJavaObjectFactoryProxy = 99; + /** Collection: custom. */ public const byte CollectionCustom = 0; http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs index 457830f..81fc195 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs @@ -26,6 +26,7 @@ namespace Apache.Ignite.Core.Impl.Binary using Apache.Ignite.Core.Impl.Binary.Metadata; using Apache.Ignite.Core.Impl.Cache; using Apache.Ignite.Core.Impl.Cache.Query.Continuous; + using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.Impl.Compute; using Apache.Ignite.Core.Impl.Compute.Closure; using Apache.Ignite.Core.Impl.Datastream; @@ -534,6 +535,7 @@ namespace Apache.Ignite.Core.Impl.Binary AddSystemType(BinaryUtils.TypeCacheEntryPredicateHolder, w => new CacheEntryFilterHolder(w)); AddSystemType(BinaryUtils.TypeMessageListenerHolder, w => new MessageListenerHolder(w)); AddSystemType(BinaryUtils.TypeStreamReceiverHolder, w => new StreamReceiverHolder(w)); + AddSystemType(BinaryUtils.TypePlatformJavaObjectFactoryProxy, w => new PlatformJavaObjectFactoryProxy()); } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Event/JavaCacheEntryEventFilter.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Event/JavaCacheEntryEventFilter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Event/JavaCacheEntryEventFilter.cs new file mode 100644 index 0000000..b5c2ece --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Event/JavaCacheEntryEventFilter.cs @@ -0,0 +1,49 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Impl.Cache.Event +{ + using System; + using System.Collections.Generic; + using Apache.Ignite.Core.Cache.Event; + using Apache.Ignite.Core.Impl.Common; + + /// <summary> + /// Cache entry event filter that delegates to Java. + /// </summary> + /// <typeparam name="TK">Key type.</typeparam> + /// <typeparam name="TV">Value type.</typeparam> + internal class JavaCacheEntryEventFilter<TK, TV> : PlatformJavaObjectFactoryProxy, ICacheEntryEventFilter<TK, TV> + { + /** <inheritdoc /> */ + public bool Evaluate(ICacheEntryEvent<TK, TV> evt) + { + throw new InvalidOperationException(GetType() + " cannot be invoked directly."); + } + + /// <summary> + /// Initializes a new instance of the <see cref="JavaCacheEntryEventFilter{TK, TV}"/> class. + /// </summary> + /// <param name="factoryClassName">Name of the factory class.</param> + /// <param name="properties">The properties.</param> + public JavaCacheEntryEventFilter(string factoryClassName, IDictionary<string, object> properties) + : base(FactoryType.User, factoryClassName, null, properties) + { + // No-op. + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/Continuous/ContinuousQueryHandleImpl.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/Continuous/ContinuousQueryHandleImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/Continuous/ContinuousQueryHandleImpl.cs index fef904b..101ed43 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/Continuous/ContinuousQueryHandleImpl.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/Continuous/ContinuousQueryHandleImpl.cs @@ -26,6 +26,7 @@ namespace Apache.Ignite.Core.Impl.Cache.Query.Continuous using Apache.Ignite.Core.Cache.Query.Continuous; using Apache.Ignite.Core.Impl.Binary; using Apache.Ignite.Core.Impl.Binary.IO; + using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.Impl.Resource; using Apache.Ignite.Core.Impl.Unmanaged; using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils; @@ -111,10 +112,20 @@ namespace Apache.Ignite.Core.Impl.Cache.Query.Continuous writer.WriteBoolean(qry.Local); writer.WriteBoolean(_filter != null); - var filterHolder = _filter == null || qry.Local ? null : - new ContinuousQueryFilterHolder(_filter, _keepBinary); + var javaFilter = _filter as PlatformJavaObjectFactoryProxy; - writer.WriteObject(filterHolder); + if (javaFilter != null) + { + writer.WriteObject(javaFilter.GetRawProxy()); + } + else + { + var filterHolder = _filter == null || qry.Local + ? null + : new ContinuousQueryFilterHolder(_filter, _keepBinary); + + writer.WriteObject(filterHolder); + } writer.WriteInt(qry.BufferSize); writer.WriteLong((long)qry.TimeInterval.TotalMilliseconds); http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PlatformJavaObjectFactoryProxy.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PlatformJavaObjectFactoryProxy.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PlatformJavaObjectFactoryProxy.cs new file mode 100644 index 0000000..89b2891 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PlatformJavaObjectFactoryProxy.cs @@ -0,0 +1,106 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Impl.Common +{ + using System; + using System.Collections.Generic; + using Apache.Ignite.Core.Binary; + using Apache.Ignite.Core.Impl.Binary; + + /// <summary> + /// Maps to PlatformJavaObjectFactoryProxy in Java. + /// </summary> + internal class PlatformJavaObjectFactoryProxy : IBinaryWriteAware + { + /// <summary> + /// Represents the factory type. + /// </summary> + internal enum FactoryType + { + User = 0, + Default = 1 + } + + /** Type code. */ + private readonly FactoryType _factoryType; + + /** Java class name */ + private readonly string _factoryClassName; + + /** Optional payload. */ + private readonly object _payload; + + /** Properties to set */ + private readonly IDictionary<string, object> _properties; + + /// <summary> + /// Initializes a new instance of the <see cref="PlatformJavaObjectFactoryProxy" /> class. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="factoryClassName">Name of the factory class.</param> + /// <param name="payload">The payload.</param> + /// <param name="properties">The properties.</param> + protected PlatformJavaObjectFactoryProxy(FactoryType type, string factoryClassName, object payload, + IDictionary<string, object> properties) + { + _factoryType = type; + _factoryClassName = factoryClassName; + _payload = payload; + _properties = properties; + } + + /// <summary> + /// Initializes a new instance of the <see cref="PlatformJavaObjectFactoryProxy"/> class. + /// </summary> + public PlatformJavaObjectFactoryProxy() + { + throw new InvalidOperationException(GetType() + " should never be deserialized on .NET side."); + } + + /** <inheritdoc /> */ + public void WriteBinary(IBinaryWriter writer) + { + var w = writer.GetRawWriter(); + + w.WriteInt((int) _factoryType); + w.WriteString(_factoryClassName); + w.WriteObject(_payload); + + if (_properties != null) + { + w.WriteInt(_properties.Count); + + foreach (var pair in _properties) + { + w.WriteString(pair.Key); + w.WriteObject(pair.Value); + } + } + else + w.WriteInt(0); + } + + /// <summary> + /// Gets the raw proxy (not the derived type) for serialization. + /// </summary> + public PlatformJavaObjectFactoryProxy GetRawProxy() + { + return new PlatformJavaObjectFactoryProxy(_factoryType, _factoryClassName, _payload, _properties); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Interop/JavaObject.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Interop/JavaObject.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Interop/JavaObject.cs new file mode 100644 index 0000000..98ef619 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Interop/JavaObject.cs @@ -0,0 +1,80 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Interop +{ + using System.Collections.Generic; + using Apache.Ignite.Core.Impl.Common; + + /// <summary> + /// Represents a Java object wrapper. + /// <para /> + /// <see cref="JavaObject"/> can be converted to Ignite filters and predicates + /// which can be used on non-.NET Ignite nodes. + /// <para /> + /// Workflow is as follows: + /// Instantiate specified Java class; + /// Set property values; + /// If the resulting object implements PlatformJavaObjectFactory, call create() method and use the result, + /// otherwise use the original object. + /// </summary> + public class JavaObject + { + /** Java class name. */ + private readonly string _className; + + /** Properties. */ + private readonly IDictionary<string, object> _properties = new Dictionary<string, object>(); + + /// <summary> + /// Initializes a new instance of the <see cref="JavaObject"/> class. + /// </summary> + /// <param name="className">Name of the Java class.</param> + public JavaObject(string className) + { + IgniteArgumentCheck.NotNullOrEmpty(className, "className"); + + _className = className; + } + + /// <summary> + /// Initializes a new instance of the <see cref="JavaObject"/> class. + /// </summary> + /// <param name="className">Name of the Java class.</param> + /// <param name="properties">The properties to set on the Java object.</param> + public JavaObject(string className, IDictionary<string, object> properties) : this(className) + { + _properties = properties ?? _properties; + } + + /// <summary> + /// Gets the Java class name. + /// </summary> + public string ClassName + { + get { return _className; } + } + + /// <summary> + /// Gets the properties to be set on the Java object. + /// </summary> + public IDictionary<string, object> Properties + { + get { return _properties; } + } + } +}
