Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/IMessageReader.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/IMessageReader.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/IMessageReader.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/IMessageReader.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,93 @@ +using System; +using System.Messaging; +using Apache.NMS.MSMQ; +/* + * 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.NMS.MSMQ.Readers +{ + /// <summary> + /// MSMQ message reader. + /// </summary> + public interface IMessageReader + { + /// <summary> + /// Returns without removing (peeks) the first message in the queue + /// referenced by this MessageQueue matching the selection criteria. + /// The Peek method is synchronous, so it blocks the current thread + /// until a message becomes available. + /// </summary> + /// <returns>Peeked message.</returns> + IMessage Peek(); + + /// <summary> + /// Returns without removing (peeks) the first message in the queue + /// referenced by this MessageQueue matching the selection criteria. + /// The Peek method is synchronous, so it blocks the current thread + /// until a message becomes available or the specified time-out occurs. + /// </summary> + /// <param name="timeSpan">Reception time-out.</param> + /// <returns>Peeked message.</returns> + IMessage Peek(TimeSpan timeSpan); + + /// <summary> + /// Receives the first message available in the queue referenced by + /// the MessageQueue matching the selection criteria. + /// This call is synchronous, and blocks the current thread of execution + /// until a message is available. + /// </summary> + /// <returns>Received message.</returns> + IMessage Receive(); + + /// <summary> + /// Receives the first message available in the queue referenced by the + /// MessageQueue matching the selection criteria, and waits until either + /// a message is available in the queue, or the time-out expires. + /// </summary> + /// <param name="timeSpan">Reception time-out.</param> + /// <returns>Received message.</returns> + IMessage Receive(TimeSpan timeSpan); + + /// <summary> + /// Receives the first message available in the transactional queue + /// referenced by the MessageQueue matching the selection criteria. + /// This call is synchronous, and blocks the current thread of execution + /// until a message is available. + /// </summary> + /// <param name="transaction">Transaction.</param> + /// <returns>Received message.</returns> + IMessage Receive(MessageQueueTransaction transaction); + + /// <summary> + /// Receives the first message available in the transactional queue + /// referenced by the MessageQueue matching the selection criteria, + /// and waits until either a message is available in the queue, or the + /// time-out expires. + /// </summary> + /// <param name="timeSpan">Reception time-out.</param> + /// <param name="transaction">Transaction.</param> + /// <returns>Received message.</returns> + IMessage Receive(TimeSpan timeSpan, MessageQueueTransaction transaction); + + /// <summary> + /// Checks if an MSMQ message matches the selection criteria. + /// </summary> + /// <param name="message">MSMQ message.</param> + /// <return>true if the message matches the selection criteria.</return> + bool Matches(Message message); + } +}
Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/MessageReaderUtil.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/MessageReaderUtil.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/MessageReaderUtil.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/MessageReaderUtil.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,91 @@ +using System; +using System.Messaging; +using System.Globalization; +using System.Text.RegularExpressions; +/* + * 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.NMS.MSMQ.Readers +{ + /// <summary> + /// Utility routines for creating MSMQ message readers. + /// </summary> + public static class MessageReaderUtil + { + private static Regex basicSelectorRegex = + new Regex(@"^\s*" + + @"(NMSMessageId)\s*=\s*'([^']*)'|" + + @"(NMSCorrelationId)\s*=\s*'([^']*)'|" + + @"(LookupId)\s*=\s*([-+]{0,1}\d+)" + + @"\s*$", + RegexOptions.IgnoreCase | RegexOptions.Compiled); + + /// <summary> + /// Creates a message reader for the specified message selector. + /// </summary> + /// <param name="messageQueue">The MSMQ message queue from which + /// messages will be read.</param> + /// <param name="messageConverter">A message converter for mapping + /// MSMQ messages to NMS messages.</param> + /// <param name="selector">The message selector.</param> + /// <return>A reader for the specified selector.</return> + public static IMessageReader CreateMessageReader( + MessageQueue messageQueue, IMessageConverter messageConverter, + string selector) + { + IMessageReader reader; + + if(string.IsNullOrEmpty(selector)) + { + reader = new NonFilteringMessageReader(messageQueue, + messageConverter); + } + else + { + Match match = basicSelectorRegex.Match(selector); + if(match.Success) + { + if(!string.IsNullOrEmpty(match.Groups[1].Value)) + { + reader = new ByIdMessageReader(messageQueue, + messageConverter, match.Groups[2].Value); + } + else if(!string.IsNullOrEmpty(match.Groups[3].Value)) + { + reader = new ByCorrelationIdMessageReader(messageQueue, + messageConverter, match.Groups[4].Value); + } + else + { + Int64 lookupId = Int64.Parse(match.Groups[6].Value, + CultureInfo.InvariantCulture); + + reader = new ByLookupIdMessageReader(messageQueue, + messageConverter, lookupId); + } + } + else + { + reader = new BySelectorMessageReader(messageQueue, + messageConverter, selector); + } + } + + return reader; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/NonFilteringMessageReader.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/NonFilteringMessageReader.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/NonFilteringMessageReader.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Readers/NonFilteringMessageReader.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,128 @@ +using System; +using System.Messaging; +using Apache.NMS.MSMQ; +/* + * 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.NMS.MSMQ.Readers +{ + /// <summary> + /// MSMQ message reader, returning all messages, without filtering. + /// </summary> + public class NonFilteringMessageReader : AbstractMessageReader + { + /// <summary> + /// Constructor. + /// </summary> + /// <param name="messageQueue">The MSMQ message queue from which + /// messages will be read.</param> + /// <param name="messageConverter">A message converter for mapping + /// MSMQ messages to NMS messages.</param> + public NonFilteringMessageReader(MessageQueue messageQueue, + IMessageConverter messageConverter) + : base(messageQueue, messageConverter) + { + } + + /// <summary> + /// Returns without removing (peeks) the first message in the queue + /// referenced by this MessageQueue matching the selection criteria. + /// The Peek method is synchronous, so it blocks the current thread + /// until a message becomes available. + /// </summary> + /// <returns>Peeked message.</returns> + public override IMessage Peek() + { + return Convert(messageQueue.Peek()); + } + + /// <summary> + /// Returns without removing (peeks) the first message in the queue + /// referenced by this MessageQueue matching the selection criteria. + /// The Peek method is synchronous, so it blocks the current thread + /// until a message becomes available or the specified time-out occurs. + /// </summary> + /// <param name="timeSpan">Reception time-out.</param> + /// <returns>Peeked message.</returns> + public override IMessage Peek(TimeSpan timeSpan) + { + return Convert(messageQueue.Peek(timeSpan)); + } + + /// <summary> + /// Receives the first message available in the queue referenced by + /// the MessageQueue matching the selection criteria. + /// This call is synchronous, and blocks the current thread of execution + /// until a message is available. + /// </summary> + /// <returns>Received message.</returns> + public override IMessage Receive() + { + return Convert(messageQueue.Receive()); + } + + /// <summary> + /// Receives the first message available in the queue referenced by the + /// MessageQueue matching the selection criteria, and waits until either + /// a message is available in the queue, or the time-out expires. + /// </summary> + /// <param name="timeSpan">Reception time-out.</param> + /// <returns>Received message.</returns> + public override IMessage Receive(TimeSpan timeSpan) + { + return Convert(messageQueue.Receive(timeSpan)); + } + + /// <summary> + /// Receives the first message available in the transactional queue + /// referenced by the MessageQueue matching the selection criteria. + /// This call is synchronous, and blocks the current thread of execution + /// until a message is available. + /// </summary> + /// <param name="transaction">Transaction.</param> + /// <returns>Received message.</returns> + public override IMessage Receive(MessageQueueTransaction transaction) + { + return Convert(messageQueue.Receive(transaction)); + } + + /// <summary> + /// Receives the first message available in the transactional queue + /// referenced by the MessageQueue matching the selection criteria, + /// and waits until either a message is available in the queue, or the + /// time-out expires. + /// </summary> + /// <param name="timeSpan">Reception time-out.</param> + /// <param name="transaction">Transaction.</param> + /// <returns>Received message.</returns> + public override IMessage Receive(TimeSpan timeSpan, + MessageQueueTransaction transaction) + { + return Convert(messageQueue.Receive(timeSpan, transaction)); + } + + /// <summary> + /// Checks if an MSMQ message matches the selection criteria. + /// </summary> + /// <param name="message">MSMQ message.</param> + /// <return>true if the message matches the selection criteria.</return> + public override bool Matches(Message message) + { + return true; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ANDExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ANDExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ANDExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ANDExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,47 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A filter performing a logical AND combination of two expressions. + /// </summary> + public class ANDExpression : LogicExpression + { + protected override string ExpressionSymbol + { + get { return "AND"; } + } + + public ANDExpression(IBooleanExpression left, IBooleanExpression right) + : base(left, right) + { + } + + public override object Evaluate(MessageEvaluationContext message) + { + object lvalue = Left.Evaluate(message); + if(lvalue == null) return null; + if(!(bool)lvalue) return false; + + object rvalue = Right.Evaluate(message); + return rvalue == null ? null : rvalue; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/AlignedNumericValues.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/AlignedNumericValues.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/AlignedNumericValues.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/AlignedNumericValues.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,175 @@ +using System; +using System.Globalization; +using System.Collections.Generic; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A couple of numeric values converted to the type of the largest type. + /// </summary> + public class AlignedNumericValues + { + private object left; + public object Left + { + get { return left; } + } + + private object right; + public object Right + { + get { return right; } + } + + private T type; + public T TypeEnum + { + get { return type; } + } + + public Type Type + { + get { return GetType(type); } + } + + public AlignedNumericValues(object lvalue, object rvalue) + { + if(lvalue == null || rvalue == null) + { + return; + } + + T ltypeEnum = GetTypeEnum(lvalue); + T rtypeEnum = GetTypeEnum(rvalue); + + type = targetType[(int)ltypeEnum][(int)rtypeEnum]; + + left = (ltypeEnum == type ? lvalue : ConvertValue(lvalue, type)); + right = (rtypeEnum == type ? rvalue : ConvertValue(rvalue, type)); + } + + public enum T + { + SByteType = 0, // Signed 8-bit integer (-128 to 127) + ByteType = 1, // Unsigned 8-bit integer (0 to 255) + CharType = 2, // Unicode 16-bit character (U+0000 to U+ffff) + ShortType = 3, // Signed 16-bit integer (-32 768 to 32 767) + UShortType = 4, // Unsigned 16-bit integer (0 to 65 535) + IntType = 5, // Signed 32-bit integer (-2 147 483 648 to 2 147 483 647) + UIntType = 6, // Unsigned 32-bit integer (0 to 4 294 967 295) + LongType = 7, // Signed 64-bit integer (-9 223 372 036 854 775 808 to 9 223 372 036 854 775 807) + ULongType = 8, // Unsigned 64-bit integer (0 to 18 446 744 073 709 551 615) + FloatType = 9, // 7 digits (±1.5eâ45 to ±3.4e38) + DoubleType = 10 // 15-16 digits (±5.0eâ324 to ±1.7e308) + } + + private static Dictionary<Type, T> typeEnums + = new Dictionary<Type, T> + { + { typeof(sbyte ), T.SByteType }, + { typeof(byte ), T.ByteType }, + { typeof(char ), T.CharType }, + { typeof(short ), T.ShortType }, + { typeof(ushort), T.UShortType }, + { typeof(int ), T.IntType }, + { typeof(uint ), T.UIntType }, + { typeof(long ), T.LongType }, + { typeof(ulong ), T.ULongType }, + { typeof(float ), T.FloatType }, + { typeof(double), T.DoubleType } + }; + + private static T[][] targetType = new T[][] + { + // SByteType , ByteType , CharType , ShortType , UShortType, IntType , UIntType , LongType , ULongType , FloatType , DoubleType + /*SByteType */new T[] { T.SByteType , T.ShortType , T.IntType , T.ShortType , T.IntType , T.IntType , T.LongType , T.LongType , T.LongType , T.FloatType , T.DoubleType }, + /*ByteType */new T[] { T.ShortType , T.ByteType , T.UShortType, T.ShortType , T.UShortType, T.IntType , T.UIntType , T.LongType , T.ULongType , T.FloatType , T.DoubleType }, + /*CharType */new T[] { T.IntType , T.UShortType, T.CharType , T.IntType , T.UShortType, T.IntType , T.LongType , T.LongType , T.ULongType , T.FloatType , T.DoubleType }, + /*ShortType */new T[] { T.ShortType , T.ShortType , T.IntType , T.ShortType , T.IntType , T.IntType , T.LongType , T.LongType , T.LongType , T.FloatType , T.DoubleType }, + /*UShortType*/new T[] { T.IntType , T.UShortType, T.UShortType, T.IntType , T.UShortType, T.IntType , T.UIntType , T.LongType , T.ULongType , T.FloatType , T.DoubleType }, + /*IntType */new T[] { T.IntType , T.IntType , T.IntType , T.IntType , T.IntType , T.IntType , T.LongType , T.LongType , T.LongType , T.FloatType , T.DoubleType }, + /*UIntType */new T[] { T.LongType , T.UIntType , T.LongType , T.LongType , T.UIntType , T.LongType , T.UIntType , T.LongType , T.ULongType , T.FloatType , T.DoubleType }, + /*LongType */new T[] { T.LongType , T.LongType , T.LongType , T.LongType , T.LongType , T.LongType , T.LongType , T.LongType , T.LongType , T.FloatType , T.DoubleType }, + /*ULongType */new T[] { T.LongType , T.ULongType , T.ULongType , T.LongType , T.ULongType , T.LongType , T.ULongType , T.LongType , T.ULongType , T.FloatType , T.DoubleType }, + /*FloatType */new T[] { T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.FloatType , T.DoubleType }, + /*DoubleType*/new T[] { T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType, T.DoubleType } + }; + + private T GetTypeEnum(object value) + { + return GetTypeEnum(value.GetType()); + } + + private T GetTypeEnum(Type type) + { + try + { + return typeEnums[type]; + } + catch + { + throw new NotSupportedException( + string.Format("Unsupported data type {0}.", type)); + } + } + + private Type GetType(T typeEnum) + { + switch(typeEnum) + { + case T.SByteType : return typeof(sbyte ); + case T.ByteType : return typeof(byte ); + case T.CharType : return typeof(char ); + case T.ShortType : return typeof(short ); + case T.UShortType: return typeof(ushort); + case T.IntType : return typeof(int ); + case T.UIntType : return typeof(uint ); + case T.LongType : return typeof(long ); + case T.ULongType : return typeof(ulong ); + case T.FloatType : return typeof(float ); + case T.DoubleType: return typeof(double); + default: + throw new NotSupportedException( + string.Format("Unsupported data type {0}.", typeEnum)); + } + } + + private object ConvertValue(object value, T targetTypeEnum) + { + switch(targetTypeEnum) + { + case T.SByteType : return Convert.ToSByte (value); + case T.ByteType : return Convert.ToByte (value); + case T.CharType : return Convert.ToChar (value); + case T.ShortType : return Convert.ToInt16 (value); + case T.UShortType: return Convert.ToUInt16(value); + case T.IntType : return Convert.ToInt32 (value); + case T.UIntType : return Convert.ToUInt32(value); + case T.LongType : return Convert.ToInt64 (value); + case T.ULongType : return Convert.ToUInt64(value); + case T.FloatType : return Convert.ToSingle(value); + case T.DoubleType: return Convert.ToDouble(value); + default: + throw new NotSupportedException( + string.Format("Unsupported data type {0}.", targetTypeEnum)); + } + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ArithmeticExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ArithmeticExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ArithmeticExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ArithmeticExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,57 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// An expression which performs an operation on two expression values. + /// </summary> + public abstract class ArithmeticExpression : BinaryExpression + { + public ArithmeticExpression(IExpression left, IExpression right) + : base(left, right) + { + } + + public static IExpression CreatePlus(IExpression left, IExpression right) + { + return new PlusExpression(left, right); + } + + public static IExpression CreateMinus(IExpression left, IExpression right) + { + return new MinusExpression(left, right); + } + + public static IExpression CreateMultiply(IExpression left, IExpression right) + { + return new MultiplyExpression(left, right); + } + + public static IExpression CreateDivide(IExpression left, IExpression right) + { + return new DivideExpression(left, right); + } + + public static IExpression CreateMod(IExpression left, IExpression right) + { + return new ModExpression(left, right); + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BinaryExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BinaryExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BinaryExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BinaryExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,59 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// An expression which performs an operation on two expression values. + /// </summary> + public abstract class BinaryExpression : IExpression + { + protected IExpression leftExpression; + public IExpression Left + { + get { return leftExpression; } + set { leftExpression = value; } + } + + protected IExpression rightExpression; + public IExpression Right + { + get { return rightExpression; } + set { rightExpression = value; } + } + + protected abstract string ExpressionSymbol + { + get; + } + + public BinaryExpression(IExpression left, IExpression right) + { + leftExpression = left; + rightExpression = right; + } + + public abstract object Evaluate(MessageEvaluationContext message); + + public override string ToString() + { + return "(" + leftExpression.ToString() + " " + ExpressionSymbol + " " + rightExpression.ToString() + ")"; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanCastExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanCastExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanCastExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanCastExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,45 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// An expression which casts an expression value to a boolean. + /// </summary> + public class BooleanCastExpression : BooleanUnaryExpression + { + protected override string ExpressionSymbol + { + get { return ""; } + } + + public BooleanCastExpression(IExpression left) + : base(left) + { + } + + public override object Evaluate(MessageEvaluationContext message) + { + object rvalue = Right.Evaluate(message); + if(rvalue == null ) return null; + if(rvalue is bool ) return (bool)rvalue; + return false; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanConstantExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanConstantExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanConstantExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanConstantExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,38 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// Represents a boolean constant expression. + /// </summary> + public class BooleanConstantExpression : ConstantExpression, IBooleanExpression + { + public BooleanConstantExpression(object value) + : base(value) + { + } + + public bool Matches(MessageEvaluationContext message) + { + object value = Evaluate(message); + return value != null && (bool)value; + } + } +} \ No newline at end of file Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanUnaryExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanUnaryExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanUnaryExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/BooleanUnaryExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,39 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// An expression which performs an operation on one expression value + /// and returns a boolean value. + /// </summary> + public abstract class BooleanUnaryExpression : UnaryExpression, IBooleanExpression + { + public BooleanUnaryExpression(IExpression left) + : base(left) + { + } + + public bool Matches(MessageEvaluationContext message) + { + object value = Evaluate(message); + return value != null && (bool)value; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ComparisonExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ComparisonExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ComparisonExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ComparisonExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,162 @@ +using System; +using System.Collections; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A filter performing a comparison of two or more expressions or objects. + /// </summary> + public abstract class ComparisonExpression : BinaryExpression, IBooleanExpression + { + public ComparisonExpression(IExpression left, IExpression right) + : base(left, right) + { + } + + public override object Evaluate(MessageEvaluationContext message) + { + object lvalue = Left.Evaluate(message); + object rvalue = Right.Evaluate(message); + + int? compared = null; + + if(lvalue == null || rvalue == null) + { + if(lvalue == null && rvalue == null) + { + compared = 0; + } + } + else + { + if(lvalue == rvalue) + { + compared = 0; + } + else if(lvalue is string && rvalue is string) + { + compared = ((string)lvalue).CompareTo(rvalue); + } + else + { + AlignedNumericValues values = new AlignedNumericValues(lvalue, rvalue); + + switch(values.TypeEnum) + { + case AlignedNumericValues.T.SByteType : compared = ((sbyte )values.Left).CompareTo((sbyte )values.Right); break; + case AlignedNumericValues.T.ByteType : compared = ((byte )values.Left).CompareTo((byte )values.Right); break; + case AlignedNumericValues.T.CharType : compared = ((char )values.Left).CompareTo((char )values.Right); break; + case AlignedNumericValues.T.ShortType : compared = ((short )values.Left).CompareTo((short )values.Right); break; + case AlignedNumericValues.T.UShortType: compared = ((ushort)values.Left).CompareTo((ushort)values.Right); break; + case AlignedNumericValues.T.IntType : compared = ((int )values.Left).CompareTo((int )values.Right); break; + case AlignedNumericValues.T.UIntType : compared = ((uint )values.Left).CompareTo((uint )values.Right); break; + case AlignedNumericValues.T.LongType : compared = ((long )values.Left).CompareTo((long )values.Right); break; + case AlignedNumericValues.T.ULongType : compared = ((ulong )values.Left).CompareTo((ulong )values.Right); break; + case AlignedNumericValues.T.FloatType : compared = ((float )values.Left).CompareTo((float )values.Right); break; + case AlignedNumericValues.T.DoubleType: compared = ((double)values.Left).CompareTo((double)values.Right); break; + } + } + } + + return AsBoolean(compared); + } + + public abstract bool AsBoolean(int? compared); + + public bool Matches(MessageEvaluationContext message) + { + object value = Evaluate(message); + return value != null && (bool)value; + } + + // Equality expressions + public static IBooleanExpression CreateEqual(IExpression left, IExpression right) + { + return new EqualExpression(left, right, true); + } + + public static IBooleanExpression CreateNotEqual(IExpression left, IExpression right) + { + return new EqualExpression(left, right, false); + } + + public static IBooleanExpression CreateIsNull(IExpression left) + { + return new IsNullExpression(left, true); + } + + public static IBooleanExpression CreateIsNotNull(IExpression left) + { + return new IsNullExpression(left, false); + } + + // Binary comparison expressions + public static IBooleanExpression CreateGreaterThan(IExpression left, IExpression right) + { + return new GreaterExpression(left, right); + } + + public static IBooleanExpression CreateGreaterThanOrEqual(IExpression left, IExpression right) + { + return new GreaterOrEqualExpression(left, right); + } + + public static IBooleanExpression CreateLesserThan(IExpression left, IExpression right) + { + return new LesserExpression(left, right); + } + + public static IBooleanExpression CreateLesserThanOrEqual(IExpression left, IExpression right) + { + return new LesserOrEqualExpression(left, right); + } + + // Other comparison expressions + public static IBooleanExpression CreateLike(IExpression left, string right, string escape) + { + return new LikeExpression(left, right, escape, true); + } + + public static IBooleanExpression CreateNotLike(IExpression left, string right, string escape) + { + return new LikeExpression(left, right, escape, false); + } + + public static IBooleanExpression CreateBetween(IExpression value, IExpression left, IExpression right) + { + return LogicExpression.CreateAND(CreateGreaterThanOrEqual(value, left), CreateLesserThanOrEqual(value, right)); + } + + public static IBooleanExpression CreateNotBetween(IExpression value, IExpression left, IExpression right) + { + return LogicExpression.CreateOR(CreateLesserThan(value, left), CreateGreaterThan(value, right)); + } + + public static IBooleanExpression CreateIn(IExpression left, ArrayList elements) + { + return new InExpression(left, elements, true); + } + + public static IBooleanExpression CreateNotIn(IExpression left, ArrayList elements) + { + return new InExpression(left, elements, false); + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ConstantExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ConstantExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ConstantExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/ConstantExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,157 @@ +using System; +using System.Text; +using System.Globalization; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// Represents a constant expression. + /// </summary> + public class ConstantExpression : IExpression + { + private object value; + public object Value + { + get { return value; } + } + + public ConstantExpression(object value) + { + this.value = value; + } + + public static ConstantExpression CreateFromDecimal(string text) + { + // Long integer specified ? + object value; + if(text.EndsWith("l") || text.EndsWith("L")) + { + text = text.Substring(0, text.Length - 1); + value = Int64.Parse(text, CultureInfo.InvariantCulture); + } + else + { + long lvalue = Int64.Parse(text, CultureInfo.InvariantCulture); + if(lvalue >= Int32.MinValue && lvalue <= Int32.MaxValue) + { + value = (int)lvalue; + } + else + { + value = lvalue; + } + } + return new ConstantExpression(value); + } + + public static ConstantExpression CreateFromHex(string text) + { + long lvalue = Convert.ToInt64(text.Substring(2), 16); + + object value; + if(lvalue >= Int32.MinValue && lvalue <= Int32.MaxValue) + { + value = (int)lvalue; + } + else + { + value = lvalue; + } + return new ConstantExpression(value); + } + + + public static ConstantExpression CreateFromOctal(string text) + { + long lvalue = Convert.ToInt64(text, 8); + + object value; + if(lvalue >= Int32.MinValue && lvalue <= Int32.MaxValue) + { + value = (int)lvalue; + } + else + { + value = lvalue; + } + return new ConstantExpression(value); + } + + public static ConstantExpression CreateFloat(string text) + { + double value = Double.Parse(text, CultureInfo.InvariantCulture); + return new ConstantExpression(value); + } + + public object Evaluate(MessageEvaluationContext message) + { + return value; + } + + public override string ToString() + { + if(value == null) + { + return "NULL"; + } + if(value is bool) + { + return (bool)value ? "TRUE" : "FALSE"; + } + if(value is string) + { + return EncodeString((string)value); + } + return value.ToString(); + } + + public override int GetHashCode() + { + return (value == null ? 0 : value.GetHashCode()); + } + + /// <summary> + /// Encodes the value of string so that it looks like it would look like + /// when it was provided in a selector. + /// </summary> + /// <param name="s">String to be encoded.</param> + /// <return>Encoded string.</return> + public static string EncodeString(string s) + { + StringBuilder b = new StringBuilder(); + b.Append('\''); + for(int c = 0; c < s.Length; c++) + { + char ch = s[c]; + if(ch == '\'') + { + b.Append(ch); + } + b.Append(ch); + } + b.Append('\''); + return b.ToString(); + } + + public static readonly BooleanConstantExpression NULL = new BooleanConstantExpression(null); + public static readonly BooleanConstantExpression TRUE = new BooleanConstantExpression(true); + public static readonly BooleanConstantExpression FALSE = new BooleanConstantExpression(false); + } +} \ No newline at end of file Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/DivideExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/DivideExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/DivideExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/DivideExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,67 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A filter performing a division of two expressions. + /// </summary> + public class DivideExpression : ArithmeticExpression + { + protected override string ExpressionSymbol + { + get { return "/"; } + } + + public DivideExpression(IExpression left, IExpression right) + : base(left, right) + { + } + + public override object Evaluate(MessageEvaluationContext message) + { + object lvalue = Left.Evaluate(message); + if(lvalue == null) return null; + + object rvalue = Right.Evaluate(message); + if(rvalue == null) return null; + + AlignedNumericValues values = new AlignedNumericValues(lvalue, rvalue); + + object result = null; + + switch(values.TypeEnum) + { + case AlignedNumericValues.T.SByteType : result = (sbyte )values.Left / (sbyte )values.Right; break; + case AlignedNumericValues.T.ByteType : result = (byte )values.Left / (byte )values.Right; break; + case AlignedNumericValues.T.CharType : result = (char )values.Left / (char )values.Right; break; + case AlignedNumericValues.T.ShortType : result = (short )values.Left / (short )values.Right; break; + case AlignedNumericValues.T.UShortType: result = (ushort)values.Left / (ushort)values.Right; break; + case AlignedNumericValues.T.IntType : result = (int )values.Left / (int )values.Right; break; + case AlignedNumericValues.T.UIntType : result = (uint )values.Left / (uint )values.Right; break; + case AlignedNumericValues.T.LongType : result = (long )values.Left / (long )values.Right; break; + case AlignedNumericValues.T.ULongType : result = (ulong )values.Left / (ulong )values.Right; break; + case AlignedNumericValues.T.FloatType : result = (float )values.Left / (float )values.Right; break; + case AlignedNumericValues.T.DoubleType: result = (double)values.Left / (double)values.Right; break; + } + + return result; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/EqualExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/EqualExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/EqualExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/EqualExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,47 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A filter performing an equality or inequality comparison + /// of two expressions. + /// </summary> + public class EqualExpression : ComparisonExpression + { + private bool notNot; + + protected override string ExpressionSymbol + { + get { return notNot ? "=" : "<>"; } + } + + public EqualExpression(IExpression left, IExpression right, bool notNot) + : base(left, right) + { + this.notNot = notNot; + } + + public override bool AsBoolean(int? compared) + { + bool answer = (compared.HasValue ? compared.Value == 0 : false); + return notNot ? answer : !answer; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/GreaterExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/GreaterExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/GreaterExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/GreaterExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,42 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A filter performing a greater than comparison of two expressions. + /// </summary> + public class GreaterExpression : ComparisonExpression + { + protected override string ExpressionSymbol + { + get { return ">"; } + } + + public GreaterExpression(IExpression left, IExpression right) + : base(left, right) + { + } + + public override bool AsBoolean(int? compared) + { + return compared.HasValue ? compared.Value > 0 : false; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/GreaterOrEqualExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/GreaterOrEqualExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/GreaterOrEqualExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/GreaterOrEqualExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,43 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A filter performing a greater than or equal comparison + /// of two expressions. + /// </summary> + public class GreaterOrEqualExpression : ComparisonExpression + { + protected override string ExpressionSymbol + { + get { return ">="; } + } + + public GreaterOrEqualExpression(IExpression left, IExpression right) + : base(left, right) + { + } + + public override bool AsBoolean(int? compared) + { + return compared.HasValue ? compared.Value >= 0 : false; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IBooleanExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IBooleanExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IBooleanExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IBooleanExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,35 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// An IBooleanExpression is an expression that always + /// produces a boolean result. + /// </summary> + public interface IBooleanExpression : IExpression + { + /// <summary> + /// Checks if expression evaluates to <c>true</c>. + /// </summary> + /// <param name="message">Evaluation context.</param> + /// <return><c>true</c> if the expression evaluates to <c>true</c>.</return> + bool Matches(MessageEvaluationContext message); + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,35 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// Represents an expression + /// </summary> + public interface IExpression + { + /// <summary> + /// Evaluates the expression. + /// </summary> + /// <param name="message">Evaluation context.</param> + /// <return>The result of the evaluation.</return> + object Evaluate(MessageEvaluationContext message); + } +} + \ No newline at end of file Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/InExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/InExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/InExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/InExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,98 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A boolean expression which checks if an expression value is + /// contained in a list of defined values. + /// </summary> + public class InExpression : BooleanUnaryExpression + { + private bool notNot; + private ArrayList elements; + private HashSet<string> hashset; + + protected override string ExpressionSymbol + { + get { return notNot ? "IN" : "NOT IN"; } + } + + public InExpression(IExpression right, ArrayList elements, bool notNot) + : base(right) + { + this.notNot = notNot; + + this.elements = elements; + this.hashset = new HashSet<string>(); + + foreach(object element in elements) + { + hashset.Add((string)element); + } + } + + public override object Evaluate(MessageEvaluationContext message) + { + object rvalue = Right.Evaluate(message); + + bool answer = false; + if(rvalue != null && (rvalue is string)) + { + answer = hashset.Contains((string)rvalue); + } + + return notNot ? answer : !answer; + } + + public override string ToString() + { + StringBuilder answer = new StringBuilder(); + answer.Append(Right); + answer.Append(" "); + answer.Append(ExpressionSymbol); + answer.Append(" ("); + + for(int i = 0; i < elements.Count; i++) + { + if(i > 0) answer.Append(", "); + + string s = (string)elements[i]; + + answer.Append('\''); + for(int c = 0; c < s.Length; c++) + { + char ch = s[c]; + if(ch == '\'') + { + answer.Append(ch); + } + answer.Append(ch); + } + answer.Append('\''); + } + + answer.Append(")"); + return answer.ToString(); + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IsNullExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IsNullExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IsNullExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/IsNullExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,59 @@ +using System; +using System.Text; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A boolean expression which checks if an expression value is null. + /// </summary> + public class IsNullExpression : BooleanUnaryExpression + { + private bool notNot; + + protected override string ExpressionSymbol + { + get { return notNot ? "IS NULL" : "IS NOT NULL"; } + } + + public IsNullExpression(IExpression right, bool notNot) + : base(right) + { + this.notNot = notNot; + } + + public override object Evaluate(MessageEvaluationContext message) + { + object rvalue = Right.Evaluate(message); + + bool answer = (rvalue == null || rvalue == ConstantExpression.NULL); + + return notNot ? answer : !answer; + } + + public override string ToString() + { + StringBuilder answer = new StringBuilder(); + answer.Append(Right); + answer.Append(" "); + answer.Append(ExpressionSymbol); + return answer.ToString(); + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LesserExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LesserExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LesserExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LesserExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,42 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A filter performing a lesser than comparison of two expressions. + /// </summary> + public class LesserExpression : ComparisonExpression + { + protected override string ExpressionSymbol + { + get { return "<"; } + } + + public LesserExpression(IExpression left, IExpression right) + : base(left, right) + { + } + + public override bool AsBoolean(int? compared) + { + return compared.HasValue ? compared.Value < 0 : false; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LesserOrEqualExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LesserOrEqualExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LesserOrEqualExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LesserOrEqualExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,43 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A filter performing a lesser than or equal comparison + /// of two expressions. + /// </summary> + public class LesserOrEqualExpression : ComparisonExpression + { + protected override string ExpressionSymbol + { + get { return "<="; } + } + + public LesserOrEqualExpression(IExpression left, IExpression right) + : base(left, right) + { + } + + public override bool AsBoolean(int? compared) + { + return compared.HasValue ? compared.Value <= 0 : false; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LikeExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LikeExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LikeExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LikeExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,124 @@ +using System; +using System.Text; +using System.Text.RegularExpressions; +using System.Globalization; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A filter performing a string matching comparison. + /// </summary> + public class LikeExpression : BooleanUnaryExpression + { + private bool notNot; + private Regex pattern; + + protected override string ExpressionSymbol + { + get { return notNot ? "LIKE" : "NOT LIKE"; } + } + + public LikeExpression(IExpression left, string like, string escape, bool notNot) + : base(left) + { + this.notNot = notNot; + + bool doEscape = false; + char escapeChar = '%'; + + if(escape != null) + { + if(escape.Length != 1) + { + throw new ApplicationException("The ESCAPE string litteral is invalid. It can only be one character. Litteral used: " + escape); + } + doEscape = true; + escapeChar = escape[0]; + } + + StringBuilder temp = new StringBuilder(); + StringBuilder regexp = new StringBuilder(like.Length * 2); + regexp.Append("^"); // The beginning of the input + for(int c = 0; c < like.Length; c++) + { + char ch = like[c]; + if(doEscape && (ch == escapeChar)) + { + c++; + if(c >= like.Length) + { + // nothing left to escape... + break; + } + temp.Append(like[c]); + } + else if(ch == '%') + { + if(temp.Length > 0) + { + regexp.Append(Regex.Escape(temp.ToString())); + temp.Length = 0; + } + regexp.Append(".*?"); // Do a non-greedy match + } + else if(c == '_') + { + if(temp.Length > 0) + { + regexp.Append(Regex.Escape(temp.ToString())); + temp.Length = 0; + } + regexp.Append("."); // match one + } + else + { + temp.Append(ch); + } + } + if(temp.Length > 0) + { + regexp.Append(Regex.Escape(temp.ToString())); + } + regexp.Append("$"); // The end of the input + + pattern = new Regex(regexp.ToString(), RegexOptions.Singleline | RegexOptions.Compiled); + } + + public override object Evaluate(MessageEvaluationContext message) + { + object rvalue = this.Right.Evaluate(message); + + bool answer = false; + if(rvalue != null) + { + if(rvalue is string) + { + answer = pattern.IsMatch((string)rvalue); + } + else + { + //throw new ApplicationException("LIKE can only operate on string identifiers. LIKE attemped on " + rvalue.GetType().ToString()); + } + } + + return notNot ? answer : !answer; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LogicExpression.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LogicExpression.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LogicExpression.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/LogicExpression.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,48 @@ +using System; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// A filter performing a logical combination of two objects. + /// </summary> + public abstract class LogicExpression : BinaryExpression, IBooleanExpression + { + public LogicExpression(IBooleanExpression left, IBooleanExpression right) + : base(left, right) + { + } + + public bool Matches(MessageEvaluationContext message) + { + object value = Evaluate(message); + return value != null && (bool)value; + } + + public static IBooleanExpression CreateOR(IBooleanExpression left, IBooleanExpression right) + { + return new ORExpression(left, right); + } + + public static IBooleanExpression CreateAND(IBooleanExpression left, IBooleanExpression right) + { + return new ANDExpression(left, right); + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/MessageEvaluationContext.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/MessageEvaluationContext.cs?rev=1751831&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/MessageEvaluationContext.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.MSMQ/trunk/src/main/csharp/Selector/MessageEvaluationContext.cs Thu Jul 7 20:47:10 2016 @@ -0,0 +1,78 @@ +using System; +using Apache.NMS; +/** + * + * 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.NMS.Selector +{ + /// <summary> + /// MessageEvaluationContext is used to cache selection results. + /// + /// A message usually has multiple selectors applied against it. Some selector + /// have a high cost of evaluating against the message. Those selectors may whish + /// to cache evaluation results associated with the message in the + /// MessageEvaluationContext. + /// </summary> + public class MessageEvaluationContext + { + private IMessage nmsMessage; + public IMessage Message + { + get { return nmsMessage; } + set { nmsMessage = value; } + } + + public MessageEvaluationContext(IMessage message) + { + nmsMessage = message; + } + + public object GetProperty(string name) + { + if(name.Length > 3 && + string.Compare(name.Substring(0, 3), "JMS", true) == 0) + { + if(string.Compare(name, "JMSCorrelationID", true) == 0) + { + return nmsMessage.NMSCorrelationID; + } + if(string.Compare(name, "JMSMessageID", true) == 0) + { + return nmsMessage.NMSMessageId; + } + if(string.Compare(name, "JMSPriority", true) == 0) + { + return nmsMessage.NMSPriority; + } + if(string.Compare(name, "JMSTimestamp", true) == 0) + { + return nmsMessage.NMSTimestamp; + } + if(string.Compare(name, "JMSType", true) == 0) + { + return nmsMessage.NMSType; + } + if(string.Compare(name, "JMSDeliveryMode", true) == 0) + { + return nmsMessage.NMSDeliveryMode; + } + } + return nmsMessage.Properties[name]; + } + } +} \ No newline at end of file