Apply patch for AMQNET-556 from Stephane Ramet. Thanks Stephane!
diff --git a/Apache.NMS.MSMQ.Test.nunit b/Apache.NMS.MSMQ.Test.nunit
index b321b9d..4dc9dc2 100644
--- a/Apache.NMS.MSMQ.Test.nunit
+++ b/Apache.NMS.MSMQ.Test.nunit
@@ -1,7 +1,7 @@
-<NUnitProject>
- <Settings activeconfig="Default" />
- <Config name="Default" binpathtype="Auto">
- <assembly path="Apache.NMS.Test.dll" />
- <assembly path="Apache.NMS.MSMQ.Test.dll" />
- </Config>
+<NUnitProject>
+ <Settings activeconfig="Default" />
+ <Config name="Default" binpathtype="Auto">
+ <!--<assembly path="Apache.NMS.Test.dll" />-->
+ <assembly path="Apache.NMS.MSMQ.Test.dll" />
+ </Config>
</NUnitProject>
\ No newline at end of file
diff --git a/msmqprovider-test.config b/msmqprovider-test.config
new file mode 100644
index 0000000..65e5dff
--- /dev/null
+++ b/msmqprovider-test.config
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+* 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.
+-->
+<configuration>
+ <testURI value="msmq://localhost">
+ <userName value="guest"/>
+ <passWord value="guest"/>
+ <defaultTestQueue value="queue://.\Private$\TestQ"/>
+ <defaultTestTopic value=""/>
+ <defaultTestQueue2 value="queue://.\Private$\TestQ2"/>
+ <defaultTestTopic2 value=""/>
+ <durableConsumerTestTopic value=""/>
+ <messageSelectorTestQueue value="queue://.\Private$\TestQ"/>
+ <messageSelectorTestTopic value=""/>
+ <deletionTestQueue value="queue://.\Private$\TestQ"/>
+ <deletionTestTopic value=""/>
+ <deletionTestTempQueue value=""/>
+ <deletionTestTempTopic value=""/>
+ <transactionTestQueue value="queue://.\Private$\TestQT"/>
+ </testURI>
+</configuration>
diff --git a/nant.build b/nant.build
index 0df9a29..67d0fa0 100644
--- a/nant.build
+++ b/nant.build
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@@ -31,8 +31,6 @@
<property name="nunit.dll" value="${basedir}/lib/NUnit/${current.build.framework}/nunit.framework.dll" dynamic="true" />
<property name="Apache.NMS.dll" value="${basedir}/lib/Apache.NMS/${current.build.framework}/Apache.NMS.dll" dynamic="true" />
<property name="Apache.NMS.pdb" value="${basedir}/lib/Apache.NMS/${current.build.framework}/Apache.NMS.pdb" dynamic="true" />
- <property name="Apache.NMS.Test.dll" value="${basedir}/lib/Apache.NMS/${current.build.framework}//Apache.NMS.Test.dll" dynamic="true" />
- <property name="Apache.NMS.Test.pdb" value="${basedir}/lib/Apache.NMS/${current.build.framework}/Apache.NMS.Test.pdb" dynamic="true" />
<property name="NUnit.Projectfile" value="Apache.NMS.MSMQ.Test.nunit" />
<!-- Skip certain frameworks, since MSMQ is not supported on those platforms. -->
@@ -77,7 +75,6 @@
<include name="${current.build.framework.assembly.dir}/System.Xml.dll" />
<include name="${current.build.framework.assembly.dir}/System.Messaging.dll" />
<include name="${Apache.NMS.dll}" />
- <include name="${Apache.NMS.Test.dll}" />
<include name="${build.bin.dir}/${project.name}.dll" />
<include name="${nunit.dll}" />
</assemblyfileset>
@@ -88,8 +85,6 @@
<include name="nmsprovider-*.config" />
<include name="${Apache.NMS.dll}" />
<include name="${Apache.NMS.pdb}" />
- <include name="${Apache.NMS.Test.dll}" />
- <include name="${Apache.NMS.Test.pdb}" />
<include name="${nunit.dll}" />
<include name="${NUnit.Projectfile}" />
</fileset>
diff --git a/src/main/csharp/Connection.cs b/src/main/csharp/Connection.cs
index 9207708..5df73f4 100644
--- a/src/main/csharp/Connection.cs
+++ b/src/main/csharp/Connection.cs
@@ -16,6 +16,7 @@
*/
using System;
+using System.Threading;
namespace Apache.NMS.MSMQ
{
@@ -26,21 +27,101 @@
///
public class Connection : IConnection
{
- private AcknowledgementMode acknowledgementMode = AcknowledgementMode.AutoAcknowledge;
- private IMessageConverter messageConverter = new DefaultMessageConverter();
+ #region Constructors
- private IRedeliveryPolicy redeliveryPolicy;
- private ConnectionMetaData metaData = null;
- private bool connected;
- private bool closed;
- private string clientId;
+ public Connection()
+ {
+ // now lets send the connection and see if we get an ack/nak
+ // TODO: establish a connection
+ }
+
+ #endregion
+
+ #region Connection state
+
+ public enum ConnectionState
+ {
+ Created,
+ Connected,
+ Starting,
+ Started,
+ Stopping,
+ Stopped,
+ Closed
+ }
+
+ private ConnectionState state = ConnectionState.Created;
+
+ public class StateChangeEventArgs : EventArgs
+ {
+ public StateChangeEventArgs(ConnectionState originalState,
+ ConnectionState currentState)
+ {
+ this.originalState = originalState;
+ this.currentState = currentState;
+ }
+
+ private ConnectionState originalState;
+ public ConnectionState OriginalState
+ {
+ get { return originalState; }
+ }
+
+ private ConnectionState currentState;
+ public ConnectionState CurrentState
+ {
+ get { return currentState; }
+ }
+ }
+
+ public delegate void StateChangeEventHandler(object sender, StateChangeEventArgs e);
+
+ public event StateChangeEventHandler ConnectionStateChange;
+
+ private void ChangeState(ConnectionState newState)
+ {
+ if(ConnectionStateChange != null)
+ {
+ ConnectionStateChange(this,
+ new StateChangeEventArgs(this.state, newState));
+ }
+
+ this.state = newState;
+ }
+
+ private object stateLock = new object();
+
+ #endregion
+
+ #region Start & stop
/// <summary>
/// Starts message delivery for this connection.
/// </summary>
public void Start()
{
- CheckConnected();
+ lock(stateLock)
+ {
+ switch(state)
+ {
+ case ConnectionState.Created:
+ case ConnectionState.Connected:
+ case ConnectionState.Stopped:
+ ChangeState(ConnectionState.Starting);
+ ChangeState(ConnectionState.Started);
+ break;
+
+ case ConnectionState.Stopping:
+ throw new NMSException("Connection stopping");
+
+ case ConnectionState.Closed:
+ throw new NMSException("Connection closed");
+
+ case ConnectionState.Starting:
+ case ConnectionState.Started:
+ break;
+ }
+ }
}
/// <summary>
@@ -49,7 +130,7 @@
/// </summary>
public bool IsStarted
{
- get { return true; }
+ get { return state == ConnectionState.Started; }
}
/// <summary>
@@ -57,9 +138,65 @@
/// </summary>
public void Stop()
{
- CheckConnected();
+ lock(stateLock)
+ {
+ switch(state)
+ {
+ case ConnectionState.Started:
+ ChangeState(ConnectionState.Stopping);
+ ChangeState(ConnectionState.Stopped);
+ break;
+
+ case ConnectionState.Starting:
+ throw new NMSException("Connection starting");
+
+ case ConnectionState.Closed:
+ throw new NMSException("Connection closed");
+
+ case ConnectionState.Created:
+ case ConnectionState.Connected:
+ case ConnectionState.Stopping:
+ case ConnectionState.Stopped:
+ break;
+ }
+ }
}
+ #endregion
+
+ #region Close & dispose
+
+ public void Close()
+ {
+ if(!IsClosed)
+ {
+ Stop();
+
+ state = ConnectionState.Closed;
+ }
+ }
+
+ public bool IsClosed
+ {
+ get { return state == ConnectionState.Closed; }
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ Close();
+ }
+ catch
+ {
+ state = ConnectionState.Closed;
+ }
+ }
+
+ #endregion
+
+ #region Create session
+
/// <summary>
/// Creates a new session to work on this connection
/// </summary>
@@ -73,14 +210,16 @@
/// </summary>
public ISession CreateSession(AcknowledgementMode mode)
{
- CheckConnected();
+ if(IsClosed)
+ {
+ throw new NMSException("Connection closed");
+ }
return new Session(this, mode);
}
- public void Dispose()
- {
- closed = true;
- }
+ #endregion
+
+ #region Connection properties
/// <summary>
/// The default timeout for network requests.
@@ -91,24 +230,27 @@
set { }
}
+ private AcknowledgementMode acknowledgementMode = AcknowledgementMode.AutoAcknowledge;
public AcknowledgementMode AcknowledgementMode
{
get { return acknowledgementMode; }
set { acknowledgementMode = value; }
}
+ private IMessageConverter messageConverter = new DefaultMessageConverter();
public IMessageConverter MessageConverter
{
get { return messageConverter; }
set { messageConverter = value; }
}
+ private string clientId;
public string ClientId
{
get { return clientId; }
set
{
- if(connected)
+ if(state != ConnectionState.Created)
{
throw new NMSException("You cannot change the ClientId once the Connection is connected");
}
@@ -116,6 +258,7 @@
}
}
+ private IRedeliveryPolicy redeliveryPolicy;
/// <summary>
/// Get/or set the redelivery policy for this connection.
/// </summary>
@@ -125,6 +268,19 @@
set { this.redeliveryPolicy = value; }
}
+ private ConnectionMetaData metaData = null;
+ /// <summary>
+ /// Gets the Meta Data for the NMS Connection instance.
+ /// </summary>
+ public IConnectionMetaData MetaData
+ {
+ get { return this.metaData ?? (this.metaData = new ConnectionMetaData()); }
+ }
+
+ #endregion
+
+ #region Transformer delegates
+
private ConsumerTransformerDelegate consumerTransformer;
public ConsumerTransformerDelegate ConsumerTransformer
{
@@ -139,57 +295,18 @@
set { this.producerTransformer = value; }
}
- /// <summary>
- /// Gets the Meta Data for the NMS Connection instance.
- /// </summary>
- public IConnectionMetaData MetaData
- {
- get { return this.metaData ?? (this.metaData = new ConnectionMetaData()); }
- }
+ #endregion
+
+ #region Exception & transport listeners
/// <summary>
/// A delegate that can receive transport level exceptions.
/// </summary>
public event ExceptionListener ExceptionListener;
- /// <summary>
- /// An asynchronous listener that is notified when a Fault tolerant connection
- /// has been interrupted.
- /// </summary>
- public event ConnectionInterruptedListener ConnectionInterruptedListener;
-
- /// <summary>
- /// An asynchronous listener that is notified when a Fault tolerant connection
- /// has been resumed.
- /// </summary>
- public event ConnectionResumedListener ConnectionResumedListener;
-
- protected void CheckConnected()
- {
- if(closed)
- {
- throw new NMSException("Connection Closed");
- }
- if(!connected)
- {
- connected = true;
- // now lets send the connection and see if we get an ack/nak
- // TODO: establish a connection
- }
- }
-
- public void Close()
- {
- Dispose();
- }
-
- public void PurgeTempDestinations()
- {
- }
-
public void HandleException(Exception e)
{
- if(ExceptionListener != null && !this.closed)
+ if(ExceptionListener != null && !this.IsClosed)
{
ExceptionListener(e);
}
@@ -199,11 +316,17 @@
}
}
+ /// <summary>
+ /// An asynchronous listener that is notified when a Fault tolerant connection
+ /// has been interrupted.
+ /// </summary>
+ public event ConnectionInterruptedListener ConnectionInterruptedListener;
+
public void HandleTransportInterrupted()
{
Tracer.Debug("Transport has been Interrupted.");
- if(this.ConnectionInterruptedListener != null && !this.closed)
+ if(this.ConnectionInterruptedListener != null && !this.IsClosed)
{
try
{
@@ -215,11 +338,17 @@
}
}
+ /// <summary>
+ /// An asynchronous listener that is notified when a Fault tolerant connection
+ /// has been resumed.
+ /// </summary>
+ public event ConnectionResumedListener ConnectionResumedListener;
+
public void HandleTransportResumed()
{
Tracer.Debug("Transport has resumed normal operation.");
- if(this.ConnectionResumedListener != null && !this.closed)
+ if(this.ConnectionResumedListener != null && !this.IsClosed)
{
try
{
@@ -230,5 +359,11 @@
}
}
}
+
+ #endregion
+
+ public void PurgeTempDestinations()
+ {
+ }
}
}
diff --git a/src/main/csharp/ConnectionMetaData.cs b/src/main/csharp/ConnectionMetaData.cs
index 5a305c0..9bba3b6 100644
--- a/src/main/csharp/ConnectionMetaData.cs
+++ b/src/main/csharp/ConnectionMetaData.cs
@@ -1,107 +1,107 @@
-/*
- * 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.
- */
-
-using System;
-using System.Reflection;
-
-namespace Apache.NMS.MSMQ
-{
- /// <summary>
- /// Implements the Connection Meta-Data feature for Apache.NMS.MSMQ
- /// </summary>
- public class ConnectionMetaData : IConnectionMetaData
- {
- private int nmsMajorVersion;
- private int nmsMinorVersion;
-
- private string nmsProviderName;
- private string nmsVersion;
-
- private int providerMajorVersion;
- private int providerMinorVersion;
- private string providerVersion;
-
- private string[] nmsxProperties;
-
- public ConnectionMetaData()
- {
- Assembly self = Assembly.GetExecutingAssembly();
- AssemblyName asmName = self.GetName();
-
- this.nmsProviderName = asmName.Name;
- this.providerMajorVersion = asmName.Version.Major;
- this.providerMinorVersion = asmName.Version.Minor;
- this.providerVersion = asmName.Version.ToString();
-
- this.nmsxProperties = new String[] { };
-
- foreach(AssemblyName name in self.GetReferencedAssemblies())
- {
- if(0 == string.Compare(name.Name, "Apache.NMS", true))
- {
- this.nmsMajorVersion = name.Version.Major;
- this.nmsMinorVersion = name.Version.Minor;
- this.nmsVersion = name.Version.ToString();
-
- return;
- }
- }
-
- throw new NMSException("Could not find a reference to the Apache.NMS Assembly.");
- }
-
- public int NMSMajorVersion
- {
- get { return this.nmsMajorVersion; }
- }
-
- public int NMSMinorVersion
- {
- get { return this.nmsMinorVersion; }
- }
-
- public string NMSProviderName
- {
- get { return this.nmsProviderName; }
- }
-
- public string NMSVersion
- {
- get { return this.nmsVersion; }
- }
-
- public string[] NMSXPropertyNames
- {
- get { return this.nmsxProperties; }
- }
-
- public int ProviderMajorVersion
- {
- get { return this.providerMajorVersion; }
- }
-
- public int ProviderMinorVersion
- {
- get { return this.providerMinorVersion; }
- }
-
- public string ProviderVersion
- {
- get { return this.providerVersion; }
- }
- }
-}
+/*
+ * 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.
+ */
+
+using System;
+using System.Reflection;
+
+namespace Apache.NMS.MSMQ
+{
+ /// <summary>
+ /// Implements the Connection Meta-Data feature for Apache.NMS.MSMQ
+ /// </summary>
+ public class ConnectionMetaData : IConnectionMetaData
+ {
+ private int nmsMajorVersion;
+ private int nmsMinorVersion;
+
+ private string nmsProviderName;
+ private string nmsVersion;
+
+ private int providerMajorVersion;
+ private int providerMinorVersion;
+ private string providerVersion;
+
+ private string[] nmsxProperties;
+
+ public ConnectionMetaData()
+ {
+ Assembly self = Assembly.GetExecutingAssembly();
+ AssemblyName asmName = self.GetName();
+
+ this.nmsProviderName = asmName.Name;
+ this.providerMajorVersion = asmName.Version.Major;
+ this.providerMinorVersion = asmName.Version.Minor;
+ this.providerVersion = asmName.Version.ToString();
+
+ this.nmsxProperties = new String[] { };
+
+ foreach(AssemblyName name in self.GetReferencedAssemblies())
+ {
+ if(0 == string.Compare(name.Name, "Apache.NMS", true))
+ {
+ this.nmsMajorVersion = name.Version.Major;
+ this.nmsMinorVersion = name.Version.Minor;
+ this.nmsVersion = name.Version.ToString();
+
+ return;
+ }
+ }
+
+ throw new NMSException("Could not find a reference to the Apache.NMS Assembly.");
+ }
+
+ public int NMSMajorVersion
+ {
+ get { return this.nmsMajorVersion; }
+ }
+
+ public int NMSMinorVersion
+ {
+ get { return this.nmsMinorVersion; }
+ }
+
+ public string NMSProviderName
+ {
+ get { return this.nmsProviderName; }
+ }
+
+ public string NMSVersion
+ {
+ get { return this.nmsVersion; }
+ }
+
+ public string[] NMSXPropertyNames
+ {
+ get { return this.nmsxProperties; }
+ }
+
+ public int ProviderMajorVersion
+ {
+ get { return this.providerMajorVersion; }
+ }
+
+ public int ProviderMinorVersion
+ {
+ get { return this.providerMinorVersion; }
+ }
+
+ public string ProviderVersion
+ {
+ get { return this.providerVersion; }
+ }
+ }
+}
diff --git a/src/main/csharp/DefaultMessageConverter.cs b/src/main/csharp/DefaultMessageConverter.cs
index 83097fc..b726474 100644
--- a/src/main/csharp/DefaultMessageConverter.cs
+++ b/src/main/csharp/DefaultMessageConverter.cs
@@ -118,16 +118,16 @@
// Populate property data
foreach(object keyObject in message.Properties.Keys)
{
- string key = (keyObject as string);
- object val = message.Properties.GetString(key);
- if(!SetLabelAsNMSType && string.Compare(key, "Label", true) == 0 && val != null)
- {
- msmqMessage.Label = val.ToString();
- }
- else
- {
- propertyData[key] = val;
- }
+ string key = (keyObject as string);
+ object val = message.Properties[key];
+ if(!SetLabelAsNMSType && string.Compare(key, "Label", true) == 0 && val != null)
+ {
+ msmqMessage.Label = val.ToString();
+ }
+ else
+ {
+ propertyData[key] = val;
+ }
}
// Store the NMS property data in the extension area
@@ -418,6 +418,8 @@
result = baseMessage;
}
+ result.ReadOnlyBody = true;
+
return result;
}
@@ -442,6 +444,7 @@
else if(message is BytesMessage)
{
BytesMessage bytesMessage = message as BytesMessage;
+ bytesMessage.Reset();
answer.BodyStream.Write(bytesMessage.Content, 0, bytesMessage.Content.Length);
answer.AppSpecific = (int) NMSMessageType.BytesMessage;
}
@@ -604,12 +607,14 @@
/// <result>MSMQ queue.</result>
public MessageQueue ToMsmqDestination(IDestination destination)
{
- if(null == destination)
+ Queue queue = destination as Queue;
+
+ if(destination == null)
{
return null;
}
- return new MessageQueue((destination as Destination).Path);
+ return queue.MSMQMessageQueue;
}
/// <summary>
@@ -625,7 +630,7 @@
return null;
}
- return new Queue(destinationQueue.Path);
+ return new Queue(destinationQueue);
}
#endregion
diff --git a/src/main/csharp/IMessageConverterEx.cs b/src/main/csharp/IMessageConverterEx.cs
index 92be928..fcd1354 100644
--- a/src/main/csharp/IMessageConverterEx.cs
+++ b/src/main/csharp/IMessageConverterEx.cs
@@ -1,44 +1,44 @@
-using System.Messaging;
-/*
- * 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
-{
- /// <summary>
- /// Extended IMessageConverter interface supporting new methods for
- /// optimizing message selection through "selectors".
- /// The original IMessageConverter is maintained for compatibility
- /// reasons with existing clients implementing it.
- /// </summary>
- public interface IMessageConverterEx : IMessageConverter
- {
- /// <summary>
- /// Converts the specified MSMQ message to an equivalent NMS message.
- /// </summary>
- /// <param name="message">MSMQ message to be converted.</param>
- /// <param name="convertBody">true if message body should be converted.</param>
- /// <result>Converted NMS message.</result>
- IMessage ToNmsMessage(Message message, bool convertBody);
-
- /// <summary>
- /// Converts an MSMQ message body to the equivalent NMS message body.
- /// </summary>
- /// <param name="message">Source MSMQ message.</param>
- /// <param name="answer">Target NMS message.</param>
- void ConvertMessageBodyToNMS(Message message, IMessage answer);
- }
-}
+using System.Messaging;
+/*
+ * 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
+{
+ /// <summary>
+ /// Extended IMessageConverter interface supporting new methods for
+ /// optimizing message selection through "selectors".
+ /// The original IMessageConverter is maintained for compatibility
+ /// reasons with existing clients implementing it.
+ /// </summary>
+ public interface IMessageConverterEx : IMessageConverter
+ {
+ /// <summary>
+ /// Converts the specified MSMQ message to an equivalent NMS message.
+ /// </summary>
+ /// <param name="message">MSMQ message to be converted.</param>
+ /// <param name="convertBody">true if message body should be converted.</param>
+ /// <result>Converted NMS message.</result>
+ IMessage ToNmsMessage(Message message, bool convertBody);
+
+ /// <summary>
+ /// Converts an MSMQ message body to the equivalent NMS message body.
+ /// </summary>
+ /// <param name="message">Source MSMQ message.</param>
+ /// <param name="answer">Target NMS message.</param>
+ void ConvertMessageBodyToNMS(Message message, IMessage answer);
+ }
+}
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index eaaed5c..c69c6f5 100644
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -32,9 +32,6 @@
private readonly Session session;
private readonly AcknowledgementMode acknowledgementMode;
private MessageQueue messageQueue;
- private Thread asyncDeliveryThread = null;
- private AutoResetEvent pause = new AutoResetEvent(false);
- private Atomic<bool> asyncDelivery = new Atomic<bool>(false);
private ConsumerTransformerDelegate consumerTransformer;
public ConsumerTransformerDelegate ConsumerTransformer
@@ -81,6 +78,8 @@
messageQueue, session.MessageConverter, selector);
}
+ #region Asynchronous delivery
+
private int listenerCount = 0;
private event MessageListener listener;
public event MessageListener Listener
@@ -89,7 +88,13 @@
{
listener += value;
listenerCount++;
- StartAsyncDelivery();
+
+ session.Connection.ConnectionStateChange += OnConnectionStateChange;
+
+ if(session.Connection.IsStarted)
+ {
+ StartAsyncDelivery();
+ }
}
remove
@@ -100,13 +105,112 @@
listenerCount--;
}
- if(0 == listenerCount)
+ if(listenerCount == 0)
+ {
+ session.Connection.ConnectionStateChange -= OnConnectionStateChange;
+
+ StopAsyncDelivery();
+ }
+ }
+ }
+
+ private void OnConnectionStateChange(object sender, Connection.StateChangeEventArgs e)
+ {
+ if(e.CurrentState == Connection.ConnectionState.Starting)
+ {
+ if(listenerCount > 0)
+ {
+ StartAsyncDelivery();
+ }
+ }
+ else if(e.CurrentState == Connection.ConnectionState.Stopping)
+ {
+ if(listenerCount > 0)
{
StopAsyncDelivery();
}
}
}
+ private Thread asyncDeliveryThread = null;
+ private Atomic<bool> asyncDelivery = new Atomic<bool>(false);
+ TimeSpan dispatchingTimeout = new TimeSpan(5000);
+
+ protected virtual void StartAsyncDelivery()
+ {
+ if(asyncDelivery.CompareAndSet(false, true))
+ {
+ asyncDeliveryThread = new Thread(new ThreadStart(DispatchLoop));
+ asyncDeliveryThread.Name = "Message Consumer Dispatch: " + messageQueue.QueueName;
+ asyncDeliveryThread.IsBackground = true;
+ asyncDeliveryThread.Start();
+ }
+ }
+
+ protected virtual void DispatchLoop()
+ {
+ Tracer.Info("Starting dispatcher thread consumer: " + this);
+ while(asyncDelivery.Value)
+ {
+ try
+ {
+ IMessage message = Receive(dispatchingTimeout);
+ if(asyncDelivery.Value && message != null)
+ {
+ try
+ {
+ listener(message);
+ }
+ catch(Exception e)
+ {
+ HandleAsyncException(e);
+ }
+ }
+ }
+ catch(ThreadAbortException ex)
+ {
+ Tracer.InfoFormat("Thread abort received in thread: {0} : {1}", this, ex.Message);
+
+ break;
+ }
+ catch(Exception ex)
+ {
+ Tracer.ErrorFormat("Exception while receiving message in thread: {0} : {1}", this, ex.Message);
+ }
+ }
+ Tracer.Info("Stopping dispatcher thread consumer: " + this);
+ }
+
+ protected virtual void StopAsyncDelivery()
+ {
+ if(asyncDelivery.CompareAndSet(true, false))
+ {
+ if(null != asyncDeliveryThread)
+ {
+ // Thread.Interrupt and Thread.Abort do not interrupt Receive
+ // instructions. Attempting to abort the thread and joining
+ // will result in a phantom backgroud thread, which may
+ // ultimately consume a message before actually stopping.
+
+ Tracer.Info("Waiting for thread to complete aborting.");
+ asyncDeliveryThread.Join(dispatchingTimeout);
+
+ asyncDeliveryThread = null;
+ Tracer.Info("Async delivery thread stopped.");
+ }
+ }
+ }
+
+
+ protected virtual void HandleAsyncException(Exception e)
+ {
+ session.Connection.HandleException(e);
+ }
+
+ #endregion
+
+ #region Receive (synchronous)
+
public IMessage Receive()
{
IMessage nmsMessage = null;
@@ -126,7 +230,17 @@
if(messageQueue != null)
{
- nmsMessage = reader.Receive(timeout);
+ try
+ {
+ nmsMessage = reader.Receive(timeout);
+ }
+ catch(MessageQueueException ex)
+ {
+ if(ex.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout)
+ {
+ throw ex;
+ }
+ }
nmsMessage = TransformMessage(nmsMessage);
}
@@ -135,17 +249,13 @@
public IMessage ReceiveNoWait()
{
- IMessage nmsMessage = null;
-
- if(messageQueue != null)
- {
- nmsMessage = reader.Receive(zeroTimeout);
- nmsMessage = TransformMessage(nmsMessage);
- }
-
- return nmsMessage;
+ return Receive(zeroTimeout);
}
+ #endregion
+
+ #region Close & dispose
+
public void Dispose()
{
Close();
@@ -153,7 +263,13 @@
public void Close()
{
- StopAsyncDelivery();
+ if(listenerCount > 0)
+ {
+ session.Connection.ConnectionStateChange -= OnConnectionStateChange;
+
+ StopAsyncDelivery();
+ }
+
if(messageQueue != null)
{
messageQueue.Dispose();
@@ -161,74 +277,7 @@
}
}
- protected virtual void StopAsyncDelivery()
- {
- if(asyncDelivery.CompareAndSet(true, false))
- {
- if(null != asyncDeliveryThread)
- {
- Tracer.Info("Stopping async delivery thread.");
- pause.Set();
- if(!asyncDeliveryThread.Join(10000))
- {
- Tracer.Info("Aborting async delivery thread.");
- asyncDeliveryThread.Abort();
- }
-
- asyncDeliveryThread = null;
- Tracer.Info("Async delivery thread stopped.");
- }
- }
- }
-
- protected virtual void StartAsyncDelivery()
- {
- if(asyncDelivery.CompareAndSet(false, true))
- {
- asyncDeliveryThread = new Thread(new ThreadStart(DispatchLoop));
- asyncDeliveryThread.Name = "Message Consumer Dispatch: " + messageQueue.QueueName;
- asyncDeliveryThread.IsBackground = true;
- asyncDeliveryThread.Start();
- }
- }
-
- protected virtual void DispatchLoop()
- {
- Tracer.Info("Starting dispatcher thread consumer: " + this);
- while(asyncDelivery.Value)
- {
- try
- {
- IMessage message = Receive();
- if(asyncDelivery.Value && message != null)
- {
- try
- {
- listener(message);
- }
- catch(Exception e)
- {
- HandleAsyncException(e);
- }
- }
- }
- catch(ThreadAbortException ex)
- {
- Tracer.InfoFormat("Thread abort received in thread: {0} : {1}", this, ex.Message);
- break;
- }
- catch(Exception ex)
- {
- Tracer.ErrorFormat("Exception while receiving message in thread: {0} : {1}", this, ex.Message);
- }
- }
- Tracer.Info("Stopping dispatcher thread consumer: " + this);
- }
-
- protected virtual void HandleAsyncException(Exception e)
- {
- session.Connection.HandleException(e);
- }
+ #endregion
protected virtual IMessage TransformMessage(IMessage message)
{
diff --git a/src/main/csharp/MessageProducer.cs b/src/main/csharp/MessageProducer.cs
index 8690fc4..4a0bed4 100644
--- a/src/main/csharp/MessageProducer.cs
+++ b/src/main/csharp/MessageProducer.cs
@@ -50,41 +50,47 @@
this.destination = destination;
if(destination != null)
{
- messageQueue = openMessageQueue(destination);
+ messageQueue = OpenMessageQueue(destination);
}
}
- private MessageQueue openMessageQueue(Destination dest)
+ private MessageQueue OpenMessageQueue(Destination dest)
{
- MessageQueue rc = null;
- try
+ Queue queue = dest as Queue;
+
+ MessageQueue mq = queue.MSMQMessageQueue;
+
+ if(mq == null)
{
- if(!MessageQueue.Exists(dest.Path))
+ try
{
- // create the new message queue and make it transactional
- rc = MessageQueue.Create(dest.Path, session.Transacted);
- this.destination.Path = rc.Path;
- }
- else
- {
- rc = new MessageQueue(dest.Path);
- this.destination.Path = rc.Path;
- if(!rc.CanWrite)
+ if(!Queue.Exists(dest.Path))
{
- throw new NMSSecurityException("Do not have write access to: " + dest);
+ // create the new message queue and make it transactional
+ mq = MessageQueue.Create(dest.Path, session.Transacted);
+ this.destination = new Queue(mq);
+ }
+ else
+ {
+ mq = new MessageQueue(dest.Path);
+ this.destination = new Queue(mq);
+ if(!mq.CanWrite)
+ {
+ throw new NMSSecurityException("Do not have write access to: " + dest);
+ }
}
}
- }
- catch(Exception e)
- {
- if(rc != null)
+ catch(Exception e)
{
- rc.Dispose();
+ if(mq != null)
+ {
+ mq.Dispose();
+ }
+
+ throw new NMSException(e.Message + ": " + dest, e);
}
-
- throw new NMSException(e.Message + ": " + dest, e);
}
- return rc;
+ return mq;
}
public void Send(IMessage message)
@@ -111,18 +117,28 @@
// Locate the MSMQ Queue we will be sending to
if(messageQueue != null)
{
+ if(destination == null)
+ {
+ throw new InvalidDestinationException("This producer can only be used to send to: " + destination);
+ }
+
if(destination.Equals(this.destination))
{
mq = messageQueue;
}
else
{
- throw new NMSException("This producer can only be used to send to: " + destination);
+ throw new NotSupportedException("This producer can only be used to send to: " + destination);
}
}
else
{
- mq = openMessageQueue((Destination) destination);
+ if(destination == null)
+ {
+ throw new NotSupportedException();
+ }
+
+ mq = OpenMessageQueue((Destination) destination);
}
if(this.ProducerTransformer != null)
@@ -147,7 +163,7 @@
// TODO: message.NMSMessageId =
}
- // Convert the Mesasge into a MSMQ message
+ // Convert the Message into a MSMQ message
Message msg = session.MessageConverter.ToMsmqMessage(message);
if(mq.Transactional)
@@ -179,6 +195,11 @@
mq.Send(msg);
}
+ message.NMSMessageId = msg.Id;
+ if(message.NMSCorrelationID == null)
+ {
+ message.NMSCorrelationID = msg.CorrelationId;
+ }
}
finally
{
diff --git a/src/main/csharp/Queue.cs b/src/main/csharp/Queue.cs
index 30efcd9..4444a1b 100644
--- a/src/main/csharp/Queue.cs
+++ b/src/main/csharp/Queue.cs
@@ -15,6 +15,7 @@
* limitations under the License.
*/
using System;
+using System.Messaging;
namespace Apache.NMS.MSMQ
{
@@ -24,17 +25,69 @@
/// </summary>
public class Queue : Destination, IQueue
{
-
public Queue()
: base()
{
}
+ public Queue(MessageQueue messageQueue)
+ : base()
+ {
+ this.messageQueue = messageQueue;
+ Path = messageQueue.Path;
+ }
+
public Queue(String name)
: base(name)
{
+ if(string.IsNullOrEmpty(name))
+ {
+ messageQueue = null;
+ }
+ else
+ {
+ try
+ {
+ messageQueue = new MessageQueue(name);
+ }
+ catch(Exception /*ex*/)
+ {
+ // Excerpt from Microsoft documentation for MessageQueue.Exists :
+ // (@https://msdn.microsoft.com/fr-fr/library/system.messaging.messagequeue.exists(v=vs.110).aspx)
+ // Exists(String) is an expensive operation. Use it only when it is necessary within the application.
+ // ---
+ // Therefore, we won't check for existence of the queue before attempting to access it.
+
+ //if(!Exists(name))
+ //{
+ // Excerpt from the Oracle JMS JavaDoc for Session.createQueue :
+ // (@https://docs.oracle.com/javaee/7/api/javax/jms/Session.html#createQueue-java.lang.String-)
+ // Note that this method simply creates an object that encapsulates the name of a queue. It does
+ // not create the physical queue in the JMS provider. JMS does not provide a method to create the
+ // physical queue, since this would be specific to a given JMS provider. Creating a physical queue
+ // is provider-specific and is typically an administrative task performed by an administrator,
+ // though some providers may create them automatically when needed. The one exception to this is
+ // the creation of a temporary queue, which is done using the createTemporaryQueue method.
+ // ---
+ // Therefore, we should throw an NMSException if the queue does not exist.
+ // ---
+ // BUT, to keep it compatible with the initial implementation of MessageProducer, which attempts
+ // to create non pre-existing queues, we keep it silent..
+
+ // throw new NMSException("Message queue \"" + name + "\" does not exist", ex);
+ //}
+
+ // throw new NMSException("Cannot access message queue \"" + name + "\"", ex);
+ }
+ }
}
+ private MessageQueue messageQueue;
+ public MessageQueue MSMQMessageQueue
+ {
+ get { return messageQueue; }
+ }
+
override public DestinationType DestinationType
{
get
@@ -54,7 +107,25 @@
return new Queue(name);
}
+ public static bool Exists(string name)
+ {
+ try
+ {
+ return MessageQueue.Exists(name);
+ }
+ catch(InvalidOperationException)
+ {
+ // Excerpt from Microsoft documentation for MessageQueue.Exists :
+ // (@https://msdn.microsoft.com/fr-fr/library/system.messaging.messagequeue.exists(v=vs.110).aspx)
+ // InvalidOperationException: The application used format name syntax when verifying queue existence.
+ // ---
+ // The Exists(String) method does not support the FormatName prefix.
+ // No method exists to determine whether a queue with a specified format name exists.
+ // We'll assume the queue exists at this point
+ return true;
+ }
+ }
}
}
diff --git a/src/main/csharp/QueueBrowser.cs b/src/main/csharp/QueueBrowser.cs
index 3ff795d..9ccc2f9 100644
--- a/src/main/csharp/QueueBrowser.cs
+++ b/src/main/csharp/QueueBrowser.cs
@@ -1,164 +1,172 @@
-/*
- * 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.
- */
-using System;
-using System.Collections;
-using System.Messaging;
-using Apache.NMS;
-using Apache.NMS.Util;
-using Apache.NMS.MSMQ.Readers;
-
-namespace Apache.NMS.MSMQ
-{
- public class QueueBrowser : Apache.NMS.IQueueBrowser
- {
- private bool closed = false;
- private bool disposed = false;
-
- private readonly Session session;
- private MessageQueue messageQueue;
-
- private string selector;
-
- private IMessageReader reader;
-
- public QueueBrowser(Session session, MessageQueue messageQueue)
- : this(session, messageQueue, null)
- {
- }
-
- public QueueBrowser(Session session, MessageQueue messageQueue,
- string selector)
- {
- this.session = session;
- this.messageQueue = messageQueue;
- if(null != this.messageQueue)
- {
- this.messageQueue.MessageReadPropertyFilter.SetAll();
- }
-
- reader = MessageReaderUtil.CreateMessageReader(
- messageQueue, session.MessageConverter, selector);
- }
-
- ~QueueBrowser()
- {
- Dispose(false);
- }
-
- #region IDisposable Members
-
- ///<summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ///</summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected void Dispose(bool disposing)
- {
- if(disposed)
- {
- return;
- }
-
- if(disposing)
- {
- // Dispose managed code here.
- }
-
- try
- {
- Close();
- }
- catch
- {
- // Ignore errors.
- }
-
- disposed = true;
- }
-
- #endregion
-
- public void Close()
- {
- if(messageQueue != null)
- {
- messageQueue.Dispose();
- messageQueue = null;
- }
- closed = true;
- }
-
- public string MessageSelector
- {
- get { return selector; }
- }
-
- public IQueue Queue
- {
- get { return new Queue(this.messageQueue.Path); }
- }
-
- internal class Enumerator : IEnumerator
- {
- private readonly Session session;
- private readonly MessageEnumerator innerEnumerator;
- private readonly IMessageReader reader;
-
- public Enumerator(Session session, MessageQueue messageQueue,
- IMessageReader reader)
- {
- this.session = session;
- this.innerEnumerator = messageQueue.GetMessageEnumerator2();
- this.reader = reader;
- }
-
- public object Current
- {
- get
- {
- return this.session.MessageConverter.ToNmsMessage(this.innerEnumerator.Current);
- }
- }
-
- public bool MoveNext()
- {
- while(this.innerEnumerator.MoveNext())
- {
- if(reader.Matches(this.innerEnumerator.Current))
- {
- return true;
- }
- }
- return false;
- }
-
- public void Reset()
- {
- this.innerEnumerator.Reset();
- }
- }
-
- public IEnumerator GetEnumerator()
- {
- return new Enumerator(this.session, this.messageQueue, this.reader);
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using System.Messaging;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.MSMQ.Readers;
+
+namespace Apache.NMS.MSMQ
+{
+ public class QueueBrowser : Apache.NMS.IQueueBrowser
+ {
+ private bool disposed = false;
+
+ private readonly Session session;
+ private MessageQueue messageQueue;
+
+ private string selector;
+
+ private IMessageReader reader;
+
+ public QueueBrowser(Session session, MessageQueue messageQueue)
+ : this(session, messageQueue, null)
+ {
+ }
+
+ public QueueBrowser(Session session, MessageQueue messageQueue,
+ string selector)
+ {
+ this.session = session;
+ this.messageQueue = messageQueue;
+ if(null != this.messageQueue)
+ {
+ this.messageQueue.MessageReadPropertyFilter.SetAll();
+ }
+ this.selector = selector;
+
+ reader = MessageReaderUtil.CreateMessageReader(
+ messageQueue, session.MessageConverter, selector);
+ }
+
+ ~QueueBrowser()
+ {
+ Dispose(false);
+ }
+
+ #region IDisposable Members
+
+ ///<summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///</summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected void Dispose(bool disposing)
+ {
+ if(disposed)
+ {
+ return;
+ }
+
+ if(disposing)
+ {
+ // Dispose managed code here.
+ }
+
+ try
+ {
+ Close();
+ }
+ catch
+ {
+ // Ignore errors.
+ }
+
+ disposed = true;
+ }
+
+ #endregion
+
+ public void Close()
+ {
+ if(messageQueue != null)
+ {
+ messageQueue.Dispose();
+ messageQueue = null;
+ }
+ }
+
+ public string MessageSelector
+ {
+ get { return selector; }
+ }
+
+ public IQueue Queue
+ {
+ get { return new Queue(this.messageQueue.Path); }
+ }
+
+ internal class Enumerator : IEnumerator, IDisposable
+ {
+ private Session session;
+ private MessageEnumerator innerEnumerator;
+ private IMessageReader reader;
+
+ public Enumerator(Session session, MessageQueue messageQueue,
+ IMessageReader reader)
+ {
+ this.session = session;
+ this.innerEnumerator = messageQueue.GetMessageEnumerator2();
+ this.reader = reader;
+ }
+
+ public object Current
+ {
+ get
+ {
+ return this.session.MessageConverter.ToNmsMessage(this.innerEnumerator.Current);
+ }
+ }
+
+ public bool MoveNext()
+ {
+ while(this.innerEnumerator.MoveNext())
+ {
+ if(reader.Matches(this.innerEnumerator.Current))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void Reset()
+ {
+ this.innerEnumerator.Reset();
+ }
+
+ public void Dispose()
+ {
+ if(innerEnumerator != null)
+ {
+ innerEnumerator.Close();
+ innerEnumerator = null;
+ }
+ }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return new Enumerator(this.session, this.messageQueue, this.reader);
+ }
+ }
+}
diff --git a/src/main/csharp/Readers/AbstractMessageReader.cs b/src/main/csharp/Readers/AbstractMessageReader.cs
index 7874696..dcb217d 100644
--- a/src/main/csharp/Readers/AbstractMessageReader.cs
+++ b/src/main/csharp/Readers/AbstractMessageReader.cs
@@ -1,126 +1,126 @@
-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>
- /// Abstract MSMQ message reader. Derived classes support various
- /// message filtering methods.
- /// </summary>
- public abstract class AbstractMessageReader : IMessageReader
- {
- protected MessageQueue messageQueue;
- protected IMessageConverter messageConverter;
- protected IMessageConverterEx messageConverterEx;
-
- /// <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 AbstractMessageReader(MessageQueue messageQueue,
- IMessageConverter messageConverter)
- {
- this.messageQueue = messageQueue;
-
- this.messageConverter = messageConverter;
- this.messageConverterEx = (messageConverter as IMessageConverterEx);
- }
-
- /// <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 abstract 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>
- public abstract 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>
- public abstract 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>
- public abstract 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>
- public abstract 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>
- public abstract 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>
- public abstract bool Matches(Message message);
-
- /// <summary>
- /// Converts an MSMQ message to an NMS message, using the converter
- /// specified at construction time.
- /// </summary>
- /// <param name="message">MSMQ message.</param>
- /// <return>NMS message.</return>
- protected IMessage Convert(Message message)
- {
- return message == null ? null : messageConverter.ToNmsMessage(message);
- }
- }
-}
+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>
+ /// Abstract MSMQ message reader. Derived classes support various
+ /// message filtering methods.
+ /// </summary>
+ public abstract class AbstractMessageReader : IMessageReader
+ {
+ protected MessageQueue messageQueue;
+ protected IMessageConverter messageConverter;
+ protected IMessageConverterEx messageConverterEx;
+
+ /// <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 AbstractMessageReader(MessageQueue messageQueue,
+ IMessageConverter messageConverter)
+ {
+ this.messageQueue = messageQueue;
+
+ this.messageConverter = messageConverter;
+ this.messageConverterEx = (messageConverter as IMessageConverterEx);
+ }
+
+ /// <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 abstract 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>
+ public abstract 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>
+ public abstract 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>
+ public abstract 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>
+ public abstract 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>
+ public abstract 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>
+ public abstract bool Matches(Message message);
+
+ /// <summary>
+ /// Converts an MSMQ message to an NMS message, using the converter
+ /// specified at construction time.
+ /// </summary>
+ /// <param name="message">MSMQ message.</param>
+ /// <return>NMS message.</return>
+ protected IMessage Convert(Message message)
+ {
+ return message == null ? null : messageConverter.ToNmsMessage(message);
+ }
+ }
+}
diff --git a/src/main/csharp/Readers/ByCorrelationIdMessageReader.cs b/src/main/csharp/Readers/ByCorrelationIdMessageReader.cs
index fad3d1a..bc8d832 100644
--- a/src/main/csharp/Readers/ByCorrelationIdMessageReader.cs
+++ b/src/main/csharp/Readers/ByCorrelationIdMessageReader.cs
@@ -1,139 +1,139 @@
-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 messages matching the specified
- /// message identifier.
- /// </summary>
- public class ByCorrelationIdMessageReader : AbstractMessageReader
- {
- private string correlationId;
-
- /// <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>
- /// <param name="correlationId">The correlation identifier of messages
- /// to be read.</param>
- public ByCorrelationIdMessageReader(MessageQueue messageQueue,
- IMessageConverter messageConverter, string correlationId)
- : base(messageQueue, messageConverter)
- {
- this.correlationId = correlationId;
- }
-
- /// <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.PeekByCorrelationId(correlationId));
- }
-
- /// <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.PeekByCorrelationId(correlationId,
- 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.ReceiveByCorrelationId(correlationId));
- }
-
- /// <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.ReceiveByCorrelationId(correlationId,
- 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.ReceiveByCorrelationId(correlationId,
- 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.ReceiveByCorrelationId(correlationId,
- 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)
- {
- // NB: case-sensitive match
- return message.CorrelationId == correlationId;
- }
- }
-}
+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 messages matching the specified
+ /// message identifier.
+ /// </summary>
+ public class ByCorrelationIdMessageReader : AbstractMessageReader
+ {
+ private string correlationId;
+
+ /// <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>
+ /// <param name="correlationId">The correlation identifier of messages
+ /// to be read.</param>
+ public ByCorrelationIdMessageReader(MessageQueue messageQueue,
+ IMessageConverter messageConverter, string correlationId)
+ : base(messageQueue, messageConverter)
+ {
+ this.correlationId = correlationId;
+ }
+
+ /// <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.PeekByCorrelationId(correlationId));
+ }
+
+ /// <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.PeekByCorrelationId(correlationId,
+ 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.ReceiveByCorrelationId(correlationId));
+ }
+
+ /// <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.ReceiveByCorrelationId(correlationId,
+ 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.ReceiveByCorrelationId(correlationId,
+ 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.ReceiveByCorrelationId(correlationId,
+ 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)
+ {
+ // NB: case-sensitive match
+ return message.CorrelationId == correlationId;
+ }
+ }
+}
diff --git a/src/main/csharp/Readers/ByIdMessageReader.cs b/src/main/csharp/Readers/ByIdMessageReader.cs
index f981ca8..6a544f4 100644
--- a/src/main/csharp/Readers/ByIdMessageReader.cs
+++ b/src/main/csharp/Readers/ByIdMessageReader.cs
@@ -1,136 +1,136 @@
-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 messages matching the specified
- /// message identifier.
- /// </summary>
- public class ByIdMessageReader : AbstractMessageReader
- {
- private string messageId;
-
- /// <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>
- /// <param name="messageId">The message identifier of messages to
- /// be read.</param>
- public ByIdMessageReader(MessageQueue messageQueue,
- IMessageConverter messageConverter, string messageId)
- : base(messageQueue, messageConverter)
- {
- this.messageId = messageId;
- }
-
- /// <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.PeekById(messageId));
- }
-
- /// <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.PeekById(messageId, 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.ReceiveById(messageId));
- }
-
- /// <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.ReceiveById(messageId, 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.ReceiveById(messageId, 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.ReceiveById(messageId, 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)
- {
- // NB: case-sensitive match
- return message.Id == messageId;
- }
- }
-}
+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 messages matching the specified
+ /// message identifier.
+ /// </summary>
+ public class ByIdMessageReader : AbstractMessageReader
+ {
+ private string messageId;
+
+ /// <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>
+ /// <param name="messageId">The message identifier of messages to
+ /// be read.</param>
+ public ByIdMessageReader(MessageQueue messageQueue,
+ IMessageConverter messageConverter, string messageId)
+ : base(messageQueue, messageConverter)
+ {
+ this.messageId = messageId;
+ }
+
+ /// <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.PeekById(messageId));
+ }
+
+ /// <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.PeekById(messageId, 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.ReceiveById(messageId));
+ }
+
+ /// <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.ReceiveById(messageId, 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.ReceiveById(messageId, 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.ReceiveById(messageId, 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)
+ {
+ // NB: case-sensitive match
+ return message.Id == messageId;
+ }
+ }
+}
diff --git a/src/main/csharp/Readers/ByLookupIdMessageReader.cs b/src/main/csharp/Readers/ByLookupIdMessageReader.cs
index 421c52b..423c3a7 100644
--- a/src/main/csharp/Readers/ByLookupIdMessageReader.cs
+++ b/src/main/csharp/Readers/ByLookupIdMessageReader.cs
@@ -1,145 +1,215 @@
-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 messages matching the specified
- /// lookup identifier.
- /// </summary>
- public class ByLookupIdMessageReader : AbstractMessageReader
- {
- private Int64 lookupId;
-
- /// <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>
- /// <param name="lookupId">The lookup identifier of the message
- /// to be read.</param>
- public ByLookupIdMessageReader(MessageQueue messageQueue,
- IMessageConverter messageConverter, Int64 lookupId)
- : base(messageQueue, messageConverter)
- {
- this.lookupId = lookupId;
- }
-
- /// <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.PeekByLookupId(lookupId));
- }
-
- /// <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)
- {
- // No time-out option for receiving messages by lookup identifiers:
- // either the message is present in the queue, or the method throws
- // an exception immediately if the message is not in the queue.
- return Convert(messageQueue.PeekByLookupId(lookupId));
- }
-
- /// <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.ReceiveByLookupId(lookupId));
- }
-
- /// <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)
- {
- // No time-out option for receiving messages by lookup identifiers:
- // either the message is present in the queue, or the method throws
- // an exception immediately if the message is not in the queue.
- return Convert(messageQueue.ReceiveByLookupId(lookupId));
- }
-
- /// <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.ReceiveByLookupId(
- MessageLookupAction.Current, lookupId, 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)
- {
- // No time-out option for receiving messages by lookup identifiers:
- // either the message is present in the queue, or the method throws
- // an exception immediately if the message is not in the queue.
- return Convert(messageQueue.ReceiveByLookupId(
- MessageLookupAction.Current, lookupId, 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 message.LookupId == lookupId;
- }
- }
-}
+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 messages matching the specified
+ /// lookup identifier.
+ /// </summary>
+ public class ByLookupIdMessageReader : AbstractMessageReader
+ {
+ private Int64 lookupId;
+
+ // The MSMQ documentation for MessageQueue.PeekByLookupId(*) and
+ // MessageQueue.ReceiveByLookupId(*) specifies:
+ // InvalidOperationException: The message with the specified lookupId could not be found.
+
+ /// <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>
+ /// <param name="lookupId">The lookup identifier of the message
+ /// to be read.</param>
+ public ByLookupIdMessageReader(MessageQueue messageQueue,
+ IMessageConverter messageConverter, Int64 lookupId)
+ : base(messageQueue, messageConverter)
+ {
+ this.lookupId = lookupId;
+ }
+
+ /// <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()
+ {
+ try
+ {
+ return Convert(messageQueue.PeekByLookupId(lookupId));
+ }
+ catch(InvalidOperationException)
+ {
+ return null;
+ }
+ catch(Exception ex)
+ {
+ throw ex;
+ }
+ }
+
+ /// <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)
+ {
+ try
+ {
+ // No time-out option for receiving messages by lookup identifiers:
+ // either the message is present in the queue, or the method throws
+ // an exception immediately if the message is not in the queue.
+ return Convert(messageQueue.PeekByLookupId(lookupId));
+ }
+ catch(InvalidOperationException)
+ {
+ return null;
+ }
+ catch(Exception ex)
+ {
+ throw ex;
+ }
+ }
+
+ /// <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()
+ {
+ try
+ {
+ return Convert(messageQueue.ReceiveByLookupId(lookupId));
+ }
+ catch(InvalidOperationException)
+ {
+ return null;
+ }
+ catch(Exception ex)
+ {
+ throw ex;
+ }
+ }
+
+ /// <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)
+ {
+ try
+ {
+ // No time-out option for receiving messages by lookup identifiers:
+ // either the message is present in the queue, or the method throws
+ // an exception immediately if the message is not in the queue.
+ return Convert(messageQueue.ReceiveByLookupId(lookupId));
+ }
+ catch(InvalidOperationException)
+ {
+ return null;
+ }
+ catch(Exception ex)
+ {
+ throw ex;
+ }
+ }
+
+ /// <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)
+ {
+ try
+ {
+ return Convert(messageQueue.ReceiveByLookupId(
+ MessageLookupAction.Current, lookupId, transaction));
+ }
+ catch(InvalidOperationException)
+ {
+ return null;
+ }
+ catch(Exception ex)
+ {
+ throw ex;
+ }
+ }
+
+ /// <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)
+ {
+ try
+ {
+ // No time-out option for receiving messages by lookup identifiers:
+ // either the message is present in the queue, or the method throws
+ // an exception immediately if the message is not in the queue.
+ return Convert(messageQueue.ReceiveByLookupId(
+ MessageLookupAction.Current, lookupId, transaction));
+ }
+ catch(InvalidOperationException)
+ {
+ return null;
+ }
+ catch(Exception ex)
+ {
+ throw ex;
+ }
+ }
+
+ /// <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 message.LookupId == lookupId;
+ }
+ }
+}
diff --git a/src/main/csharp/Readers/BySelectorMessageReader.cs b/src/main/csharp/Readers/BySelectorMessageReader.cs
index e7cd5c3..5617784 100644
--- a/src/main/csharp/Readers/BySelectorMessageReader.cs
+++ b/src/main/csharp/Readers/BySelectorMessageReader.cs
@@ -1,290 +1,286 @@
-using System;
-using System.Messaging;
-using Apache.NMS.MSMQ;
-using Apache.NMS;
-using Apache.NMS.Selector;
-/*
- * 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 messages matching the specified
- /// selector.
- /// </summary>
- public class BySelectorMessageReader : AbstractMessageReader
- {
- private string selector;
- private MessageEvaluationContext evaluationContext;
- private IBooleanExpression selectionExpression;
-
- /// <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>
- /// <param name="selector">The selector string.</param>
- public BySelectorMessageReader(MessageQueue messageQueue,
- IMessageConverter messageConverter, string selector)
- : base(messageQueue, messageConverter)
- {
- this.selector = selector;
-
- SelectorParser selectorParser = new SelectorParser();
- selectionExpression = selectorParser.Parse(selector);
-
- evaluationContext = new MessageEvaluationContext(null);
- }
-
- /// <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 InternalPeek(DateTime.MaxValue, true);
- }
-
- /// <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)
- {
- DateTime maxTime = DateTime.Now + timeSpan;
- return InternalPeek(maxTime, true);
- }
-
- /// <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 InternalReceive(DateTime.MaxValue, null);
- }
-
- /// <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 InternalReceive(DateTime.Now + timeSpan, null);
- }
-
- /// <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 InternalReceive(DateTime.MaxValue, 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 InternalReceive(DateTime.Now + timeSpan, 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="maxTime">Reception time-out.</param>
- /// <param name="transaction">Transaction.</param>
- /// <returns>Received message.</returns>
- public IMessage InternalReceive(DateTime maxTime,
- MessageQueueTransaction transaction)
- {
- // In a shared connection / multi-consumer context, the message may
- // have been consumed by another client, after it was peeked but
- // before it was peeked by this client. Hence the loop.
- // (not sure it can be shared AND transactional, though).
- while(true)
- {
- IMessage peekedMessage = InternalPeek(maxTime, false);
-
- if(peekedMessage == null)
- {
- return null;
- }
-
- try
- {
- long lookupId = peekedMessage.Properties.GetLong("LookupId");
-
- Message message = (transaction == null ?
- messageQueue.ReceiveByLookupId(lookupId) :
- messageQueue.ReceiveByLookupId(
- MessageLookupAction.Current, lookupId, transaction));
-
- return Convert(message);
- }
- catch(InvalidOperationException exc)
- {
- // TODO: filter exceptions, catch only exceptions due to
- // unknown lookup id.
- }
- }
- }
-
- /// <summary>
- /// Returns without removing (peeks) the first message in the queue
- /// referenced by this MessageQueue, matching the selection criteria.
- /// </summary>
- /// <param name="maxTime">Reception time-out.</param>
- /// <param name="convertBody">true if message body should be converted.</param>
- /// <returns>Peeked message.</returns>
- private IMessage InternalPeek(DateTime maxTime, bool convertBody)
- {
- TimeSpan timeSpan = maxTime - DateTime.Now;
- if(timeSpan <= TimeSpan.Zero)
- {
- timeSpan = TimeSpan.Zero;
- }
-
- Cursor cursor = messageQueue.CreateCursor();
-
- PeekAction action = PeekAction.Current;
-
- while(true)
- {
- Message msmqMessage = null;
-
- try
- {
- msmqMessage = messageQueue.Peek(timeSpan, cursor, action);
- }
- catch(MessageQueueException exc)
- {
- if(exc.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout)
- {
- throw exc;
- }
- }
-
- if(msmqMessage == null)
- {
- return null;
- }
-
- IMessage nmsMessage = InternalMatch(msmqMessage, convertBody);
-
- if(nmsMessage != null)
- {
- return nmsMessage;
- }
-
- action = PeekAction.Next;
- }
- }
-
- /// <summary>
- /// Checks if an MSMQ message matches the selection criteria. If matched
- /// the method returns the converted NMS message. Else it returns null.
- /// </summary>
- /// <param name="message">The MSMQ message to check.</param>
- /// <param name="convertBody">true if the message body should be
- /// converted.</param>
- /// <returns>The matching message converted to NMS, or null.</returns>
- private IMessage InternalMatch(Message message, bool convertBody)
- {
- if(messageConverterEx == null)
- {
- IMessage nmsMessage = messageConverter.ToNmsMessage(message);
-
- evaluationContext.Message = nmsMessage;
-
- if(selectionExpression.Matches(evaluationContext))
- {
- return nmsMessage;
- }
- }
- else
- {
- // This version converts the message body only for those
- // messages matching the selection criteria.
- // Relies on MessageConverterEx for partial conversions.
- IMessage nmsMessage = messageConverterEx.ToNmsMessage(
- message, false);
-
- evaluationContext.Message = nmsMessage;
-
- if(selectionExpression.Matches(evaluationContext))
- {
- if(convertBody)
- {
- messageConverterEx.ConvertMessageBodyToNMS(
- message, nmsMessage);
- }
-
- return nmsMessage;
- }
- }
-
- return null;
- }
-
- /// <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)
- {
- IMessage nmsMessage = messageConverterEx == null ?
- messageConverter.ToNmsMessage(message) :
- messageConverterEx.ToNmsMessage(message, false);
-
- evaluationContext.Message = nmsMessage;
-
- return selectionExpression.Matches(evaluationContext);
- }
- }
-}
+using System;
+using System.Messaging;
+using Apache.NMS.MSMQ;
+using Apache.NMS;
+using Apache.NMS.Selector;
+/*
+ * 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 messages matching the specified
+ /// selector.
+ /// </summary>
+ public class BySelectorMessageReader : AbstractMessageReader
+ {
+ private string selector;
+ private MessageEvaluationContext evaluationContext;
+ private IBooleanExpression selectionExpression;
+
+ /// <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>
+ /// <param name="selector">The selector string.</param>
+ public BySelectorMessageReader(MessageQueue messageQueue,
+ IMessageConverter messageConverter, string selector)
+ : base(messageQueue, messageConverter)
+ {
+ this.selector = selector;
+
+ SelectorParser selectorParser = new SelectorParser();
+ selectionExpression = selectorParser.Parse(selector);
+
+ evaluationContext = new MessageEvaluationContext(null);
+ }
+
+ /// <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 InternalPeek(DateTime.MaxValue, true);
+ }
+
+ /// <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)
+ {
+ DateTime maxTime = DateTime.Now + timeSpan;
+ return InternalPeek(maxTime, true);
+ }
+
+ /// <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 InternalReceive(DateTime.MaxValue, null);
+ }
+
+ /// <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 InternalReceive(DateTime.Now + timeSpan, null);
+ }
+
+ /// <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 InternalReceive(DateTime.MaxValue, 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 InternalReceive(DateTime.Now + timeSpan, 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="maxTime">Reception time-out.</param>
+ /// <param name="transaction">Transaction.</param>
+ /// <returns>Received message.</returns>
+ public IMessage InternalReceive(DateTime maxTime,
+ MessageQueueTransaction transaction)
+ {
+ // In a shared connection / multi-consumer context, the message may
+ // have been consumed by another client, after it was peeked but
+ // before it was peeked by this client. Hence the loop.
+ // (not sure it can be shared AND transactional, though).
+ while(true)
+ {
+ IMessage peekedMessage = InternalPeek(maxTime, false);
+
+ if(peekedMessage == null)
+ {
+ return null;
+ }
+
+ try
+ {
+ long lookupId = peekedMessage.Properties.GetLong("LookupId");
+
+ Message message = (transaction == null ?
+ messageQueue.ReceiveByLookupId(lookupId) :
+ messageQueue.ReceiveByLookupId(
+ MessageLookupAction.Current, lookupId, transaction));
+
+ return Convert(message);
+ }
+ catch(InvalidOperationException)
+ {
+ // TODO: filter exceptions, catch only exceptions due to
+ // unknown lookup id.
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns without removing (peeks) the first message in the queue
+ /// referenced by this MessageQueue, matching the selection criteria.
+ /// </summary>
+ /// <param name="maxTime">Reception time-out.</param>
+ /// <param name="convertBody">true if message body should be converted.</param>
+ /// <returns>Peeked message.</returns>
+ private IMessage InternalPeek(DateTime maxTime, bool convertBody)
+ {
+ TimeSpan timeSpan = maxTime - DateTime.Now;
+ if(timeSpan <= TimeSpan.Zero)
+ {
+ timeSpan = TimeSpan.Zero;
+ }
+
+ using(Cursor cursor = messageQueue.CreateCursor())
+ {
+ PeekAction action = PeekAction.Current;
+ while(true)
+ {
+ Message msmqMessage = null;
+
+ try
+ {
+ msmqMessage = messageQueue.Peek(timeSpan, cursor, action);
+ }
+ catch(MessageQueueException exc)
+ {
+ if(exc.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
+ {
+ return null;
+ }
+ throw exc;
+ }
+
+ IMessage nmsMessage = InternalMatch(msmqMessage, convertBody);
+
+ if(nmsMessage != null)
+ {
+ return nmsMessage;
+ }
+
+ action = PeekAction.Next;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Checks if an MSMQ message matches the selection criteria. If matched
+ /// the method returns the converted NMS message. Else it returns null.
+ /// </summary>
+ /// <param name="message">The MSMQ message to check.</param>
+ /// <param name="convertBody">true if the message body should be
+ /// converted.</param>
+ /// <returns>The matching message converted to NMS, or null.</returns>
+ private IMessage InternalMatch(Message message, bool convertBody)
+ {
+ if(messageConverterEx == null)
+ {
+ IMessage nmsMessage = messageConverter.ToNmsMessage(message);
+
+ evaluationContext.Message = nmsMessage;
+
+ if(selectionExpression.Matches(evaluationContext))
+ {
+ return nmsMessage;
+ }
+ }
+ else
+ {
+ // This version converts the message body only for those
+ // messages matching the selection criteria.
+ // Relies on MessageConverterEx for partial conversions.
+ IMessage nmsMessage = messageConverterEx.ToNmsMessage(
+ message, false);
+
+ evaluationContext.Message = nmsMessage;
+
+ if(selectionExpression.Matches(evaluationContext))
+ {
+ if(convertBody)
+ {
+ messageConverterEx.ConvertMessageBodyToNMS(
+ message, nmsMessage);
+ }
+
+ return nmsMessage;
+ }
+ }
+
+ return null;
+ }
+
+ /// <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)
+ {
+ IMessage nmsMessage = messageConverterEx == null ?
+ messageConverter.ToNmsMessage(message) :
+ messageConverterEx.ToNmsMessage(message, false);
+
+ evaluationContext.Message = nmsMessage;
+
+ return selectionExpression.Matches(evaluationContext);
+ }
+ }
+}
diff --git a/src/main/csharp/Readers/IMessageReader.cs b/src/main/csharp/Readers/IMessageReader.cs
index 8168664..c36323f 100644
--- a/src/main/csharp/Readers/IMessageReader.cs
+++ b/src/main/csharp/Readers/IMessageReader.cs
@@ -1,93 +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);
- }
-}
+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);
+ }
+}
diff --git a/src/main/csharp/Readers/MessageReaderUtil.cs b/src/main/csharp/Readers/MessageReaderUtil.cs
index c303965..97d62c3 100644
--- a/src/main/csharp/Readers/MessageReaderUtil.cs
+++ b/src/main/csharp/Readers/MessageReaderUtil.cs
@@ -1,91 +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;
- }
- }
-}
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Readers/NonFilteringMessageReader.cs b/src/main/csharp/Readers/NonFilteringMessageReader.cs
index ea98baf..0b9ff7b 100644
--- a/src/main/csharp/Readers/NonFilteringMessageReader.cs
+++ b/src/main/csharp/Readers/NonFilteringMessageReader.cs
@@ -1,128 +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;
- }
- }
-}
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/ANDExpression.cs b/src/main/csharp/Selector/ANDExpression.cs
index 285efe3..976eacc 100644
--- a/src/main/csharp/Selector/ANDExpression.cs
+++ b/src/main/csharp/Selector/ANDExpression.cs
@@ -1,47 +1,46 @@
-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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/AlignedNumericValues.cs b/src/main/csharp/Selector/AlignedNumericValues.cs
index 96e2eeb..b8bfa50 100644
--- a/src/main/csharp/Selector/AlignedNumericValues.cs
+++ b/src/main/csharp/Selector/AlignedNumericValues.cs
@@ -1,175 +1,174 @@
-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));
- }
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+using System.Globalization;
+using System.Collections.Generic;
+
+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));
+ }
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/ArithmeticExpression.cs b/src/main/csharp/Selector/ArithmeticExpression.cs
index a0524ee..0da9129 100644
--- a/src/main/csharp/Selector/ArithmeticExpression.cs
+++ b/src/main/csharp/Selector/ArithmeticExpression.cs
@@ -1,57 +1,56 @@
-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);
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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);
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/BinaryExpression.cs b/src/main/csharp/Selector/BinaryExpression.cs
index 9206f8c..0cb506d 100644
--- a/src/main/csharp/Selector/BinaryExpression.cs
+++ b/src/main/csharp/Selector/BinaryExpression.cs
@@ -1,59 +1,58 @@
-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() + ")";
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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() + ")";
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/BooleanCastExpression.cs b/src/main/csharp/Selector/BooleanCastExpression.cs
index 26a6e9e..ea5bf05 100644
--- a/src/main/csharp/Selector/BooleanCastExpression.cs
+++ b/src/main/csharp/Selector/BooleanCastExpression.cs
@@ -1,45 +1,44 @@
-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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/BooleanConstantExpression.cs b/src/main/csharp/Selector/BooleanConstantExpression.cs
index eb6447a..1859436 100644
--- a/src/main/csharp/Selector/BooleanConstantExpression.cs
+++ b/src/main/csharp/Selector/BooleanConstantExpression.cs
@@ -1,38 +1,37 @@
-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;
- }
- }
+/*
+ * 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.
+ */
+using System;
+
+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
diff --git a/src/main/csharp/Selector/BooleanUnaryExpression.cs b/src/main/csharp/Selector/BooleanUnaryExpression.cs
index 3873050..00489d5 100644
--- a/src/main/csharp/Selector/BooleanUnaryExpression.cs
+++ b/src/main/csharp/Selector/BooleanUnaryExpression.cs
@@ -1,39 +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>
- /// 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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/ComparisonExpression.cs b/src/main/csharp/Selector/ComparisonExpression.cs
index 4024271..ca9a9fe 100644
--- a/src/main/csharp/Selector/ComparisonExpression.cs
+++ b/src/main/csharp/Selector/ComparisonExpression.cs
@@ -1,162 +1,161 @@
-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);
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+
+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);
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/ConstantExpression.cs b/src/main/csharp/Selector/ConstantExpression.cs
index 90dfd69..b71683d 100644
--- a/src/main/csharp/Selector/ConstantExpression.cs
+++ b/src/main/csharp/Selector/ConstantExpression.cs
@@ -1,157 +1,156 @@
-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);
- }
+/*
+ * 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.
+ */
+using System;
+using System.Text;
+using System.Globalization;
+
+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
diff --git a/src/main/csharp/Selector/DivideExpression.cs b/src/main/csharp/Selector/DivideExpression.cs
index e280ec8..63f13aa 100644
--- a/src/main/csharp/Selector/DivideExpression.cs
+++ b/src/main/csharp/Selector/DivideExpression.cs
@@ -1,67 +1,66 @@
-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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/EqualExpression.cs b/src/main/csharp/Selector/EqualExpression.cs
index 0e9a792..af48080 100644
--- a/src/main/csharp/Selector/EqualExpression.cs
+++ b/src/main/csharp/Selector/EqualExpression.cs
@@ -1,47 +1,46 @@
-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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/GreaterExpression.cs b/src/main/csharp/Selector/GreaterExpression.cs
index eb264e5..012f3fb 100644
--- a/src/main/csharp/Selector/GreaterExpression.cs
+++ b/src/main/csharp/Selector/GreaterExpression.cs
@@ -1,42 +1,41 @@
-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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/GreaterOrEqualExpression.cs b/src/main/csharp/Selector/GreaterOrEqualExpression.cs
index 7a456f8..df8cc6f 100644
--- a/src/main/csharp/Selector/GreaterOrEqualExpression.cs
+++ b/src/main/csharp/Selector/GreaterOrEqualExpression.cs
@@ -1,43 +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 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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/IBooleanExpression.cs b/src/main/csharp/Selector/IBooleanExpression.cs
index af6c0f5..bf5a833 100644
--- a/src/main/csharp/Selector/IBooleanExpression.cs
+++ b/src/main/csharp/Selector/IBooleanExpression.cs
@@ -1,35 +1,34 @@
-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);
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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);
+ }
+}
diff --git a/src/main/csharp/Selector/IExpression.cs b/src/main/csharp/Selector/IExpression.cs
index 30fb893..833c6b5 100644
--- a/src/main/csharp/Selector/IExpression.cs
+++ b/src/main/csharp/Selector/IExpression.cs
@@ -1,35 +1,34 @@
-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);
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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
diff --git a/src/main/csharp/Selector/InExpression.cs b/src/main/csharp/Selector/InExpression.cs
index cd2d7ea..cbf3e60 100644
--- a/src/main/csharp/Selector/InExpression.cs
+++ b/src/main/csharp/Selector/InExpression.cs
@@ -1,98 +1,97 @@
-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();
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+
+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();
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/IsNullExpression.cs b/src/main/csharp/Selector/IsNullExpression.cs
index 28d89a2..6ad0436 100644
--- a/src/main/csharp/Selector/IsNullExpression.cs
+++ b/src/main/csharp/Selector/IsNullExpression.cs
@@ -1,59 +1,58 @@
-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();
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+using System.Text;
+
+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();
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/LesserExpression.cs b/src/main/csharp/Selector/LesserExpression.cs
index 4be2c9d..24b707b 100644
--- a/src/main/csharp/Selector/LesserExpression.cs
+++ b/src/main/csharp/Selector/LesserExpression.cs
@@ -1,42 +1,41 @@
-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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/LesserOrEqualExpression.cs b/src/main/csharp/Selector/LesserOrEqualExpression.cs
index abdc7e5..f4a99db 100644
--- a/src/main/csharp/Selector/LesserOrEqualExpression.cs
+++ b/src/main/csharp/Selector/LesserOrEqualExpression.cs
@@ -1,43 +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 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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/LikeExpression.cs b/src/main/csharp/Selector/LikeExpression.cs
index 8317bd6..41be1bd 100644
--- a/src/main/csharp/Selector/LikeExpression.cs
+++ b/src/main/csharp/Selector/LikeExpression.cs
@@ -1,124 +1,123 @@
-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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Globalization;
+
+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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/LogicExpression.cs b/src/main/csharp/Selector/LogicExpression.cs
index 61617a4..8e60fb0 100644
--- a/src/main/csharp/Selector/LogicExpression.cs
+++ b/src/main/csharp/Selector/LogicExpression.cs
@@ -1,48 +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 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);
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+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);
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/MessageEvaluationContext.cs b/src/main/csharp/Selector/MessageEvaluationContext.cs
index 054d911..6f26d0f 100644
--- a/src/main/csharp/Selector/MessageEvaluationContext.cs
+++ b/src/main/csharp/Selector/MessageEvaluationContext.cs
@@ -1,78 +1,77 @@
-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];
- }
- }
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS;
+
+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
diff --git a/src/main/csharp/Selector/MinusExpression.cs b/src/main/csharp/Selector/MinusExpression.cs
index 260e5e8..b2bc845 100644
--- a/src/main/csharp/Selector/MinusExpression.cs
+++ b/src/main/csharp/Selector/MinusExpression.cs
@@ -1,67 +1,66 @@
-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 substraction of two expressions.
- /// </summary>
- public class MinusExpression : ArithmeticExpression
- {
- protected override string ExpressionSymbol
- {
- get { return "-"; }
- }
-
- public MinusExpression(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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Selector
+{
+ /// <summary>
+ /// A filter performing a substraction of two expressions.
+ /// </summary>
+ public class MinusExpression : ArithmeticExpression
+ {
+ protected override string ExpressionSymbol
+ {
+ get { return "-"; }
+ }
+
+ public MinusExpression(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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/ModExpression.cs b/src/main/csharp/Selector/ModExpression.cs
index 386c08d..0ed5234 100644
--- a/src/main/csharp/Selector/ModExpression.cs
+++ b/src/main/csharp/Selector/ModExpression.cs
@@ -1,67 +1,66 @@
-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 modulo of two expressions.
- /// </summary>
- public class ModExpression : ArithmeticExpression
- {
- protected override string ExpressionSymbol
- {
- get { return "%"; }
- }
-
- public ModExpression(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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Selector
+{
+ /// <summary>
+ /// A filter performing a modulo of two expressions.
+ /// </summary>
+ public class ModExpression : ArithmeticExpression
+ {
+ protected override string ExpressionSymbol
+ {
+ get { return "%"; }
+ }
+
+ public ModExpression(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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/MultiplyExpression.cs b/src/main/csharp/Selector/MultiplyExpression.cs
index 0009092..130783f 100644
--- a/src/main/csharp/Selector/MultiplyExpression.cs
+++ b/src/main/csharp/Selector/MultiplyExpression.cs
@@ -1,67 +1,66 @@
-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 multiplication of two expressions.
- /// </summary>
- public class MultiplyExpression : ArithmeticExpression
- {
- protected override string ExpressionSymbol
- {
- get { return "*"; }
- }
-
- public MultiplyExpression(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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Selector
+{
+ /// <summary>
+ /// A filter performing a multiplication of two expressions.
+ /// </summary>
+ public class MultiplyExpression : ArithmeticExpression
+ {
+ protected override string ExpressionSymbol
+ {
+ get { return "*"; }
+ }
+
+ public MultiplyExpression(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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/NOTExpression.cs b/src/main/csharp/Selector/NOTExpression.cs
index 6d6ef55..a8b1c33 100644
--- a/src/main/csharp/Selector/NOTExpression.cs
+++ b/src/main/csharp/Selector/NOTExpression.cs
@@ -1,45 +1,44 @@
-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 negates a boolean expression value.
- /// </summary>
- public class NOTExpression : BooleanUnaryExpression
- {
- protected override string ExpressionSymbol
- {
- get { return "NOT"; }
- }
-
- public NOTExpression(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 null;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Selector
+{
+ /// <summary>
+ /// An expression which negates a boolean expression value.
+ /// </summary>
+ public class NOTExpression : BooleanUnaryExpression
+ {
+ protected override string ExpressionSymbol
+ {
+ get { return "NOT"; }
+ }
+
+ public NOTExpression(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 null;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/NegateExpression.cs b/src/main/csharp/Selector/NegateExpression.cs
index 0496b6f..f074590 100644
--- a/src/main/csharp/Selector/NegateExpression.cs
+++ b/src/main/csharp/Selector/NegateExpression.cs
@@ -1,51 +1,50 @@
-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 negates a numeric expression value.
- /// </summary>
- public class NegateExpression : UnaryExpression
- {
- protected override string ExpressionSymbol
- {
- get { return "-"; }
- }
-
- public NegateExpression(IExpression left)
- : base(left)
- {
- }
-
- public override object Evaluate(MessageEvaluationContext message)
- {
- object rvalue = Right.Evaluate(message);
- if(rvalue == null ) return null;
- if(rvalue is int ) return -(int )rvalue;
- if(rvalue is long ) return -(long )rvalue;
- if(rvalue is double ) return -(double )rvalue;
- if(rvalue is float ) return -(float )rvalue;
- if(rvalue is decimal) return -(decimal)rvalue;
- if(rvalue is short ) return -(short )rvalue;
- if(rvalue is byte ) return -(byte )rvalue;
- return null;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Selector
+{
+ /// <summary>
+ /// An expression which negates a numeric expression value.
+ /// </summary>
+ public class NegateExpression : UnaryExpression
+ {
+ protected override string ExpressionSymbol
+ {
+ get { return "-"; }
+ }
+
+ public NegateExpression(IExpression left)
+ : base(left)
+ {
+ }
+
+ public override object Evaluate(MessageEvaluationContext message)
+ {
+ object rvalue = Right.Evaluate(message);
+ if(rvalue == null ) return null;
+ if(rvalue is int ) return -(int )rvalue;
+ if(rvalue is long ) return -(long )rvalue;
+ if(rvalue is double ) return -(double )rvalue;
+ if(rvalue is float ) return -(float )rvalue;
+ if(rvalue is decimal) return -(decimal)rvalue;
+ if(rvalue is short ) return -(short )rvalue;
+ if(rvalue is byte ) return -(byte )rvalue;
+ return null;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/ORExpression.cs b/src/main/csharp/Selector/ORExpression.cs
index 86648bc..b2ed7f3 100644
--- a/src/main/csharp/Selector/ORExpression.cs
+++ b/src/main/csharp/Selector/ORExpression.cs
@@ -1,46 +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>
- /// A filter performing a logical OR combination of two expressions.
- /// </summary>
- public class ORExpression : LogicExpression
- {
- protected override string ExpressionSymbol
- {
- get { return "OR"; }
- }
-
- public ORExpression(IBooleanExpression left, IBooleanExpression right)
- : base(left, right)
- {
- }
-
- public override object Evaluate(MessageEvaluationContext message)
- {
- object lvalue = Left.Evaluate(message);
- if(lvalue != null && (bool)lvalue) return true;
-
- object rvalue = Right.Evaluate(message);
- return rvalue == null ? null : rvalue;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Selector
+{
+ /// <summary>
+ /// A filter performing a logical OR combination of two expressions.
+ /// </summary>
+ public class ORExpression : LogicExpression
+ {
+ protected override string ExpressionSymbol
+ {
+ get { return "OR"; }
+ }
+
+ public ORExpression(IBooleanExpression left, IBooleanExpression right)
+ : base(left, right)
+ {
+ }
+
+ public override object Evaluate(MessageEvaluationContext message)
+ {
+ object lvalue = Left.Evaluate(message);
+ if(lvalue != null && (bool)lvalue) return true;
+
+ object rvalue = Right.Evaluate(message);
+ return rvalue == null ? null : rvalue;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/ParseException.cs b/src/main/csharp/Selector/ParseException.cs
index f1b6d60..17706e1 100644
--- a/src/main/csharp/Selector/ParseException.cs
+++ b/src/main/csharp/Selector/ParseException.cs
@@ -1,197 +1,197 @@
-/* Generated By:CSharpCC: Do not edit this line. ParseException.cs Version 3.2 */
-/// <summary>
-/// This exception is thrown when parse errors are encountered.
-/// </summary>
-/// <remarks>
-/// You can explicitly create objects of this exception type by
-/// calling the method GenerateParseException in the generated
-/// parser.
-/// <para>
-/// You can modify this class to customize your error reporting
-/// mechanisms so long as you retain the public fields.
-/// </para>
-/// </remarks>
-public class ParseException : System.Exception {
-
- /**
- * This constructor is used by the method "GenerateParseException"
- * in the generated parser. Calling this constructor generates
- * a new object of this type with the fields "currentToken",
- * "expectedTokenSequences", and "tokenImage" set. The boolean
- * flag "specialConstructor" is also set to true to indicate that
- * this constructor was used to create this object.
- * This constructor calls its super class with the empty string
- * to force the "toString" method of parent class "Throwable" to
- * print the error message in the form:
- * ParseException: result of getMessage
- */
- public ParseException(Token currentTokenVal,
- int[][] expectedTokenSequencesVal,
- string[] tokenImageVal
- ) : base("") {
- specialConstructor = true;
- currentToken = currentTokenVal;
- expectedTokenSequences = expectedTokenSequencesVal;
- tokenImage = tokenImageVal;
- }
-
- /**
- * The following constructors are for use by you for whatever
- * purpose you can think of. Constructing the exception in this
- * manner makes the exception behave in the normal way - i.e., as
- * documented in the class "Exception". The fields "errorToken",
- * "expectedTokenSequences", and "tokenImage" do not contain
- * relevant information. The CSharpCC generated code does not use
- * these constructors.
- */
-
- public ParseException() :
- base() {
- specialConstructor = false;
- }
-
- public ParseException(string message) :
- base(message) {
- specialConstructor = false;
- }
-
- /**
- * This variable determines which constructor was used to create
- * this object and thereby affects the semantics of the
- * "getMessage" method (see below).
- */
- protected bool specialConstructor;
-
- /**
- * This is the last token that has been consumed successfully. If
- * this object has been created due to a parse error, the token
- * followng this token will (therefore) be the first error token.
- */
- public Token currentToken;
-
- /**
- * Each entry in this array is an array of integers. Each array
- * of integers represents a sequence of tokens (by their ordinal
- * values) that is expected at this point of the parse.
- */
- public int[][] expectedTokenSequences;
-
- /**
- * This is a reference to the "tokenImage" array of the generated
- * parser within which the parse error occurred. This array is
- * defined in the generated ...Constants interface.
- */
- public string[] tokenImage;
-
- /**
- * This method has the standard behavior when this object has been
- * created using the standard constructors. Otherwise, it uses
- * "currentToken" and "expectedTokenSequences" to generate a parse
- * error message and returns it. If this object has been created
- * due to a parse error, and you do not catch it (it gets thrown
- * from the parser), then this method is called during the printing
- * of the final stack trace, and hence the correct error message
- * gets displayed.
- */
- public override string Message {
- get {
- if (!specialConstructor) {
- return base.Message;
- }
- string expected = "";
- int maxSize = 0;
- for (int i = 0; i < expectedTokenSequences.Length; i++) {
- if (maxSize < expectedTokenSequences[i].Length) {
- maxSize = expectedTokenSequences[i].Length;
- }
- for (int j = 0; j < expectedTokenSequences[i].Length; j++) {
- expected += tokenImage[expectedTokenSequences[i][j]] + " ";
- }
- if (expectedTokenSequences[i][expectedTokenSequences[i].Length - 1] != 0) {
- expected += "...";
- }
- expected += eol + " ";
- }
- string retval = "Encountered \"";
- Token tok = currentToken.next;
- for (int i = 0; i < maxSize; i++) {
- if (i != 0) retval += " ";
- if (tok.kind == 0) {
- retval += tokenImage[0];
- break;
- }
- retval += AddEscapes(tok.image);
- tok = tok.next;
- }
- if (currentToken.next.kind == 0) {
- retval += "\" after line ";
- } else {
- retval += "\" at line ";
- }
- retval += currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
- retval += "." + eol;
- if (expectedTokenSequences.Length == 1) {
- retval += "Was expecting:" + eol + " ";
- } else {
- retval += "Was expecting one of:" + eol + " ";
- }
- retval += expected;
- return retval;
- }
- }
-
- /**
- * The end of line string for this machine.
- */
- protected string eol = System.Environment.NewLine;
-
- /**
- * Used to convert raw characters to their escaped version
- * when these raw version cannot be used as part of an ASCII
- * string literal.
- */
- protected string AddEscapes(string str) {
- System.Text.StringBuilder retval = new System.Text.StringBuilder();
- char ch;
- for (int i = 0; i < str.Length; i++) {
- switch (str[i]) {
- case '\0' :
- continue;
- case '\b':
- retval.Append("\\b");
- continue;
- case '\t':
- retval.Append("\\t");
- continue;
- case '\n':
- retval.Append("\\n");
- continue;
- case '\f':
- retval.Append("\\f");
- continue;
- case '\r':
- retval.Append("\\r");
- continue;
- case '\"':
- retval.Append("\\\"");
- continue;
- case '\'':
- retval.Append("\\\'");
- continue;
- case '\\':
- retval.Append("\\\\");
- continue;
- default:
- if ((ch = str[i]) < 0x20 || ch > 0x7e) {
- string s = "0000" + System.Convert.ToString((int)ch, 16);
- retval.Append("\\u" + s.Substring(s.Length - 4, s.Length - (s.Length - 4)));
- } else {
- retval.Append(ch);
- }
- continue;
- }
- }
- return retval.ToString();
- }
-
-}
+/* Generated By:CSharpCC: Do not edit this line. ParseException.cs Version 3.2 */
+/// <summary>
+/// This exception is thrown when parse errors are encountered.
+/// </summary>
+/// <remarks>
+/// You can explicitly create objects of this exception type by
+/// calling the method GenerateParseException in the generated
+/// parser.
+/// <para>
+/// You can modify this class to customize your error reporting
+/// mechanisms so long as you retain the public fields.
+/// </para>
+/// </remarks>
+public class ParseException : System.Exception {
+
+ /**
+ * This constructor is used by the method "GenerateParseException"
+ * in the generated parser. Calling this constructor generates
+ * a new object of this type with the fields "currentToken",
+ * "expectedTokenSequences", and "tokenImage" set. The boolean
+ * flag "specialConstructor" is also set to true to indicate that
+ * this constructor was used to create this object.
+ * This constructor calls its super class with the empty string
+ * to force the "toString" method of parent class "Throwable" to
+ * print the error message in the form:
+ * ParseException: result of getMessage
+ */
+ public ParseException(Token currentTokenVal,
+ int[][] expectedTokenSequencesVal,
+ string[] tokenImageVal
+ ) : base("") {
+ specialConstructor = true;
+ currentToken = currentTokenVal;
+ expectedTokenSequences = expectedTokenSequencesVal;
+ tokenImage = tokenImageVal;
+ }
+
+ /**
+ * The following constructors are for use by you for whatever
+ * purpose you can think of. Constructing the exception in this
+ * manner makes the exception behave in the normal way - i.e., as
+ * documented in the class "Exception". The fields "errorToken",
+ * "expectedTokenSequences", and "tokenImage" do not contain
+ * relevant information. The CSharpCC generated code does not use
+ * these constructors.
+ */
+
+ public ParseException() :
+ base() {
+ specialConstructor = false;
+ }
+
+ public ParseException(string message) :
+ base(message) {
+ specialConstructor = false;
+ }
+
+ /**
+ * This variable determines which constructor was used to create
+ * this object and thereby affects the semantics of the
+ * "getMessage" method (see below).
+ */
+ protected bool specialConstructor;
+
+ /**
+ * This is the last token that has been consumed successfully. If
+ * this object has been created due to a parse error, the token
+ * followng this token will (therefore) be the first error token.
+ */
+ public Token currentToken;
+
+ /**
+ * Each entry in this array is an array of integers. Each array
+ * of integers represents a sequence of tokens (by their ordinal
+ * values) that is expected at this point of the parse.
+ */
+ public int[][] expectedTokenSequences;
+
+ /**
+ * This is a reference to the "tokenImage" array of the generated
+ * parser within which the parse error occurred. This array is
+ * defined in the generated ...Constants interface.
+ */
+ public string[] tokenImage;
+
+ /**
+ * This method has the standard behavior when this object has been
+ * created using the standard constructors. Otherwise, it uses
+ * "currentToken" and "expectedTokenSequences" to generate a parse
+ * error message and returns it. If this object has been created
+ * due to a parse error, and you do not catch it (it gets thrown
+ * from the parser), then this method is called during the printing
+ * of the final stack trace, and hence the correct error message
+ * gets displayed.
+ */
+ public override string Message {
+ get {
+ if (!specialConstructor) {
+ return base.Message;
+ }
+ string expected = "";
+ int maxSize = 0;
+ for (int i = 0; i < expectedTokenSequences.Length; i++) {
+ if (maxSize < expectedTokenSequences[i].Length) {
+ maxSize = expectedTokenSequences[i].Length;
+ }
+ for (int j = 0; j < expectedTokenSequences[i].Length; j++) {
+ expected += tokenImage[expectedTokenSequences[i][j]] + " ";
+ }
+ if (expectedTokenSequences[i][expectedTokenSequences[i].Length - 1] != 0) {
+ expected += "...";
+ }
+ expected += eol + " ";
+ }
+ string retval = "Encountered \"";
+ Token tok = currentToken.next;
+ for (int i = 0; i < maxSize; i++) {
+ if (i != 0) retval += " ";
+ if (tok.kind == 0) {
+ retval += tokenImage[0];
+ break;
+ }
+ retval += AddEscapes(tok.image);
+ tok = tok.next;
+ }
+ if (currentToken.next.kind == 0) {
+ retval += "\" after line ";
+ } else {
+ retval += "\" at line ";
+ }
+ retval += currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
+ retval += "." + eol;
+ if (expectedTokenSequences.Length == 1) {
+ retval += "Was expecting:" + eol + " ";
+ } else {
+ retval += "Was expecting one of:" + eol + " ";
+ }
+ retval += expected;
+ return retval;
+ }
+ }
+
+ /**
+ * The end of line string for this machine.
+ */
+ protected string eol = System.Environment.NewLine;
+
+ /**
+ * Used to convert raw characters to their escaped version
+ * when these raw version cannot be used as part of an ASCII
+ * string literal.
+ */
+ protected string AddEscapes(string str) {
+ System.Text.StringBuilder retval = new System.Text.StringBuilder();
+ char ch;
+ for (int i = 0; i < str.Length; i++) {
+ switch (str[i]) {
+ case '\0' :
+ continue;
+ case '\b':
+ retval.Append("\\b");
+ continue;
+ case '\t':
+ retval.Append("\\t");
+ continue;
+ case '\n':
+ retval.Append("\\n");
+ continue;
+ case '\f':
+ retval.Append("\\f");
+ continue;
+ case '\r':
+ retval.Append("\\r");
+ continue;
+ case '\"':
+ retval.Append("\\\"");
+ continue;
+ case '\'':
+ retval.Append("\\\'");
+ continue;
+ case '\\':
+ retval.Append("\\\\");
+ continue;
+ default:
+ if ((ch = str[i]) < 0x20 || ch > 0x7e) {
+ string s = "0000" + System.Convert.ToString((int)ch, 16);
+ retval.Append("\\u" + s.Substring(s.Length - 4, s.Length - (s.Length - 4)));
+ } else {
+ retval.Append(ch);
+ }
+ continue;
+ }
+ }
+ return retval.ToString();
+ }
+
+}
diff --git a/src/main/csharp/Selector/PlusExpression.cs b/src/main/csharp/Selector/PlusExpression.cs
index 450b653..b966765 100644
--- a/src/main/csharp/Selector/PlusExpression.cs
+++ b/src/main/csharp/Selector/PlusExpression.cs
@@ -1,68 +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 an addition of two expressions.
- /// </summary>
- public class PlusExpression : ArithmeticExpression
- {
- protected override string ExpressionSymbol
- {
- get { return "+"; }
- }
-
- public PlusExpression(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(lvalue is string) return (string)lvalue + rvalue;
- 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;
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Selector
+{
+ /// <summary>
+ /// A filter performing an addition of two expressions.
+ /// </summary>
+ public class PlusExpression : ArithmeticExpression
+ {
+ protected override string ExpressionSymbol
+ {
+ get { return "+"; }
+ }
+
+ public PlusExpression(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(lvalue is string) return (string)lvalue + rvalue;
+ 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;
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/PropertyExpression.cs b/src/main/csharp/Selector/PropertyExpression.cs
index 8d00757..0cd5c47 100644
--- a/src/main/csharp/Selector/PropertyExpression.cs
+++ b/src/main/csharp/Selector/PropertyExpression.cs
@@ -1,53 +1,52 @@
-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 property expression.
- /// </summary>
- public class PropertyExpression : IExpression
- {
- private string name;
- public string Name
- {
- get { return name; }
- }
-
- public PropertyExpression(string name)
- {
- this.name = name;
- }
-
- public object Evaluate(MessageEvaluationContext message)
- {
- return message.GetProperty(name);
- }
-
- public override string ToString()
- {
- return name;
- }
-
- public override int GetHashCode()
- {
- return name.GetHashCode();
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Selector
+{
+ /// <summary>
+ /// Represents a property expression.
+ /// </summary>
+ public class PropertyExpression : IExpression
+ {
+ private string name;
+ public string Name
+ {
+ get { return name; }
+ }
+
+ public PropertyExpression(string name)
+ {
+ this.name = name;
+ }
+
+ public object Evaluate(MessageEvaluationContext message)
+ {
+ return message.GetProperty(name);
+ }
+
+ public override string ToString()
+ {
+ return name;
+ }
+
+ public override int GetHashCode()
+ {
+ return name.GetHashCode();
+ }
+ }
+}
diff --git a/src/main/csharp/Selector/SelectorParser.cs b/src/main/csharp/Selector/SelectorParser.cs
index 92226ac..efb05f5 100644
--- a/src/main/csharp/Selector/SelectorParser.cs
+++ b/src/main/csharp/Selector/SelectorParser.cs
@@ -1,1172 +1,1171 @@
-/* Generated By:CSharpCC: Do not edit this line. SelectorParser.cs */
-/**
- *
- * 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.
- */
-using System;
-using System.IO;
-using System.Text;
-using System.Collections;
-
-using Apache.NMS;
-
-namespace Apache.NMS.Selector
-{
- /// <summary>
- /// JMS Selector Parser generated by <a href="https://github.com/deveel/csharpcc">CSharpCC</a>
- ///
- /// Do not edit this .cs file directly - it is autogenerated from SelectorParser.csc
- /// using <c>csharpcc.exe -UNICODE_INPUT=true SelectorParser.csc</c>.
- ///
- /// SelectorParser.csc is adapted from
- /// <a href="https://raw.githubusercontent.com/apache/activemq/activemq-4.0/activemq-core/src/main/grammar/SelectorParser.jj">
- /// ActiveMQ 4.0 SelectorParser.jj</a>
- /// </summary>
- public class SelectorParser : SelectorParserConstants {
-
- public SelectorParser()
- : this(new StringReader(""))
- {
- }
-
- public IBooleanExpression Parse(string selector)
- {
- this.ReInit(new StringReader(selector));
-
- try
- {
- return this.JmsSelector();
- }
- catch(Exception e)
- {
- throw new InvalidSelectorException(selector, e);
- }
- }
-
- private IBooleanExpression AsBooleanExpression(IExpression value)
- {
- if(value is IBooleanExpression)
- {
- return (IBooleanExpression)value;
- }
- if(value is PropertyExpression)
- {
- return UnaryExpression.CreateBooleanCast(value);
- }
- throw new ParseException("IExpression will not result in a boolean value: " + value);
- }
-
-// ----------------------------------------------------------------------------
-// Grammar
-// ----------------------------------------------------------------------------
- public IBooleanExpression JmsSelector() {
- IExpression left = null;
- left = GetOrExpression();
- {return AsBooleanExpression(left);}
- throw new Exception("Missing return statement in function");
- }
-
- public IExpression GetOrExpression() {
- IExpression left;
- IExpression right;
- left = GetAndExpression();
- while (true) {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case OR:
- ;
- break;
- default:
- goto label_1;
- }
- mcc_consume_token(OR);
- right = GetAndExpression();
- left = LogicExpression.CreateOR(AsBooleanExpression(left), AsBooleanExpression(right));
- }label_1: ;
-
- {return left;}
- throw new Exception("Missing return statement in function");
- }
-
- public IExpression GetAndExpression() {
- IExpression left;
- IExpression right;
- left = GetEqualityExpression();
- while (true) {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case AND:
- ;
- break;
- default:
- goto label_2;
- }
- mcc_consume_token(AND);
- right = GetEqualityExpression();
- left = LogicExpression.CreateAND(AsBooleanExpression(left), AsBooleanExpression(right));
- }label_2: ;
-
- {return left;}
- throw new Exception("Missing return statement in function");
- }
-
- public IExpression GetEqualityExpression() {
- IExpression left;
- IExpression right;
- left = GetComparisonExpression();
- while (true) {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case IS:
- case 28:
- case 29:
- ;
- break;
- default:
- goto label_3;
- }
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case 28:
- mcc_consume_token(28);
- right = GetComparisonExpression();
- left = ComparisonExpression.CreateEqual(left, right);
- break;
- case 29:
- mcc_consume_token(29);
- right = GetComparisonExpression();
- left = ComparisonExpression.CreateNotEqual(left, right);
- break;
- default:
- if (mcc_2_1(2)) {
- mcc_consume_token(IS);
- mcc_consume_token(NULL);
- left = ComparisonExpression.CreateIsNull(left);
- } else {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case IS:
- mcc_consume_token(IS);
- mcc_consume_token(NOT);
- mcc_consume_token(NULL);
- left = ComparisonExpression.CreateIsNotNull(left);
- break;
- default:
- mcc_consume_token(-1);
- throw new ParseException();
- }
- }
- break;
- }
- }label_3: ;
-
- {return left;}
- throw new Exception("Missing return statement in function");
- }
-
- public IExpression GetComparisonExpression() {
- IExpression left;
- IExpression right;
- IExpression low;
- IExpression high;
- string t;
- string u;
- ArrayList list;
- left = GetAddExpression();
- while (true) {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case NOT:
- case BETWEEN:
- case LIKE:
- case IN:
- case 30:
- case 31:
- case 32:
- case 33:
- ;
- break;
- default:
- goto label_4;
- }
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case 30:
- mcc_consume_token(30);
- right = GetAddExpression();
- left = ComparisonExpression.CreateGreaterThan(left, right);
- break;
- case 31:
- mcc_consume_token(31);
- right = GetAddExpression();
- left = ComparisonExpression.CreateGreaterThanOrEqual(left, right);
- break;
- case 32:
- mcc_consume_token(32);
- right = GetAddExpression();
- left = ComparisonExpression.CreateLesserThan(left, right);
- break;
- case 33:
- mcc_consume_token(33);
- right = GetAddExpression();
- left = ComparisonExpression.CreateLesserThanOrEqual(left, right);
- break;
- case LIKE:
- u = null;
- mcc_consume_token(LIKE);
- t = GetStringLitteral();
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case ESCAPE:
- mcc_consume_token(ESCAPE);
- u = GetStringLitteral();
- break;
- default:
- ;
- break;
- }
- left = ComparisonExpression.CreateLike(left, t, u);
- break;
- default:
- if (mcc_2_2(2)) {
- u=null;
- mcc_consume_token(NOT);
- mcc_consume_token(LIKE);
- t = GetStringLitteral();
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case ESCAPE:
- mcc_consume_token(ESCAPE);
- u = GetStringLitteral();
- break;
- default:
- ;
- break;
- }
- left = ComparisonExpression.CreateNotLike(left, t, u);
- } else {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case BETWEEN:
- mcc_consume_token(BETWEEN);
- low = GetAddExpression();
- mcc_consume_token(AND);
- high = GetAddExpression();
- left = ComparisonExpression.CreateBetween(left, low, high);
- break;
- default:
- if (mcc_2_3(2)) {
- mcc_consume_token(NOT);
- mcc_consume_token(BETWEEN);
- low = GetAddExpression();
- mcc_consume_token(AND);
- high = GetAddExpression();
- left = ComparisonExpression.CreateNotBetween(left, low, high);
- } else {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case IN:
- mcc_consume_token(IN);
- mcc_consume_token(34);
- t = GetStringLitteral();
- list = new ArrayList();
- list.Add(t);
- while (true) {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case 35:
- ;
- break;
- default:
- goto label_5;
- }
- mcc_consume_token(35);
- t = GetStringLitteral();
- list.Add(t);
- }label_5: ;
-
- mcc_consume_token(36);
- left = ComparisonExpression.CreateIn(left, list);
- break;
- default:
- if (mcc_2_4(2)) {
- mcc_consume_token(NOT);
- mcc_consume_token(IN);
- mcc_consume_token(34);
- t = GetStringLitteral();
- list = new ArrayList();
- list.Add(t);
- while (true) {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case 35:
- ;
- break;
- default:
- goto label_6;
- }
- mcc_consume_token(35);
- t = GetStringLitteral();
- list.Add(t);
- }label_6: ;
-
- mcc_consume_token(36);
- left = ComparisonExpression.CreateNotIn(left, list);
- } else {
- mcc_consume_token(-1);
- throw new ParseException();
- }
- break;
- }
- }
- break;
- }
- }
- break;
- }
- }label_4: ;
-
- {return left;}
- throw new Exception("Missing return statement in function");
- }
-
- public IExpression GetAddExpression() {
- IExpression left;
- IExpression right;
- left = GetMultiplyExpression();
- while (true) {
- if (mcc_2_5(2147483647)) {
- ;
- } else {
- goto label_7;
- }
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case 37:
- mcc_consume_token(37);
- right = GetMultiplyExpression();
- left = ArithmeticExpression.CreatePlus(left, right);
- break;
- case 38:
- mcc_consume_token(38);
- right = GetMultiplyExpression();
- left = ArithmeticExpression.CreateMinus(left, right);
- break;
- default:
- mcc_consume_token(-1);
- throw new ParseException();
- }
- }label_7: ;
-
- {return left;}
- throw new Exception("Missing return statement in function");
- }
-
- public IExpression GetMultiplyExpression() {
- IExpression left;
- IExpression right;
- left = GetUnaryExpression();
- while (true) {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case 39:
- case 40:
- case 41:
- ;
- break;
- default:
- goto label_8;
- }
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case 39:
- mcc_consume_token(39);
- right = GetUnaryExpression();
- left = ArithmeticExpression.CreateMultiply(left, right);
- break;
- case 40:
- mcc_consume_token(40);
- right = GetUnaryExpression();
- left = ArithmeticExpression.CreateDivide(left, right);
- break;
- case 41:
- mcc_consume_token(41);
- right = GetUnaryExpression();
- left = ArithmeticExpression.CreateMod(left, right);
- break;
- default:
- mcc_consume_token(-1);
- throw new ParseException();
- }
- }label_8: ;
-
- {return left;}
- throw new Exception("Missing return statement in function");
- }
-
- public IExpression GetUnaryExpression() {
- IExpression left = null;
- if (mcc_2_6(2147483647)) {
- mcc_consume_token(37);
- left = GetUnaryExpression();
- } else {
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case 38:
- mcc_consume_token(38);
- left = GetUnaryExpression();
- left = UnaryExpression.CreateNegate(left);
- break;
- case NOT:
- mcc_consume_token(NOT);
- left = GetUnaryExpression();
- left = UnaryExpression.CreateNOT(AsBooleanExpression(left));
- break;
- case TRUE:
- case FALSE:
- case NULL:
- case DECIMAL_LITERAL:
- case HEX_LITERAL:
- case OCTAL_LITERAL:
- case FLOATING_POINT_LITERAL:
- case STRING_LITERAL:
- case ID:
- case 34:
- left = GetPrimaryExpression();
- break;
- default:
- mcc_consume_token(-1);
- throw new ParseException();
- }
- }
- {return left;}
- throw new Exception("Missing return statement in function");
- }
-
- public IExpression GetPrimaryExpression() {
- IExpression left = null;
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case TRUE:
- case FALSE:
- case NULL:
- case DECIMAL_LITERAL:
- case HEX_LITERAL:
- case OCTAL_LITERAL:
- case FLOATING_POINT_LITERAL:
- case STRING_LITERAL:
- left = GetLiteral();
- break;
- case ID:
- left = GetVariable();
- break;
- case 34:
- mcc_consume_token(34);
- left = GetOrExpression();
- mcc_consume_token(36);
- break;
- default:
- mcc_consume_token(-1);
- throw new ParseException();
- }
- {return left;}
- throw new Exception("Missing return statement in function");
- }
-
- public ConstantExpression GetLiteral() {
- Token t;
- string s;
- ConstantExpression left = null;
- switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
- case STRING_LITERAL:
- s = GetStringLitteral();
- left = new ConstantExpression(s);
- break;
- case DECIMAL_LITERAL:
- t = mcc_consume_token(DECIMAL_LITERAL);
- left = ConstantExpression.CreateFromDecimal(t.image);
- break;
- case HEX_LITERAL:
- t = mcc_consume_token(HEX_LITERAL);
- left = ConstantExpression.CreateFromHex(t.image);
- break;
- case OCTAL_LITERAL:
- t = mcc_consume_token(OCTAL_LITERAL);
- left = ConstantExpression.CreateFromOctal(t.image);
- break;
- case FLOATING_POINT_LITERAL:
- t = mcc_consume_token(FLOATING_POINT_LITERAL);
- left = ConstantExpression.CreateFloat(t.image);
- break;
- case TRUE:
- mcc_consume_token(TRUE);
- left = ConstantExpression.TRUE;
- break;
- case FALSE:
- mcc_consume_token(FALSE);
- left = ConstantExpression.FALSE;
- break;
- case NULL:
- mcc_consume_token(NULL);
- left = ConstantExpression.NULL;
- break;
- default:
- mcc_consume_token(-1);
- throw new ParseException();
- }
- {return left;}
- throw new Exception("Missing return statement in function");
- }
-
- public string GetStringLitteral() {
- Token t;
- StringBuilder rc = new StringBuilder();
- t = mcc_consume_token(STRING_LITERAL);
- // Decode the sting value.
- String image = t.image;
- for(int c = 1; c < image.Length - 1; c++)
- {
- char ch = image[c];
- if(ch == '\'')
- {
- c++;
- }
- rc.Append(ch);
- }
- {return rc.ToString();}
- throw new Exception("Missing return statement in function");
- }
-
- public PropertyExpression GetVariable() {
- Token t;
- PropertyExpression left = null;
- t = mcc_consume_token(ID);
- left = new PropertyExpression(t.image);
- {return left;}
- throw new Exception("Missing return statement in function");
- }
-
- private bool mcc_2_1(int xla) {
- mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
- try { return !mcc_3_1(); }
- catch(LookaheadSuccess) { return true; }
- }
-
- private bool mcc_2_2(int xla) {
- mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
- try { return !mcc_3_2(); }
- catch(LookaheadSuccess) { return true; }
- }
-
- private bool mcc_2_3(int xla) {
- mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
- try { return !mcc_3_3(); }
- catch(LookaheadSuccess) { return true; }
- }
-
- private bool mcc_2_4(int xla) {
- mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
- try { return !mcc_3_4(); }
- catch(LookaheadSuccess) { return true; }
- }
-
- private bool mcc_2_5(int xla) {
- mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
- try { return !mcc_3_5(); }
- catch(LookaheadSuccess) { return true; }
- }
-
- private bool mcc_2_6(int xla) {
- mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
- try { return !mcc_3_6(); }
- catch(LookaheadSuccess) { return true; }
- }
-
- private bool mcc_3R_57() {
- if (mcc_scan_token(ESCAPE)) return true;
- if (mcc_3R_36()) return true;
- return false;
- }
-
- private bool mcc_3R_19() {
- Token xsp;
- xsp = mcc_scanpos;
- if (mcc_3R_20()) {
- mcc_scanpos = xsp;
- if (mcc_3R_21()) {
- mcc_scanpos = xsp;
- if (mcc_3R_22()) return true;
- }
- }
- return false;
- }
-
- private bool mcc_3R_39() {
- if (mcc_3R_41()) return true;
- Token xsp;
- while (true) {
- xsp = mcc_scanpos;
- if (mcc_3R_42()) { mcc_scanpos = xsp; break; }
- }
- return false;
- }
-
- private bool mcc_3_4() {
- if (mcc_scan_token(NOT)) return true;
- if (mcc_scan_token(IN)) return true;
- if (mcc_scan_token(34)) return true;
- if (mcc_3R_36()) return true;
- Token xsp;
- while (true) {
- xsp = mcc_scanpos;
- if (mcc_3R_59()) { mcc_scanpos = xsp; break; }
- }
- if (mcc_scan_token(36)) return true;
- return false;
- }
-
- private bool mcc_3_6() {
- if (mcc_scan_token(37)) return true;
- if (mcc_3R_10()) return true;
- return false;
- }
-
- private bool mcc_3R_15() {
- if (mcc_3R_19()) return true;
- return false;
- }
-
- private bool mcc_3R_36() {
- if (mcc_scan_token(STRING_LITERAL)) return true;
- return false;
- }
-
- private bool mcc_3R_14() {
- if (mcc_scan_token(NOT)) return true;
- if (mcc_3R_10()) return true;
- return false;
- }
-
- private bool mcc_3R_12() {
- if (mcc_scan_token(37)) return true;
- if (mcc_3R_10()) return true;
- return false;
- }
-
- private bool mcc_3R_53() {
- if (mcc_scan_token(IN)) return true;
- if (mcc_scan_token(34)) return true;
- if (mcc_3R_36()) return true;
- Token xsp;
- while (true) {
- xsp = mcc_scanpos;
- if (mcc_3R_58()) { mcc_scanpos = xsp; break; }
- }
- if (mcc_scan_token(36)) return true;
- return false;
- }
-
- private bool mcc_3R_45() {
- if (mcc_scan_token(IS)) return true;
- if (mcc_scan_token(NOT)) return true;
- if (mcc_scan_token(NULL)) return true;
- return false;
- }
-
- private bool mcc_3R_13() {
- if (mcc_scan_token(38)) return true;
- if (mcc_3R_10()) return true;
- return false;
- }
-
- private bool mcc_3R_33() {
- if (mcc_scan_token(NULL)) return true;
- return false;
- }
-
- private bool mcc_3_1() {
- if (mcc_scan_token(IS)) return true;
- if (mcc_scan_token(NULL)) return true;
- return false;
- }
-
- private bool mcc_3R_10() {
- Token xsp;
- xsp = mcc_scanpos;
- if (mcc_3R_12()) {
- mcc_scanpos = xsp;
- if (mcc_3R_13()) {
- mcc_scanpos = xsp;
- if (mcc_3R_14()) {
- mcc_scanpos = xsp;
- if (mcc_3R_15()) return true;
- }
- }
- }
- return false;
- }
-
- private bool mcc_3R_44() {
- if (mcc_scan_token(29)) return true;
- if (mcc_3R_39()) return true;
- return false;
- }
-
- private bool mcc_3R_32() {
- if (mcc_scan_token(FALSE)) return true;
- return false;
- }
-
- private bool mcc_3_3() {
- if (mcc_scan_token(NOT)) return true;
- if (mcc_scan_token(BETWEEN)) return true;
- if (mcc_3R_41()) return true;
- if (mcc_scan_token(AND)) return true;
- if (mcc_3R_41()) return true;
- return false;
- }
-
- private bool mcc_3R_43() {
- if (mcc_scan_token(28)) return true;
- if (mcc_3R_39()) return true;
- return false;
- }
-
- private bool mcc_3R_40() {
- Token xsp;
- xsp = mcc_scanpos;
- if (mcc_3R_43()) {
- mcc_scanpos = xsp;
- if (mcc_3R_44()) {
- mcc_scanpos = xsp;
- if (mcc_3_1()) {
- mcc_scanpos = xsp;
- if (mcc_3R_45()) return true;
- }
- }
- }
- return false;
- }
-
- private bool mcc_3R_52() {
- if (mcc_scan_token(BETWEEN)) return true;
- if (mcc_3R_41()) return true;
- if (mcc_scan_token(AND)) return true;
- if (mcc_3R_41()) return true;
- return false;
- }
-
- private bool mcc_3R_31() {
- if (mcc_scan_token(TRUE)) return true;
- return false;
- }
-
- private bool mcc_3R_56() {
- if (mcc_scan_token(ESCAPE)) return true;
- if (mcc_3R_36()) return true;
- return false;
- }
-
- private bool mcc_3R_18() {
- if (mcc_scan_token(41)) return true;
- if (mcc_3R_10()) return true;
- return false;
- }
-
- private bool mcc_3R_30() {
- if (mcc_scan_token(FLOATING_POINT_LITERAL)) return true;
- return false;
- }
-
- private bool mcc_3R_37() {
- if (mcc_3R_39()) return true;
- Token xsp;
- while (true) {
- xsp = mcc_scanpos;
- if (mcc_3R_40()) { mcc_scanpos = xsp; break; }
- }
- return false;
- }
-
- private bool mcc_3_2() {
- if (mcc_scan_token(NOT)) return true;
- if (mcc_scan_token(LIKE)) return true;
- if (mcc_3R_36()) return true;
- Token xsp;
- xsp = mcc_scanpos;
- if (mcc_3R_57()) mcc_scanpos = xsp;
- return false;
- }
-
- private bool mcc_3R_51() {
- if (mcc_scan_token(LIKE)) return true;
- if (mcc_3R_36()) return true;
- Token xsp;
- xsp = mcc_scanpos;
- if (mcc_3R_56()) mcc_scanpos = xsp;
- return false;
- }
-
- private bool mcc_3R_17() {
- if (mcc_scan_token(40)) return true;
- if (mcc_3R_10()) return true;
- return false;
- }
-
- private bool mcc_3R_29() {
- if (mcc_scan_token(OCTAL_LITERAL)) return true;
- return false;
- }
-
- private bool mcc_3R_16() {
- if (mcc_scan_token(39)) return true;
- if (mcc_3R_10()) return true;
- return false;
- }
-
- private bool mcc_3R_11() {
- Token xsp;
- xsp = mcc_scanpos;
- if (mcc_3R_16()) {
- mcc_scanpos = xsp;
- if (mcc_3R_17()) {
- mcc_scanpos = xsp;
- if (mcc_3R_18()) return true;
- }
- }
- return false;
- }
-
- private bool mcc_3R_38() {
- if (mcc_scan_token(AND)) return true;
- if (mcc_3R_37()) return true;
- return false;
- }
-
- private bool mcc_3R_28() {
- if (mcc_scan_token(HEX_LITERAL)) return true;
- return false;
- }
-
- private bool mcc_3R_9() {
- if (mcc_3R_10()) return true;
- Token xsp;
- while (true) {
- xsp = mcc_scanpos;
- if (mcc_3R_11()) { mcc_scanpos = xsp; break; }
- }
- return false;
- }
-
- private bool mcc_3R_27() {
- if (mcc_scan_token(DECIMAL_LITERAL)) return true;
- return false;
- }
-
- private bool mcc_3R_55() {
- if (mcc_scan_token(38)) return true;
- if (mcc_3R_9()) return true;
- return false;
- }
-
- private bool mcc_3R_34() {
- if (mcc_3R_37()) return true;
- Token xsp;
- while (true) {
- xsp = mcc_scanpos;
- if (mcc_3R_38()) { mcc_scanpos = xsp; break; }
- }
- return false;
- }
-
- private bool mcc_3_5() {
- Token xsp;
- xsp = mcc_scanpos;
- if (mcc_scan_token(37)) {
- mcc_scanpos = xsp;
- if (mcc_scan_token(38)) return true;
- }
- if (mcc_3R_9()) return true;
- return false;
- }
-
- private bool mcc_3R_50() {
- if (mcc_scan_token(33)) return true;
- if (mcc_3R_41()) return true;
- return false;
- }
-
- private bool mcc_3R_54() {
- if (mcc_scan_token(37)) return true;
- if (mcc_3R_9()) return true;
- return false;
- }
-
- private bool mcc_3R_26() {
- if (mcc_3R_36()) return true;
- return false;
- }
-
- private bool mcc_3R_49() {
- if (mcc_scan_token(32)) return true;
- if (mcc_3R_41()) return true;
- return false;
- }
-
- private bool mcc_3R_59() {
- if (mcc_scan_token(35)) return true;
- if (mcc_3R_36()) return true;
- return false;
- }
-
- private bool mcc_3R_46() {
- Token xsp;
- xsp = mcc_scanpos;
- if (mcc_3R_54()) {
- mcc_scanpos = xsp;
- if (mcc_3R_55()) return true;
- }
- return false;
- }
-
- private bool mcc_3R_35() {
- if (mcc_scan_token(OR)) return true;
- if (mcc_3R_34()) return true;
- return false;
- }
-
- private bool mcc_3R_23() {
- Token xsp;
- xsp = mcc_scanpos;
- if (mcc_3R_26()) {
- mcc_scanpos = xsp;
- if (mcc_3R_27()) {
- mcc_scanpos = xsp;
- if (mcc_3R_28()) {
- mcc_scanpos = xsp;
- if (mcc_3R_29()) {
- mcc_scanpos = xsp;
- if (mcc_3R_30()) {
- mcc_scanpos = xsp;
- if (mcc_3R_31()) {
- mcc_scanpos = xsp;
- if (mcc_3R_32()) {
- mcc_scanpos = xsp;
- if (mcc_3R_33()) return true;
- }
- }
- }
- }
- }
- }
- }
- return false;
- }
-
- private bool mcc_3R_48() {
- if (mcc_scan_token(31)) return true;
- if (mcc_3R_41()) return true;
- return false;
- }
-
- private bool mcc_3R_24() {
- if (mcc_scan_token(ID)) return true;
- return false;
- }
-
- private bool mcc_3R_47() {
- if (mcc_scan_token(30)) return true;
- if (mcc_3R_41()) return true;
- return false;
- }
-
- private bool mcc_3R_42() {
- Token xsp;
- xsp = mcc_scanpos;
- if (mcc_3R_47()) {
- mcc_scanpos = xsp;
- if (mcc_3R_48()) {
- mcc_scanpos = xsp;
- if (mcc_3R_49()) {
- mcc_scanpos = xsp;
- if (mcc_3R_50()) {
- mcc_scanpos = xsp;
- if (mcc_3R_51()) {
- mcc_scanpos = xsp;
- if (mcc_3_2()) {
- mcc_scanpos = xsp;
- if (mcc_3R_52()) {
- mcc_scanpos = xsp;
- if (mcc_3_3()) {
- mcc_scanpos = xsp;
- if (mcc_3R_53()) {
- mcc_scanpos = xsp;
- if (mcc_3_4()) return true;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return false;
- }
-
- private bool mcc_3R_41() {
- if (mcc_3R_9()) return true;
- Token xsp;
- while (true) {
- xsp = mcc_scanpos;
- if (mcc_3R_46()) { mcc_scanpos = xsp; break; }
- }
- return false;
- }
-
- private bool mcc_3R_25() {
- if (mcc_3R_34()) return true;
- Token xsp;
- while (true) {
- xsp = mcc_scanpos;
- if (mcc_3R_35()) { mcc_scanpos = xsp; break; }
- }
- return false;
- }
-
- private bool mcc_3R_22() {
- if (mcc_scan_token(34)) return true;
- if (mcc_3R_25()) return true;
- if (mcc_scan_token(36)) return true;
- return false;
- }
-
- private bool mcc_3R_21() {
- if (mcc_3R_24()) return true;
- return false;
- }
-
- private bool mcc_3R_20() {
- if (mcc_3R_23()) return true;
- return false;
- }
-
- private bool mcc_3R_58() {
- if (mcc_scan_token(35)) return true;
- if (mcc_3R_36()) return true;
- return false;
- }
-
- public SelectorParserTokenManager token_source;
- SimpleCharStream mcc_input_stream;
- public Token token, mcc_nt;
- private int mcc_ntk;
- private Token mcc_scanpos, mcc_lastpos;
- private int mcc_la;
- public bool lookingAhead = false;
- //private bool mcc_semLA;
-
- public SelectorParser(System.IO.Stream stream) {
- mcc_input_stream = new SimpleCharStream(stream, 1, 1);
- token_source = new SelectorParserTokenManager(mcc_input_stream);
- token = new Token();
- mcc_ntk = -1;
- }
-
- public void ReInit(System.IO.Stream stream) {
- mcc_input_stream.ReInit(stream, 1, 1);
- token_source.ReInit(mcc_input_stream);
- token = new Token();
- mcc_ntk = -1;
- }
-
- public SelectorParser(System.IO.TextReader stream) {
- mcc_input_stream = new SimpleCharStream(stream, 1, 1);
- token_source = new SelectorParserTokenManager(mcc_input_stream);
- token = new Token();
- mcc_ntk = -1;
- }
-
- public void ReInit(System.IO.TextReader stream) {
- mcc_input_stream.ReInit(stream, 1, 1);
- token_source.ReInit(mcc_input_stream);
- token = new Token();
- mcc_ntk = -1;
- }
-
- public SelectorParser(SelectorParserTokenManager tm) {
- token_source = tm;
- token = new Token();
- mcc_ntk = -1;
- }
-
- public void ReInit(SelectorParserTokenManager tm) {
- token_source = tm;
- token = new Token();
- mcc_ntk = -1;
- }
-
- private Token mcc_consume_token(int kind) {
- Token oldToken = null;
- if ((oldToken = token).next != null) token = token.next;
- else token = token.next = token_source.GetNextToken();
- mcc_ntk = -1;
- if (token.kind == kind) {
- return token;
- }
- token = oldToken;
- throw GenerateParseException();
- }
-
- private class LookaheadSuccess : System.Exception { }
- private LookaheadSuccess mcc_ls = new LookaheadSuccess();
- private bool mcc_scan_token(int kind) {
- if (mcc_scanpos == mcc_lastpos) {
- mcc_la--;
- if (mcc_scanpos.next == null) {
- mcc_lastpos = mcc_scanpos = mcc_scanpos.next = token_source.GetNextToken();
- } else {
- mcc_lastpos = mcc_scanpos = mcc_scanpos.next;
- }
- } else {
- mcc_scanpos = mcc_scanpos.next;
- }
- if (mcc_scanpos.kind != kind) return true;
- if (mcc_la == 0 && mcc_scanpos == mcc_lastpos) throw mcc_ls;
- return false;
- }
-
- public Token GetNextToken() {
- if (token.next != null) token = token.next;
- else token = token.next = token_source.GetNextToken();
- mcc_ntk = -1;
- return token;
- }
-
- public Token GetToken(int index) {
- Token t = lookingAhead ? mcc_scanpos : token;
- for (int i = 0; i < index; i++) {
- if (t.next != null) t = t.next;
- else t = t.next = token_source.GetNextToken();
- }
- return t;
- }
-
- private int mcc_mntk() {
- if ((mcc_nt=token.next) == null)
- return (mcc_ntk = (token.next=token_source.GetNextToken()).kind);
- else
- return (mcc_ntk = mcc_nt.kind);
- }
-
- public ParseException GenerateParseException() {
- Token errortok = token.next;
- int line = errortok.beginLine, column = errortok.beginColumn;
- string mess = (errortok.kind == 0) ? tokenImage[0] : errortok.image;
- return new ParseException("Parse error at line " + line + ", column " + column + ". Encountered: " + mess);
- }
-
- public void enable_tracing() {
- }
-
- public void disable_tracing() {
- }
-
-}
-
+/* Generated By:CSharpCC: Do not edit this line. SelectorParser.cs */
+/*
+ * 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.
+ */
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+
+using Apache.NMS;
+
+namespace Apache.NMS.Selector
+{
+ /// <summary>
+ /// JMS Selector Parser generated by <a href="https://github.com/deveel/csharpcc">CSharpCC</a>
+ ///
+ /// Do not edit this .cs file directly - it is autogenerated from SelectorParser.csc
+ /// using <c>csharpcc.exe -UNICODE_INPUT=true SelectorParser.csc</c>.
+ ///
+ /// SelectorParser.csc is adapted from
+ /// <a href="https://raw.githubusercontent.com/apache/activemq/activemq-4.0/activemq-core/src/main/grammar/SelectorParser.jj">
+ /// ActiveMQ 4.0 SelectorParser.jj</a>
+ /// </summary>
+ public class SelectorParser : SelectorParserConstants {
+
+ public SelectorParser()
+ : this(new StringReader(""))
+ {
+ }
+
+ public IBooleanExpression Parse(string selector)
+ {
+ this.ReInit(new StringReader(selector));
+
+ try
+ {
+ return this.JmsSelector();
+ }
+ catch(Exception e)
+ {
+ throw new InvalidSelectorException(selector, e);
+ }
+ }
+
+ private IBooleanExpression AsBooleanExpression(IExpression value)
+ {
+ if(value is IBooleanExpression)
+ {
+ return (IBooleanExpression)value;
+ }
+ if(value is PropertyExpression)
+ {
+ return UnaryExpression.CreateBooleanCast(value);
+ }
+ throw new ParseException("IExpression will not result in a boolean value: " + value);
+ }
+
+// ----------------------------------------------------------------------------
+// Grammar
+// ----------------------------------------------------------------------------
+ public IBooleanExpression JmsSelector() {
+ IExpression left = null;
+ left = GetOrExpression();
+ {return AsBooleanExpression(left);}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public IExpression GetOrExpression() {
+ IExpression left;
+ IExpression right;
+ left = GetAndExpression();
+ while (true) {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case OR:
+ ;
+ break;
+ default:
+ goto label_1;
+ }
+ mcc_consume_token(OR);
+ right = GetAndExpression();
+ left = LogicExpression.CreateOR(AsBooleanExpression(left), AsBooleanExpression(right));
+ }label_1: ;
+
+ {return left;}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public IExpression GetAndExpression() {
+ IExpression left;
+ IExpression right;
+ left = GetEqualityExpression();
+ while (true) {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case AND:
+ ;
+ break;
+ default:
+ goto label_2;
+ }
+ mcc_consume_token(AND);
+ right = GetEqualityExpression();
+ left = LogicExpression.CreateAND(AsBooleanExpression(left), AsBooleanExpression(right));
+ }label_2: ;
+
+ {return left;}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public IExpression GetEqualityExpression() {
+ IExpression left;
+ IExpression right;
+ left = GetComparisonExpression();
+ while (true) {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case IS:
+ case 28:
+ case 29:
+ ;
+ break;
+ default:
+ goto label_3;
+ }
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case 28:
+ mcc_consume_token(28);
+ right = GetComparisonExpression();
+ left = ComparisonExpression.CreateEqual(left, right);
+ break;
+ case 29:
+ mcc_consume_token(29);
+ right = GetComparisonExpression();
+ left = ComparisonExpression.CreateNotEqual(left, right);
+ break;
+ default:
+ if (mcc_2_1(2)) {
+ mcc_consume_token(IS);
+ mcc_consume_token(NULL);
+ left = ComparisonExpression.CreateIsNull(left);
+ } else {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case IS:
+ mcc_consume_token(IS);
+ mcc_consume_token(NOT);
+ mcc_consume_token(NULL);
+ left = ComparisonExpression.CreateIsNotNull(left);
+ break;
+ default:
+ mcc_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ break;
+ }
+ }label_3: ;
+
+ {return left;}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public IExpression GetComparisonExpression() {
+ IExpression left;
+ IExpression right;
+ IExpression low;
+ IExpression high;
+ string t;
+ string u;
+ ArrayList list;
+ left = GetAddExpression();
+ while (true) {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case NOT:
+ case BETWEEN:
+ case LIKE:
+ case IN:
+ case 30:
+ case 31:
+ case 32:
+ case 33:
+ ;
+ break;
+ default:
+ goto label_4;
+ }
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case 30:
+ mcc_consume_token(30);
+ right = GetAddExpression();
+ left = ComparisonExpression.CreateGreaterThan(left, right);
+ break;
+ case 31:
+ mcc_consume_token(31);
+ right = GetAddExpression();
+ left = ComparisonExpression.CreateGreaterThanOrEqual(left, right);
+ break;
+ case 32:
+ mcc_consume_token(32);
+ right = GetAddExpression();
+ left = ComparisonExpression.CreateLesserThan(left, right);
+ break;
+ case 33:
+ mcc_consume_token(33);
+ right = GetAddExpression();
+ left = ComparisonExpression.CreateLesserThanOrEqual(left, right);
+ break;
+ case LIKE:
+ u = null;
+ mcc_consume_token(LIKE);
+ t = GetStringLitteral();
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case ESCAPE:
+ mcc_consume_token(ESCAPE);
+ u = GetStringLitteral();
+ break;
+ default:
+ ;
+ break;
+ }
+ left = ComparisonExpression.CreateLike(left, t, u);
+ break;
+ default:
+ if (mcc_2_2(2)) {
+ u=null;
+ mcc_consume_token(NOT);
+ mcc_consume_token(LIKE);
+ t = GetStringLitteral();
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case ESCAPE:
+ mcc_consume_token(ESCAPE);
+ u = GetStringLitteral();
+ break;
+ default:
+ ;
+ break;
+ }
+ left = ComparisonExpression.CreateNotLike(left, t, u);
+ } else {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case BETWEEN:
+ mcc_consume_token(BETWEEN);
+ low = GetAddExpression();
+ mcc_consume_token(AND);
+ high = GetAddExpression();
+ left = ComparisonExpression.CreateBetween(left, low, high);
+ break;
+ default:
+ if (mcc_2_3(2)) {
+ mcc_consume_token(NOT);
+ mcc_consume_token(BETWEEN);
+ low = GetAddExpression();
+ mcc_consume_token(AND);
+ high = GetAddExpression();
+ left = ComparisonExpression.CreateNotBetween(left, low, high);
+ } else {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case IN:
+ mcc_consume_token(IN);
+ mcc_consume_token(34);
+ t = GetStringLitteral();
+ list = new ArrayList();
+ list.Add(t);
+ while (true) {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case 35:
+ ;
+ break;
+ default:
+ goto label_5;
+ }
+ mcc_consume_token(35);
+ t = GetStringLitteral();
+ list.Add(t);
+ }label_5: ;
+
+ mcc_consume_token(36);
+ left = ComparisonExpression.CreateIn(left, list);
+ break;
+ default:
+ if (mcc_2_4(2)) {
+ mcc_consume_token(NOT);
+ mcc_consume_token(IN);
+ mcc_consume_token(34);
+ t = GetStringLitteral();
+ list = new ArrayList();
+ list.Add(t);
+ while (true) {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case 35:
+ ;
+ break;
+ default:
+ goto label_6;
+ }
+ mcc_consume_token(35);
+ t = GetStringLitteral();
+ list.Add(t);
+ }label_6: ;
+
+ mcc_consume_token(36);
+ left = ComparisonExpression.CreateNotIn(left, list);
+ } else {
+ mcc_consume_token(-1);
+ throw new ParseException();
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }label_4: ;
+
+ {return left;}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public IExpression GetAddExpression() {
+ IExpression left;
+ IExpression right;
+ left = GetMultiplyExpression();
+ while (true) {
+ if (mcc_2_5(2147483647)) {
+ ;
+ } else {
+ goto label_7;
+ }
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case 37:
+ mcc_consume_token(37);
+ right = GetMultiplyExpression();
+ left = ArithmeticExpression.CreatePlus(left, right);
+ break;
+ case 38:
+ mcc_consume_token(38);
+ right = GetMultiplyExpression();
+ left = ArithmeticExpression.CreateMinus(left, right);
+ break;
+ default:
+ mcc_consume_token(-1);
+ throw new ParseException();
+ }
+ }label_7: ;
+
+ {return left;}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public IExpression GetMultiplyExpression() {
+ IExpression left;
+ IExpression right;
+ left = GetUnaryExpression();
+ while (true) {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case 39:
+ case 40:
+ case 41:
+ ;
+ break;
+ default:
+ goto label_8;
+ }
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case 39:
+ mcc_consume_token(39);
+ right = GetUnaryExpression();
+ left = ArithmeticExpression.CreateMultiply(left, right);
+ break;
+ case 40:
+ mcc_consume_token(40);
+ right = GetUnaryExpression();
+ left = ArithmeticExpression.CreateDivide(left, right);
+ break;
+ case 41:
+ mcc_consume_token(41);
+ right = GetUnaryExpression();
+ left = ArithmeticExpression.CreateMod(left, right);
+ break;
+ default:
+ mcc_consume_token(-1);
+ throw new ParseException();
+ }
+ }label_8: ;
+
+ {return left;}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public IExpression GetUnaryExpression() {
+ IExpression left = null;
+ if (mcc_2_6(2147483647)) {
+ mcc_consume_token(37);
+ left = GetUnaryExpression();
+ } else {
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case 38:
+ mcc_consume_token(38);
+ left = GetUnaryExpression();
+ left = UnaryExpression.CreateNegate(left);
+ break;
+ case NOT:
+ mcc_consume_token(NOT);
+ left = GetUnaryExpression();
+ left = UnaryExpression.CreateNOT(AsBooleanExpression(left));
+ break;
+ case TRUE:
+ case FALSE:
+ case NULL:
+ case DECIMAL_LITERAL:
+ case HEX_LITERAL:
+ case OCTAL_LITERAL:
+ case FLOATING_POINT_LITERAL:
+ case STRING_LITERAL:
+ case ID:
+ case 34:
+ left = GetPrimaryExpression();
+ break;
+ default:
+ mcc_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ {return left;}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public IExpression GetPrimaryExpression() {
+ IExpression left = null;
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case TRUE:
+ case FALSE:
+ case NULL:
+ case DECIMAL_LITERAL:
+ case HEX_LITERAL:
+ case OCTAL_LITERAL:
+ case FLOATING_POINT_LITERAL:
+ case STRING_LITERAL:
+ left = GetLiteral();
+ break;
+ case ID:
+ left = GetVariable();
+ break;
+ case 34:
+ mcc_consume_token(34);
+ left = GetOrExpression();
+ mcc_consume_token(36);
+ break;
+ default:
+ mcc_consume_token(-1);
+ throw new ParseException();
+ }
+ {return left;}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public ConstantExpression GetLiteral() {
+ Token t;
+ string s;
+ ConstantExpression left = null;
+ switch ((mcc_ntk==-1)?mcc_mntk():mcc_ntk) {
+ case STRING_LITERAL:
+ s = GetStringLitteral();
+ left = new ConstantExpression(s);
+ break;
+ case DECIMAL_LITERAL:
+ t = mcc_consume_token(DECIMAL_LITERAL);
+ left = ConstantExpression.CreateFromDecimal(t.image);
+ break;
+ case HEX_LITERAL:
+ t = mcc_consume_token(HEX_LITERAL);
+ left = ConstantExpression.CreateFromHex(t.image);
+ break;
+ case OCTAL_LITERAL:
+ t = mcc_consume_token(OCTAL_LITERAL);
+ left = ConstantExpression.CreateFromOctal(t.image);
+ break;
+ case FLOATING_POINT_LITERAL:
+ t = mcc_consume_token(FLOATING_POINT_LITERAL);
+ left = ConstantExpression.CreateFloat(t.image);
+ break;
+ case TRUE:
+ mcc_consume_token(TRUE);
+ left = ConstantExpression.TRUE;
+ break;
+ case FALSE:
+ mcc_consume_token(FALSE);
+ left = ConstantExpression.FALSE;
+ break;
+ case NULL:
+ mcc_consume_token(NULL);
+ left = ConstantExpression.NULL;
+ break;
+ default:
+ mcc_consume_token(-1);
+ throw new ParseException();
+ }
+ {return left;}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public string GetStringLitteral() {
+ Token t;
+ StringBuilder rc = new StringBuilder();
+ t = mcc_consume_token(STRING_LITERAL);
+ // Decode the sting value.
+ String image = t.image;
+ for(int c = 1; c < image.Length - 1; c++)
+ {
+ char ch = image[c];
+ if(ch == '\'')
+ {
+ c++;
+ }
+ rc.Append(ch);
+ }
+ {return rc.ToString();}
+ throw new Exception("Missing return statement in function");
+ }
+
+ public PropertyExpression GetVariable() {
+ Token t;
+ PropertyExpression left = null;
+ t = mcc_consume_token(ID);
+ left = new PropertyExpression(t.image);
+ {return left;}
+ throw new Exception("Missing return statement in function");
+ }
+
+ private bool mcc_2_1(int xla) {
+ mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
+ try { return !mcc_3_1(); }
+ catch(LookaheadSuccess) { return true; }
+ }
+
+ private bool mcc_2_2(int xla) {
+ mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
+ try { return !mcc_3_2(); }
+ catch(LookaheadSuccess) { return true; }
+ }
+
+ private bool mcc_2_3(int xla) {
+ mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
+ try { return !mcc_3_3(); }
+ catch(LookaheadSuccess) { return true; }
+ }
+
+ private bool mcc_2_4(int xla) {
+ mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
+ try { return !mcc_3_4(); }
+ catch(LookaheadSuccess) { return true; }
+ }
+
+ private bool mcc_2_5(int xla) {
+ mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
+ try { return !mcc_3_5(); }
+ catch(LookaheadSuccess) { return true; }
+ }
+
+ private bool mcc_2_6(int xla) {
+ mcc_la = xla; mcc_lastpos = mcc_scanpos = token;
+ try { return !mcc_3_6(); }
+ catch(LookaheadSuccess) { return true; }
+ }
+
+ private bool mcc_3R_57() {
+ if (mcc_scan_token(ESCAPE)) return true;
+ if (mcc_3R_36()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_19() {
+ Token xsp;
+ xsp = mcc_scanpos;
+ if (mcc_3R_20()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_21()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_22()) return true;
+ }
+ }
+ return false;
+ }
+
+ private bool mcc_3R_39() {
+ if (mcc_3R_41()) return true;
+ Token xsp;
+ while (true) {
+ xsp = mcc_scanpos;
+ if (mcc_3R_42()) { mcc_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private bool mcc_3_4() {
+ if (mcc_scan_token(NOT)) return true;
+ if (mcc_scan_token(IN)) return true;
+ if (mcc_scan_token(34)) return true;
+ if (mcc_3R_36()) return true;
+ Token xsp;
+ while (true) {
+ xsp = mcc_scanpos;
+ if (mcc_3R_59()) { mcc_scanpos = xsp; break; }
+ }
+ if (mcc_scan_token(36)) return true;
+ return false;
+ }
+
+ private bool mcc_3_6() {
+ if (mcc_scan_token(37)) return true;
+ if (mcc_3R_10()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_15() {
+ if (mcc_3R_19()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_36() {
+ if (mcc_scan_token(STRING_LITERAL)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_14() {
+ if (mcc_scan_token(NOT)) return true;
+ if (mcc_3R_10()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_12() {
+ if (mcc_scan_token(37)) return true;
+ if (mcc_3R_10()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_53() {
+ if (mcc_scan_token(IN)) return true;
+ if (mcc_scan_token(34)) return true;
+ if (mcc_3R_36()) return true;
+ Token xsp;
+ while (true) {
+ xsp = mcc_scanpos;
+ if (mcc_3R_58()) { mcc_scanpos = xsp; break; }
+ }
+ if (mcc_scan_token(36)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_45() {
+ if (mcc_scan_token(IS)) return true;
+ if (mcc_scan_token(NOT)) return true;
+ if (mcc_scan_token(NULL)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_13() {
+ if (mcc_scan_token(38)) return true;
+ if (mcc_3R_10()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_33() {
+ if (mcc_scan_token(NULL)) return true;
+ return false;
+ }
+
+ private bool mcc_3_1() {
+ if (mcc_scan_token(IS)) return true;
+ if (mcc_scan_token(NULL)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_10() {
+ Token xsp;
+ xsp = mcc_scanpos;
+ if (mcc_3R_12()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_13()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_14()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_15()) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private bool mcc_3R_44() {
+ if (mcc_scan_token(29)) return true;
+ if (mcc_3R_39()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_32() {
+ if (mcc_scan_token(FALSE)) return true;
+ return false;
+ }
+
+ private bool mcc_3_3() {
+ if (mcc_scan_token(NOT)) return true;
+ if (mcc_scan_token(BETWEEN)) return true;
+ if (mcc_3R_41()) return true;
+ if (mcc_scan_token(AND)) return true;
+ if (mcc_3R_41()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_43() {
+ if (mcc_scan_token(28)) return true;
+ if (mcc_3R_39()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_40() {
+ Token xsp;
+ xsp = mcc_scanpos;
+ if (mcc_3R_43()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_44()) {
+ mcc_scanpos = xsp;
+ if (mcc_3_1()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_45()) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private bool mcc_3R_52() {
+ if (mcc_scan_token(BETWEEN)) return true;
+ if (mcc_3R_41()) return true;
+ if (mcc_scan_token(AND)) return true;
+ if (mcc_3R_41()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_31() {
+ if (mcc_scan_token(TRUE)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_56() {
+ if (mcc_scan_token(ESCAPE)) return true;
+ if (mcc_3R_36()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_18() {
+ if (mcc_scan_token(41)) return true;
+ if (mcc_3R_10()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_30() {
+ if (mcc_scan_token(FLOATING_POINT_LITERAL)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_37() {
+ if (mcc_3R_39()) return true;
+ Token xsp;
+ while (true) {
+ xsp = mcc_scanpos;
+ if (mcc_3R_40()) { mcc_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private bool mcc_3_2() {
+ if (mcc_scan_token(NOT)) return true;
+ if (mcc_scan_token(LIKE)) return true;
+ if (mcc_3R_36()) return true;
+ Token xsp;
+ xsp = mcc_scanpos;
+ if (mcc_3R_57()) mcc_scanpos = xsp;
+ return false;
+ }
+
+ private bool mcc_3R_51() {
+ if (mcc_scan_token(LIKE)) return true;
+ if (mcc_3R_36()) return true;
+ Token xsp;
+ xsp = mcc_scanpos;
+ if (mcc_3R_56()) mcc_scanpos = xsp;
+ return false;
+ }
+
+ private bool mcc_3R_17() {
+ if (mcc_scan_token(40)) return true;
+ if (mcc_3R_10()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_29() {
+ if (mcc_scan_token(OCTAL_LITERAL)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_16() {
+ if (mcc_scan_token(39)) return true;
+ if (mcc_3R_10()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_11() {
+ Token xsp;
+ xsp = mcc_scanpos;
+ if (mcc_3R_16()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_17()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_18()) return true;
+ }
+ }
+ return false;
+ }
+
+ private bool mcc_3R_38() {
+ if (mcc_scan_token(AND)) return true;
+ if (mcc_3R_37()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_28() {
+ if (mcc_scan_token(HEX_LITERAL)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_9() {
+ if (mcc_3R_10()) return true;
+ Token xsp;
+ while (true) {
+ xsp = mcc_scanpos;
+ if (mcc_3R_11()) { mcc_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private bool mcc_3R_27() {
+ if (mcc_scan_token(DECIMAL_LITERAL)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_55() {
+ if (mcc_scan_token(38)) return true;
+ if (mcc_3R_9()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_34() {
+ if (mcc_3R_37()) return true;
+ Token xsp;
+ while (true) {
+ xsp = mcc_scanpos;
+ if (mcc_3R_38()) { mcc_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private bool mcc_3_5() {
+ Token xsp;
+ xsp = mcc_scanpos;
+ if (mcc_scan_token(37)) {
+ mcc_scanpos = xsp;
+ if (mcc_scan_token(38)) return true;
+ }
+ if (mcc_3R_9()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_50() {
+ if (mcc_scan_token(33)) return true;
+ if (mcc_3R_41()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_54() {
+ if (mcc_scan_token(37)) return true;
+ if (mcc_3R_9()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_26() {
+ if (mcc_3R_36()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_49() {
+ if (mcc_scan_token(32)) return true;
+ if (mcc_3R_41()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_59() {
+ if (mcc_scan_token(35)) return true;
+ if (mcc_3R_36()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_46() {
+ Token xsp;
+ xsp = mcc_scanpos;
+ if (mcc_3R_54()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_55()) return true;
+ }
+ return false;
+ }
+
+ private bool mcc_3R_35() {
+ if (mcc_scan_token(OR)) return true;
+ if (mcc_3R_34()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_23() {
+ Token xsp;
+ xsp = mcc_scanpos;
+ if (mcc_3R_26()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_27()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_28()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_29()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_30()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_31()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_32()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_33()) return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private bool mcc_3R_48() {
+ if (mcc_scan_token(31)) return true;
+ if (mcc_3R_41()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_24() {
+ if (mcc_scan_token(ID)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_47() {
+ if (mcc_scan_token(30)) return true;
+ if (mcc_3R_41()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_42() {
+ Token xsp;
+ xsp = mcc_scanpos;
+ if (mcc_3R_47()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_48()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_49()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_50()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_51()) {
+ mcc_scanpos = xsp;
+ if (mcc_3_2()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_52()) {
+ mcc_scanpos = xsp;
+ if (mcc_3_3()) {
+ mcc_scanpos = xsp;
+ if (mcc_3R_53()) {
+ mcc_scanpos = xsp;
+ if (mcc_3_4()) return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private bool mcc_3R_41() {
+ if (mcc_3R_9()) return true;
+ Token xsp;
+ while (true) {
+ xsp = mcc_scanpos;
+ if (mcc_3R_46()) { mcc_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private bool mcc_3R_25() {
+ if (mcc_3R_34()) return true;
+ Token xsp;
+ while (true) {
+ xsp = mcc_scanpos;
+ if (mcc_3R_35()) { mcc_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private bool mcc_3R_22() {
+ if (mcc_scan_token(34)) return true;
+ if (mcc_3R_25()) return true;
+ if (mcc_scan_token(36)) return true;
+ return false;
+ }
+
+ private bool mcc_3R_21() {
+ if (mcc_3R_24()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_20() {
+ if (mcc_3R_23()) return true;
+ return false;
+ }
+
+ private bool mcc_3R_58() {
+ if (mcc_scan_token(35)) return true;
+ if (mcc_3R_36()) return true;
+ return false;
+ }
+
+ public SelectorParserTokenManager token_source;
+ SimpleCharStream mcc_input_stream;
+ public Token token, mcc_nt;
+ private int mcc_ntk;
+ private Token mcc_scanpos, mcc_lastpos;
+ private int mcc_la;
+ public bool lookingAhead = false;
+ //private bool mcc_semLA;
+
+ public SelectorParser(System.IO.Stream stream) {
+ mcc_input_stream = new SimpleCharStream(stream, 1, 1);
+ token_source = new SelectorParserTokenManager(mcc_input_stream);
+ token = new Token();
+ mcc_ntk = -1;
+ }
+
+ public void ReInit(System.IO.Stream stream) {
+ mcc_input_stream.ReInit(stream, 1, 1);
+ token_source.ReInit(mcc_input_stream);
+ token = new Token();
+ mcc_ntk = -1;
+ }
+
+ public SelectorParser(System.IO.TextReader stream) {
+ mcc_input_stream = new SimpleCharStream(stream, 1, 1);
+ token_source = new SelectorParserTokenManager(mcc_input_stream);
+ token = new Token();
+ mcc_ntk = -1;
+ }
+
+ public void ReInit(System.IO.TextReader stream) {
+ mcc_input_stream.ReInit(stream, 1, 1);
+ token_source.ReInit(mcc_input_stream);
+ token = new Token();
+ mcc_ntk = -1;
+ }
+
+ public SelectorParser(SelectorParserTokenManager tm) {
+ token_source = tm;
+ token = new Token();
+ mcc_ntk = -1;
+ }
+
+ public void ReInit(SelectorParserTokenManager tm) {
+ token_source = tm;
+ token = new Token();
+ mcc_ntk = -1;
+ }
+
+ private Token mcc_consume_token(int kind) {
+ Token oldToken = null;
+ if ((oldToken = token).next != null) token = token.next;
+ else token = token.next = token_source.GetNextToken();
+ mcc_ntk = -1;
+ if (token.kind == kind) {
+ return token;
+ }
+ token = oldToken;
+ throw GenerateParseException();
+ }
+
+ private class LookaheadSuccess : System.Exception { }
+ private LookaheadSuccess mcc_ls = new LookaheadSuccess();
+ private bool mcc_scan_token(int kind) {
+ if (mcc_scanpos == mcc_lastpos) {
+ mcc_la--;
+ if (mcc_scanpos.next == null) {
+ mcc_lastpos = mcc_scanpos = mcc_scanpos.next = token_source.GetNextToken();
+ } else {
+ mcc_lastpos = mcc_scanpos = mcc_scanpos.next;
+ }
+ } else {
+ mcc_scanpos = mcc_scanpos.next;
+ }
+ if (mcc_scanpos.kind != kind) return true;
+ if (mcc_la == 0 && mcc_scanpos == mcc_lastpos) throw mcc_ls;
+ return false;
+ }
+
+ public Token GetNextToken() {
+ if (token.next != null) token = token.next;
+ else token = token.next = token_source.GetNextToken();
+ mcc_ntk = -1;
+ return token;
+ }
+
+ public Token GetToken(int index) {
+ Token t = lookingAhead ? mcc_scanpos : token;
+ for (int i = 0; i < index; i++) {
+ if (t.next != null) t = t.next;
+ else t = t.next = token_source.GetNextToken();
+ }
+ return t;
+ }
+
+ private int mcc_mntk() {
+ if ((mcc_nt=token.next) == null)
+ return (mcc_ntk = (token.next=token_source.GetNextToken()).kind);
+ else
+ return (mcc_ntk = mcc_nt.kind);
+ }
+
+ public ParseException GenerateParseException() {
+ Token errortok = token.next;
+ int line = errortok.beginLine, column = errortok.beginColumn;
+ string mess = (errortok.kind == 0) ? tokenImage[0] : errortok.image;
+ return new ParseException("Parse error at line " + line + ", column " + column + ". Encountered: " + mess);
+ }
+
+ public void enable_tracing() {
+ }
+
+ public void disable_tracing() {
+ }
+
+}
+
}
\ No newline at end of file
diff --git a/src/main/csharp/Selector/SelectorParser.csc b/src/main/csharp/Selector/SelectorParser.csc
index be05ab8..d7fa5c8 100644
--- a/src/main/csharp/Selector/SelectorParser.csc
+++ b/src/main/csharp/Selector/SelectorParser.csc
@@ -1,16 +1,15 @@
-/**
- *
- * 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.
+/*
+ * 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,
+ * (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.
diff --git a/src/main/csharp/Selector/SelectorParserConstants.cs b/src/main/csharp/Selector/SelectorParserConstants.cs
index 5f75539..74c5362 100644
--- a/src/main/csharp/Selector/SelectorParserConstants.cs
+++ b/src/main/csharp/Selector/SelectorParserConstants.cs
@@ -1,75 +1,75 @@
-/* Generated By:CSharpCC: Do not edit this line. SelectorParserConstants.cs */
-public class SelectorParserConstants {
-
- public const int EOF = 0;
- public const int LINE_COMMENT = 6;
- public const int BLOCK_COMMENT = 7;
- public const int NOT = 8;
- public const int AND = 9;
- public const int OR = 10;
- public const int BETWEEN = 11;
- public const int LIKE = 12;
- public const int ESCAPE = 13;
- public const int IN = 14;
- public const int IS = 15;
- public const int TRUE = 16;
- public const int FALSE = 17;
- public const int NULL = 18;
- public const int XPATH = 19;
- public const int XQUERY = 20;
- public const int DECIMAL_LITERAL = 21;
- public const int HEX_LITERAL = 22;
- public const int OCTAL_LITERAL = 23;
- public const int FLOATING_POINT_LITERAL = 24;
- public const int EXPONENT = 25;
- public const int STRING_LITERAL = 26;
- public const int ID = 27;
-
- public const int DEFAULT = 0;
-
- public readonly string[] tokenImage = {
- "<EOF>",
- "\" \"",
- "\"\\t\"",
- "\"\\n\"",
- "\"\\r\"",
- "\"\\f\"",
- "<LINE_COMMENT>",
- "<BLOCK_COMMENT>",
- "\"NOT\"",
- "\"AND\"",
- "\"OR\"",
- "\"BETWEEN\"",
- "\"LIKE\"",
- "\"ESCAPE\"",
- "\"IN\"",
- "\"IS\"",
- "\"TRUE\"",
- "\"FALSE\"",
- "\"NULL\"",
- "\"XPATH\"",
- "\"XQUERY\"",
- "<DECIMAL_LITERAL>",
- "<HEX_LITERAL>",
- "<OCTAL_LITERAL>",
- "<FLOATING_POINT_LITERAL>",
- "<EXPONENT>",
- "<STRING_LITERAL>",
- "<ID>",
- "\"=\"",
- "\"<>\"",
- "\">\"",
- "\">=\"",
- "\"<\"",
- "\"<=\"",
- "\"(\"",
- "\",\"",
- "\")\"",
- "\"+\"",
- "\"-\"",
- "\"*\"",
- "\"/\"",
- "\"%\"",
- };
-
-}
+/* Generated By:CSharpCC: Do not edit this line. SelectorParserConstants.cs */
+public class SelectorParserConstants {
+
+ public const int EOF = 0;
+ public const int LINE_COMMENT = 6;
+ public const int BLOCK_COMMENT = 7;
+ public const int NOT = 8;
+ public const int AND = 9;
+ public const int OR = 10;
+ public const int BETWEEN = 11;
+ public const int LIKE = 12;
+ public const int ESCAPE = 13;
+ public const int IN = 14;
+ public const int IS = 15;
+ public const int TRUE = 16;
+ public const int FALSE = 17;
+ public const int NULL = 18;
+ public const int XPATH = 19;
+ public const int XQUERY = 20;
+ public const int DECIMAL_LITERAL = 21;
+ public const int HEX_LITERAL = 22;
+ public const int OCTAL_LITERAL = 23;
+ public const int FLOATING_POINT_LITERAL = 24;
+ public const int EXPONENT = 25;
+ public const int STRING_LITERAL = 26;
+ public const int ID = 27;
+
+ public const int DEFAULT = 0;
+
+ public readonly string[] tokenImage = {
+ "<EOF>",
+ "\" \"",
+ "\"\\t\"",
+ "\"\\n\"",
+ "\"\\r\"",
+ "\"\\f\"",
+ "<LINE_COMMENT>",
+ "<BLOCK_COMMENT>",
+ "\"NOT\"",
+ "\"AND\"",
+ "\"OR\"",
+ "\"BETWEEN\"",
+ "\"LIKE\"",
+ "\"ESCAPE\"",
+ "\"IN\"",
+ "\"IS\"",
+ "\"TRUE\"",
+ "\"FALSE\"",
+ "\"NULL\"",
+ "\"XPATH\"",
+ "\"XQUERY\"",
+ "<DECIMAL_LITERAL>",
+ "<HEX_LITERAL>",
+ "<OCTAL_LITERAL>",
+ "<FLOATING_POINT_LITERAL>",
+ "<EXPONENT>",
+ "<STRING_LITERAL>",
+ "<ID>",
+ "\"=\"",
+ "\"<>\"",
+ "\">\"",
+ "\">=\"",
+ "\"<\"",
+ "\"<=\"",
+ "\"(\"",
+ "\",\"",
+ "\")\"",
+ "\"+\"",
+ "\"-\"",
+ "\"*\"",
+ "\"/\"",
+ "\"%\"",
+ };
+
+}
diff --git a/src/main/csharp/Selector/SelectorParserTokenManager.cs b/src/main/csharp/Selector/SelectorParserTokenManager.cs
index e198265..99f51e2 100644
--- a/src/main/csharp/Selector/SelectorParserTokenManager.cs
+++ b/src/main/csharp/Selector/SelectorParserTokenManager.cs
@@ -1,1042 +1,1041 @@
-/* Generated By:CSharpCC: Do not edit this line. SelectorParserTokenManager.cs */
-/**
- *
- * 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.
- */
-using System;
-using System.IO;
-using System.Text;
-using System.Collections;
-using Apache.NMS;
-
-public class SelectorParserTokenManager : SelectorParserConstants {
- public System.IO.TextWriter debugStream = Console.Out;
- public void SetDebugStream(System.IO.TextWriter ds) { debugStream = ds; }
-private int mccStopAtPos(int pos, int kind)
-{
- mccmatchedKind = kind;
- mccmatchedPos = pos;
- return pos + 1;
-}
-private int mccMoveStringLiteralDfa0_0()
-{
- switch((int)curChar) {
- case 9:
- mccmatchedKind = 2;
- return mccMoveNfa_0(5, 0);
- case 10:
- mccmatchedKind = 3;
- return mccMoveNfa_0(5, 0);
- case 12:
- mccmatchedKind = 5;
- return mccMoveNfa_0(5, 0);
- case 13:
- mccmatchedKind = 4;
- return mccMoveNfa_0(5, 0);
- case 32:
- mccmatchedKind = 1;
- return mccMoveNfa_0(5, 0);
- case 37:
- mccmatchedKind = 41;
- return mccMoveNfa_0(5, 0);
- case 40:
- mccmatchedKind = 34;
- return mccMoveNfa_0(5, 0);
- case 41:
- mccmatchedKind = 36;
- return mccMoveNfa_0(5, 0);
- case 42:
- mccmatchedKind = 39;
- return mccMoveNfa_0(5, 0);
- case 43:
- mccmatchedKind = 37;
- return mccMoveNfa_0(5, 0);
- case 44:
- mccmatchedKind = 35;
- return mccMoveNfa_0(5, 0);
- case 45:
- mccmatchedKind = 38;
- return mccMoveNfa_0(5, 0);
- case 47:
- mccmatchedKind = 40;
- return mccMoveNfa_0(5, 0);
- case 60:
- mccmatchedKind = 32;
- return mccMoveStringLiteralDfa1_0(9126805504L);
- case 61:
- mccmatchedKind = 28;
- return mccMoveNfa_0(5, 0);
- case 62:
- mccmatchedKind = 30;
- return mccMoveStringLiteralDfa1_0(2147483648L);
- case 65:
- return mccMoveStringLiteralDfa1_0(512L);
- case 66:
- return mccMoveStringLiteralDfa1_0(2048L);
- case 69:
- return mccMoveStringLiteralDfa1_0(8192L);
- case 70:
- return mccMoveStringLiteralDfa1_0(131072L);
- case 73:
- return mccMoveStringLiteralDfa1_0(49152L);
- case 76:
- return mccMoveStringLiteralDfa1_0(4096L);
- case 78:
- return mccMoveStringLiteralDfa1_0(262400L);
- case 79:
- return mccMoveStringLiteralDfa1_0(1024L);
- case 84:
- return mccMoveStringLiteralDfa1_0(65536L);
- case 88:
- return mccMoveStringLiteralDfa1_0(1572864L);
- case 97:
- return mccMoveStringLiteralDfa1_0(512L);
- case 98:
- return mccMoveStringLiteralDfa1_0(2048L);
- case 101:
- return mccMoveStringLiteralDfa1_0(8192L);
- case 102:
- return mccMoveStringLiteralDfa1_0(131072L);
- case 105:
- return mccMoveStringLiteralDfa1_0(49152L);
- case 108:
- return mccMoveStringLiteralDfa1_0(4096L);
- case 110:
- return mccMoveStringLiteralDfa1_0(262400L);
- case 111:
- return mccMoveStringLiteralDfa1_0(1024L);
- case 116:
- return mccMoveStringLiteralDfa1_0(65536L);
- case 120:
- return mccMoveStringLiteralDfa1_0(1572864L);
- default :
- return mccMoveNfa_0(5, 0);
- }
-}
-private int mccMoveStringLiteralDfa1_0(long active0)
-{
- try { curChar = input_stream.ReadChar(); }
- catch(System.IO.IOException) {
- return mccMoveNfa_0(5, 0);
- }
- switch((int)curChar) {
- case 61:
- if ((active0 & 2147483648L) != 0L)
- {
- mccmatchedKind = 31;
- mccmatchedPos = 1;
- }
- else if ((active0 & 8589934592L) != 0L)
- {
- mccmatchedKind = 33;
- mccmatchedPos = 1;
- }
- break;
- case 62:
- if ((active0 & 536870912L) != 0L)
- {
- mccmatchedKind = 29;
- mccmatchedPos = 1;
- }
- break;
- case 65:
- return mccMoveStringLiteralDfa2_0(active0, 131072L);
- case 69:
- return mccMoveStringLiteralDfa2_0(active0, 2048L);
- case 73:
- return mccMoveStringLiteralDfa2_0(active0, 4096L);
- case 78:
- if ((active0 & 16384L) != 0L)
- {
- mccmatchedKind = 14;
- mccmatchedPos = 1;
- }
- return mccMoveStringLiteralDfa2_0(active0, 512L);
- case 79:
- return mccMoveStringLiteralDfa2_0(active0, 256L);
- case 80:
- return mccMoveStringLiteralDfa2_0(active0, 524288L);
- case 81:
- return mccMoveStringLiteralDfa2_0(active0, 1048576L);
- case 82:
- if ((active0 & 1024L) != 0L)
- {
- mccmatchedKind = 10;
- mccmatchedPos = 1;
- }
- return mccMoveStringLiteralDfa2_0(active0, 65536L);
- case 83:
- if ((active0 & 32768L) != 0L)
- {
- mccmatchedKind = 15;
- mccmatchedPos = 1;
- }
- return mccMoveStringLiteralDfa2_0(active0, 8192L);
- case 85:
- return mccMoveStringLiteralDfa2_0(active0, 262144L);
- case 97:
- return mccMoveStringLiteralDfa2_0(active0, 131072L);
- case 101:
- return mccMoveStringLiteralDfa2_0(active0, 2048L);
- case 105:
- return mccMoveStringLiteralDfa2_0(active0, 4096L);
- case 110:
- if ((active0 & 16384L) != 0L)
- {
- mccmatchedKind = 14;
- mccmatchedPos = 1;
- }
- return mccMoveStringLiteralDfa2_0(active0, 512L);
- case 111:
- return mccMoveStringLiteralDfa2_0(active0, 256L);
- case 112:
- return mccMoveStringLiteralDfa2_0(active0, 524288L);
- case 113:
- return mccMoveStringLiteralDfa2_0(active0, 1048576L);
- case 114:
- if ((active0 & 1024L) != 0L)
- {
- mccmatchedKind = 10;
- mccmatchedPos = 1;
- }
- return mccMoveStringLiteralDfa2_0(active0, 65536L);
- case 115:
- if ((active0 & 32768L) != 0L)
- {
- mccmatchedKind = 15;
- mccmatchedPos = 1;
- }
- return mccMoveStringLiteralDfa2_0(active0, 8192L);
- case 117:
- return mccMoveStringLiteralDfa2_0(active0, 262144L);
- default :
- break;
- }
- return mccMoveNfa_0(5, 1);
-}
-private int mccMoveStringLiteralDfa2_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return mccMoveNfa_0(5, 1);
- try { curChar = input_stream.ReadChar(); }
- catch(System.IO.IOException) {
- return mccMoveNfa_0(5, 1);
- }
- switch((int)curChar) {
- case 65:
- return mccMoveStringLiteralDfa3_0(active0, 524288L);
- case 67:
- return mccMoveStringLiteralDfa3_0(active0, 8192L);
- case 68:
- if ((active0 & 512L) != 0L)
- {
- mccmatchedKind = 9;
- mccmatchedPos = 2;
- }
- break;
- case 75:
- return mccMoveStringLiteralDfa3_0(active0, 4096L);
- case 76:
- return mccMoveStringLiteralDfa3_0(active0, 393216L);
- case 84:
- if ((active0 & 256L) != 0L)
- {
- mccmatchedKind = 8;
- mccmatchedPos = 2;
- }
- return mccMoveStringLiteralDfa3_0(active0, 2048L);
- case 85:
- return mccMoveStringLiteralDfa3_0(active0, 1114112L);
- case 97:
- return mccMoveStringLiteralDfa3_0(active0, 524288L);
- case 99:
- return mccMoveStringLiteralDfa3_0(active0, 8192L);
- case 100:
- if ((active0 & 512L) != 0L)
- {
- mccmatchedKind = 9;
- mccmatchedPos = 2;
- }
- break;
- case 107:
- return mccMoveStringLiteralDfa3_0(active0, 4096L);
- case 108:
- return mccMoveStringLiteralDfa3_0(active0, 393216L);
- case 116:
- if ((active0 & 256L) != 0L)
- {
- mccmatchedKind = 8;
- mccmatchedPos = 2;
- }
- return mccMoveStringLiteralDfa3_0(active0, 2048L);
- case 117:
- return mccMoveStringLiteralDfa3_0(active0, 1114112L);
- default :
- break;
- }
- return mccMoveNfa_0(5, 2);
-}
-private int mccMoveStringLiteralDfa3_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return mccMoveNfa_0(5, 2);
- try { curChar = input_stream.ReadChar(); }
- catch(System.IO.IOException) {
- return mccMoveNfa_0(5, 2);
- }
- switch((int)curChar) {
- case 65:
- return mccMoveStringLiteralDfa4_0(active0, 8192L);
- case 69:
- if ((active0 & 4096L) != 0L)
- {
- mccmatchedKind = 12;
- mccmatchedPos = 3;
- }
- else if ((active0 & 65536L) != 0L)
- {
- mccmatchedKind = 16;
- mccmatchedPos = 3;
- }
- return mccMoveStringLiteralDfa4_0(active0, 1048576L);
- case 76:
- if ((active0 & 262144L) != 0L)
- {
- mccmatchedKind = 18;
- mccmatchedPos = 3;
- }
- break;
- case 83:
- return mccMoveStringLiteralDfa4_0(active0, 131072L);
- case 84:
- return mccMoveStringLiteralDfa4_0(active0, 524288L);
- case 87:
- return mccMoveStringLiteralDfa4_0(active0, 2048L);
- case 97:
- return mccMoveStringLiteralDfa4_0(active0, 8192L);
- case 101:
- if ((active0 & 4096L) != 0L)
- {
- mccmatchedKind = 12;
- mccmatchedPos = 3;
- }
- else if ((active0 & 65536L) != 0L)
- {
- mccmatchedKind = 16;
- mccmatchedPos = 3;
- }
- return mccMoveStringLiteralDfa4_0(active0, 1048576L);
- case 108:
- if ((active0 & 262144L) != 0L)
- {
- mccmatchedKind = 18;
- mccmatchedPos = 3;
- }
- break;
- case 115:
- return mccMoveStringLiteralDfa4_0(active0, 131072L);
- case 116:
- return mccMoveStringLiteralDfa4_0(active0, 524288L);
- case 119:
- return mccMoveStringLiteralDfa4_0(active0, 2048L);
- default :
- break;
- }
- return mccMoveNfa_0(5, 3);
-}
-private int mccMoveStringLiteralDfa4_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return mccMoveNfa_0(5, 3);
- try { curChar = input_stream.ReadChar(); }
- catch(System.IO.IOException) {
- return mccMoveNfa_0(5, 3);
- }
- switch((int)curChar) {
- case 69:
- if ((active0 & 131072L) != 0L)
- {
- mccmatchedKind = 17;
- mccmatchedPos = 4;
- }
- return mccMoveStringLiteralDfa5_0(active0, 2048L);
- case 72:
- if ((active0 & 524288L) != 0L)
- {
- mccmatchedKind = 19;
- mccmatchedPos = 4;
- }
- break;
- case 80:
- return mccMoveStringLiteralDfa5_0(active0, 8192L);
- case 82:
- return mccMoveStringLiteralDfa5_0(active0, 1048576L);
- case 101:
- if ((active0 & 131072L) != 0L)
- {
- mccmatchedKind = 17;
- mccmatchedPos = 4;
- }
- return mccMoveStringLiteralDfa5_0(active0, 2048L);
- case 104:
- if ((active0 & 524288L) != 0L)
- {
- mccmatchedKind = 19;
- mccmatchedPos = 4;
- }
- break;
- case 112:
- return mccMoveStringLiteralDfa5_0(active0, 8192L);
- case 114:
- return mccMoveStringLiteralDfa5_0(active0, 1048576L);
- default :
- break;
- }
- return mccMoveNfa_0(5, 4);
-}
-private int mccMoveStringLiteralDfa5_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return mccMoveNfa_0(5, 4);
- try { curChar = input_stream.ReadChar(); }
- catch(System.IO.IOException) {
- return mccMoveNfa_0(5, 4);
- }
- switch((int)curChar) {
- case 69:
- if ((active0 & 8192L) != 0L)
- {
- mccmatchedKind = 13;
- mccmatchedPos = 5;
- }
- return mccMoveStringLiteralDfa6_0(active0, 2048L);
- case 89:
- if ((active0 & 1048576L) != 0L)
- {
- mccmatchedKind = 20;
- mccmatchedPos = 5;
- }
- break;
- case 101:
- if ((active0 & 8192L) != 0L)
- {
- mccmatchedKind = 13;
- mccmatchedPos = 5;
- }
- return mccMoveStringLiteralDfa6_0(active0, 2048L);
- case 121:
- if ((active0 & 1048576L) != 0L)
- {
- mccmatchedKind = 20;
- mccmatchedPos = 5;
- }
- break;
- default :
- break;
- }
- return mccMoveNfa_0(5, 5);
-}
-private int mccMoveStringLiteralDfa6_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return mccMoveNfa_0(5, 5);
- try { curChar = input_stream.ReadChar(); }
- catch(System.IO.IOException) {
- return mccMoveNfa_0(5, 5);
- }
- switch((int)curChar) {
- case 78:
- if ((active0 & 2048L) != 0L)
- {
- mccmatchedKind = 11;
- mccmatchedPos = 6;
- }
- break;
- case 110:
- if ((active0 & 2048L) != 0L)
- {
- mccmatchedKind = 11;
- mccmatchedPos = 6;
- }
- break;
- default :
- break;
- }
- return mccMoveNfa_0(5, 6);
-}
-private void mccCheckNAdd(int state)
-{
- if (mccrounds[state] != mccround)
- {
- mccstateSet[mccnewStateCnt++] = state;
- mccrounds[state] = mccround;
- }
-}
-private void mccAddStates(int start, int end)
-{
- do {
- mccstateSet[mccnewStateCnt++] = mccnextStates[start];
- } while (start++ != end);
-}
-private void mccCheckNAddTwoStates(int state1, int state2)
-{
- mccCheckNAdd(state1);
- mccCheckNAdd(state2);
-}
-private void mccCheckNAddStates(int start, int end)
-{
- do {
- mccCheckNAdd(mccnextStates[start]);
- } while (start++ != end);
-}
-private void mccCheckNAddStates(int start)
-{
- mccCheckNAdd(mccnextStates[start]);
- mccCheckNAdd(mccnextStates[start + 1]);
-}
+/* Generated By:CSharpCC: Do not edit this line. SelectorParserTokenManager.cs */
+/*
+ * 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.
+ */
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+using Apache.NMS;
+
+public class SelectorParserTokenManager : SelectorParserConstants {
+ public System.IO.TextWriter debugStream = Console.Out;
+ public void SetDebugStream(System.IO.TextWriter ds) { debugStream = ds; }
+private int mccStopAtPos(int pos, int kind)
+{
+ mccmatchedKind = kind;
+ mccmatchedPos = pos;
+ return pos + 1;
+}
+private int mccMoveStringLiteralDfa0_0()
+{
+ switch((int)curChar) {
+ case 9:
+ mccmatchedKind = 2;
+ return mccMoveNfa_0(5, 0);
+ case 10:
+ mccmatchedKind = 3;
+ return mccMoveNfa_0(5, 0);
+ case 12:
+ mccmatchedKind = 5;
+ return mccMoveNfa_0(5, 0);
+ case 13:
+ mccmatchedKind = 4;
+ return mccMoveNfa_0(5, 0);
+ case 32:
+ mccmatchedKind = 1;
+ return mccMoveNfa_0(5, 0);
+ case 37:
+ mccmatchedKind = 41;
+ return mccMoveNfa_0(5, 0);
+ case 40:
+ mccmatchedKind = 34;
+ return mccMoveNfa_0(5, 0);
+ case 41:
+ mccmatchedKind = 36;
+ return mccMoveNfa_0(5, 0);
+ case 42:
+ mccmatchedKind = 39;
+ return mccMoveNfa_0(5, 0);
+ case 43:
+ mccmatchedKind = 37;
+ return mccMoveNfa_0(5, 0);
+ case 44:
+ mccmatchedKind = 35;
+ return mccMoveNfa_0(5, 0);
+ case 45:
+ mccmatchedKind = 38;
+ return mccMoveNfa_0(5, 0);
+ case 47:
+ mccmatchedKind = 40;
+ return mccMoveNfa_0(5, 0);
+ case 60:
+ mccmatchedKind = 32;
+ return mccMoveStringLiteralDfa1_0(9126805504L);
+ case 61:
+ mccmatchedKind = 28;
+ return mccMoveNfa_0(5, 0);
+ case 62:
+ mccmatchedKind = 30;
+ return mccMoveStringLiteralDfa1_0(2147483648L);
+ case 65:
+ return mccMoveStringLiteralDfa1_0(512L);
+ case 66:
+ return mccMoveStringLiteralDfa1_0(2048L);
+ case 69:
+ return mccMoveStringLiteralDfa1_0(8192L);
+ case 70:
+ return mccMoveStringLiteralDfa1_0(131072L);
+ case 73:
+ return mccMoveStringLiteralDfa1_0(49152L);
+ case 76:
+ return mccMoveStringLiteralDfa1_0(4096L);
+ case 78:
+ return mccMoveStringLiteralDfa1_0(262400L);
+ case 79:
+ return mccMoveStringLiteralDfa1_0(1024L);
+ case 84:
+ return mccMoveStringLiteralDfa1_0(65536L);
+ case 88:
+ return mccMoveStringLiteralDfa1_0(1572864L);
+ case 97:
+ return mccMoveStringLiteralDfa1_0(512L);
+ case 98:
+ return mccMoveStringLiteralDfa1_0(2048L);
+ case 101:
+ return mccMoveStringLiteralDfa1_0(8192L);
+ case 102:
+ return mccMoveStringLiteralDfa1_0(131072L);
+ case 105:
+ return mccMoveStringLiteralDfa1_0(49152L);
+ case 108:
+ return mccMoveStringLiteralDfa1_0(4096L);
+ case 110:
+ return mccMoveStringLiteralDfa1_0(262400L);
+ case 111:
+ return mccMoveStringLiteralDfa1_0(1024L);
+ case 116:
+ return mccMoveStringLiteralDfa1_0(65536L);
+ case 120:
+ return mccMoveStringLiteralDfa1_0(1572864L);
+ default :
+ return mccMoveNfa_0(5, 0);
+ }
+}
+private int mccMoveStringLiteralDfa1_0(long active0)
+{
+ try { curChar = input_stream.ReadChar(); }
+ catch(System.IO.IOException) {
+ return mccMoveNfa_0(5, 0);
+ }
+ switch((int)curChar) {
+ case 61:
+ if ((active0 & 2147483648L) != 0L)
+ {
+ mccmatchedKind = 31;
+ mccmatchedPos = 1;
+ }
+ else if ((active0 & 8589934592L) != 0L)
+ {
+ mccmatchedKind = 33;
+ mccmatchedPos = 1;
+ }
+ break;
+ case 62:
+ if ((active0 & 536870912L) != 0L)
+ {
+ mccmatchedKind = 29;
+ mccmatchedPos = 1;
+ }
+ break;
+ case 65:
+ return mccMoveStringLiteralDfa2_0(active0, 131072L);
+ case 69:
+ return mccMoveStringLiteralDfa2_0(active0, 2048L);
+ case 73:
+ return mccMoveStringLiteralDfa2_0(active0, 4096L);
+ case 78:
+ if ((active0 & 16384L) != 0L)
+ {
+ mccmatchedKind = 14;
+ mccmatchedPos = 1;
+ }
+ return mccMoveStringLiteralDfa2_0(active0, 512L);
+ case 79:
+ return mccMoveStringLiteralDfa2_0(active0, 256L);
+ case 80:
+ return mccMoveStringLiteralDfa2_0(active0, 524288L);
+ case 81:
+ return mccMoveStringLiteralDfa2_0(active0, 1048576L);
+ case 82:
+ if ((active0 & 1024L) != 0L)
+ {
+ mccmatchedKind = 10;
+ mccmatchedPos = 1;
+ }
+ return mccMoveStringLiteralDfa2_0(active0, 65536L);
+ case 83:
+ if ((active0 & 32768L) != 0L)
+ {
+ mccmatchedKind = 15;
+ mccmatchedPos = 1;
+ }
+ return mccMoveStringLiteralDfa2_0(active0, 8192L);
+ case 85:
+ return mccMoveStringLiteralDfa2_0(active0, 262144L);
+ case 97:
+ return mccMoveStringLiteralDfa2_0(active0, 131072L);
+ case 101:
+ return mccMoveStringLiteralDfa2_0(active0, 2048L);
+ case 105:
+ return mccMoveStringLiteralDfa2_0(active0, 4096L);
+ case 110:
+ if ((active0 & 16384L) != 0L)
+ {
+ mccmatchedKind = 14;
+ mccmatchedPos = 1;
+ }
+ return mccMoveStringLiteralDfa2_0(active0, 512L);
+ case 111:
+ return mccMoveStringLiteralDfa2_0(active0, 256L);
+ case 112:
+ return mccMoveStringLiteralDfa2_0(active0, 524288L);
+ case 113:
+ return mccMoveStringLiteralDfa2_0(active0, 1048576L);
+ case 114:
+ if ((active0 & 1024L) != 0L)
+ {
+ mccmatchedKind = 10;
+ mccmatchedPos = 1;
+ }
+ return mccMoveStringLiteralDfa2_0(active0, 65536L);
+ case 115:
+ if ((active0 & 32768L) != 0L)
+ {
+ mccmatchedKind = 15;
+ mccmatchedPos = 1;
+ }
+ return mccMoveStringLiteralDfa2_0(active0, 8192L);
+ case 117:
+ return mccMoveStringLiteralDfa2_0(active0, 262144L);
+ default :
+ break;
+ }
+ return mccMoveNfa_0(5, 1);
+}
+private int mccMoveStringLiteralDfa2_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return mccMoveNfa_0(5, 1);
+ try { curChar = input_stream.ReadChar(); }
+ catch(System.IO.IOException) {
+ return mccMoveNfa_0(5, 1);
+ }
+ switch((int)curChar) {
+ case 65:
+ return mccMoveStringLiteralDfa3_0(active0, 524288L);
+ case 67:
+ return mccMoveStringLiteralDfa3_0(active0, 8192L);
+ case 68:
+ if ((active0 & 512L) != 0L)
+ {
+ mccmatchedKind = 9;
+ mccmatchedPos = 2;
+ }
+ break;
+ case 75:
+ return mccMoveStringLiteralDfa3_0(active0, 4096L);
+ case 76:
+ return mccMoveStringLiteralDfa3_0(active0, 393216L);
+ case 84:
+ if ((active0 & 256L) != 0L)
+ {
+ mccmatchedKind = 8;
+ mccmatchedPos = 2;
+ }
+ return mccMoveStringLiteralDfa3_0(active0, 2048L);
+ case 85:
+ return mccMoveStringLiteralDfa3_0(active0, 1114112L);
+ case 97:
+ return mccMoveStringLiteralDfa3_0(active0, 524288L);
+ case 99:
+ return mccMoveStringLiteralDfa3_0(active0, 8192L);
+ case 100:
+ if ((active0 & 512L) != 0L)
+ {
+ mccmatchedKind = 9;
+ mccmatchedPos = 2;
+ }
+ break;
+ case 107:
+ return mccMoveStringLiteralDfa3_0(active0, 4096L);
+ case 108:
+ return mccMoveStringLiteralDfa3_0(active0, 393216L);
+ case 116:
+ if ((active0 & 256L) != 0L)
+ {
+ mccmatchedKind = 8;
+ mccmatchedPos = 2;
+ }
+ return mccMoveStringLiteralDfa3_0(active0, 2048L);
+ case 117:
+ return mccMoveStringLiteralDfa3_0(active0, 1114112L);
+ default :
+ break;
+ }
+ return mccMoveNfa_0(5, 2);
+}
+private int mccMoveStringLiteralDfa3_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return mccMoveNfa_0(5, 2);
+ try { curChar = input_stream.ReadChar(); }
+ catch(System.IO.IOException) {
+ return mccMoveNfa_0(5, 2);
+ }
+ switch((int)curChar) {
+ case 65:
+ return mccMoveStringLiteralDfa4_0(active0, 8192L);
+ case 69:
+ if ((active0 & 4096L) != 0L)
+ {
+ mccmatchedKind = 12;
+ mccmatchedPos = 3;
+ }
+ else if ((active0 & 65536L) != 0L)
+ {
+ mccmatchedKind = 16;
+ mccmatchedPos = 3;
+ }
+ return mccMoveStringLiteralDfa4_0(active0, 1048576L);
+ case 76:
+ if ((active0 & 262144L) != 0L)
+ {
+ mccmatchedKind = 18;
+ mccmatchedPos = 3;
+ }
+ break;
+ case 83:
+ return mccMoveStringLiteralDfa4_0(active0, 131072L);
+ case 84:
+ return mccMoveStringLiteralDfa4_0(active0, 524288L);
+ case 87:
+ return mccMoveStringLiteralDfa4_0(active0, 2048L);
+ case 97:
+ return mccMoveStringLiteralDfa4_0(active0, 8192L);
+ case 101:
+ if ((active0 & 4096L) != 0L)
+ {
+ mccmatchedKind = 12;
+ mccmatchedPos = 3;
+ }
+ else if ((active0 & 65536L) != 0L)
+ {
+ mccmatchedKind = 16;
+ mccmatchedPos = 3;
+ }
+ return mccMoveStringLiteralDfa4_0(active0, 1048576L);
+ case 108:
+ if ((active0 & 262144L) != 0L)
+ {
+ mccmatchedKind = 18;
+ mccmatchedPos = 3;
+ }
+ break;
+ case 115:
+ return mccMoveStringLiteralDfa4_0(active0, 131072L);
+ case 116:
+ return mccMoveStringLiteralDfa4_0(active0, 524288L);
+ case 119:
+ return mccMoveStringLiteralDfa4_0(active0, 2048L);
+ default :
+ break;
+ }
+ return mccMoveNfa_0(5, 3);
+}
+private int mccMoveStringLiteralDfa4_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return mccMoveNfa_0(5, 3);
+ try { curChar = input_stream.ReadChar(); }
+ catch(System.IO.IOException) {
+ return mccMoveNfa_0(5, 3);
+ }
+ switch((int)curChar) {
+ case 69:
+ if ((active0 & 131072L) != 0L)
+ {
+ mccmatchedKind = 17;
+ mccmatchedPos = 4;
+ }
+ return mccMoveStringLiteralDfa5_0(active0, 2048L);
+ case 72:
+ if ((active0 & 524288L) != 0L)
+ {
+ mccmatchedKind = 19;
+ mccmatchedPos = 4;
+ }
+ break;
+ case 80:
+ return mccMoveStringLiteralDfa5_0(active0, 8192L);
+ case 82:
+ return mccMoveStringLiteralDfa5_0(active0, 1048576L);
+ case 101:
+ if ((active0 & 131072L) != 0L)
+ {
+ mccmatchedKind = 17;
+ mccmatchedPos = 4;
+ }
+ return mccMoveStringLiteralDfa5_0(active0, 2048L);
+ case 104:
+ if ((active0 & 524288L) != 0L)
+ {
+ mccmatchedKind = 19;
+ mccmatchedPos = 4;
+ }
+ break;
+ case 112:
+ return mccMoveStringLiteralDfa5_0(active0, 8192L);
+ case 114:
+ return mccMoveStringLiteralDfa5_0(active0, 1048576L);
+ default :
+ break;
+ }
+ return mccMoveNfa_0(5, 4);
+}
+private int mccMoveStringLiteralDfa5_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return mccMoveNfa_0(5, 4);
+ try { curChar = input_stream.ReadChar(); }
+ catch(System.IO.IOException) {
+ return mccMoveNfa_0(5, 4);
+ }
+ switch((int)curChar) {
+ case 69:
+ if ((active0 & 8192L) != 0L)
+ {
+ mccmatchedKind = 13;
+ mccmatchedPos = 5;
+ }
+ return mccMoveStringLiteralDfa6_0(active0, 2048L);
+ case 89:
+ if ((active0 & 1048576L) != 0L)
+ {
+ mccmatchedKind = 20;
+ mccmatchedPos = 5;
+ }
+ break;
+ case 101:
+ if ((active0 & 8192L) != 0L)
+ {
+ mccmatchedKind = 13;
+ mccmatchedPos = 5;
+ }
+ return mccMoveStringLiteralDfa6_0(active0, 2048L);
+ case 121:
+ if ((active0 & 1048576L) != 0L)
+ {
+ mccmatchedKind = 20;
+ mccmatchedPos = 5;
+ }
+ break;
+ default :
+ break;
+ }
+ return mccMoveNfa_0(5, 5);
+}
+private int mccMoveStringLiteralDfa6_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return mccMoveNfa_0(5, 5);
+ try { curChar = input_stream.ReadChar(); }
+ catch(System.IO.IOException) {
+ return mccMoveNfa_0(5, 5);
+ }
+ switch((int)curChar) {
+ case 78:
+ if ((active0 & 2048L) != 0L)
+ {
+ mccmatchedKind = 11;
+ mccmatchedPos = 6;
+ }
+ break;
+ case 110:
+ if ((active0 & 2048L) != 0L)
+ {
+ mccmatchedKind = 11;
+ mccmatchedPos = 6;
+ }
+ break;
+ default :
+ break;
+ }
+ return mccMoveNfa_0(5, 6);
+}
+private void mccCheckNAdd(int state)
+{
+ if (mccrounds[state] != mccround)
+ {
+ mccstateSet[mccnewStateCnt++] = state;
+ mccrounds[state] = mccround;
+ }
+}
+private void mccAddStates(int start, int end)
+{
+ do {
+ mccstateSet[mccnewStateCnt++] = mccnextStates[start];
+ } while (start++ != end);
+}
+private void mccCheckNAddTwoStates(int state1, int state2)
+{
+ mccCheckNAdd(state1);
+ mccCheckNAdd(state2);
+}
+private void mccCheckNAddStates(int start, int end)
+{
+ do {
+ mccCheckNAdd(mccnextStates[start]);
+ } while (start++ != end);
+}
+private void mccCheckNAddStates(int start)
+{
+ mccCheckNAdd(mccnextStates[start]);
+ mccCheckNAdd(mccnextStates[start + 1]);
+}
static readonly long[] mccbitVec0 = {
-2, -1L, -1L, -1L
-};
+};
static readonly long[] mccbitVec1 = {
-1L, -1L, -1L, -1L
-};
+};
static readonly long[] mccbitVec2 = {
0L, 0L, -1L, -1L
-};
-private int mccMoveNfa_0(int startState, int curPos)
-{
- int strKind = mccmatchedKind;
- int strPos = mccmatchedPos;
- int seenUpto = curPos + 1;
- input_stream.Backup(seenUpto);
- try { curChar = input_stream.ReadChar(); }
- catch(System.IO.IOException) { throw new Exception("Internal Error"); }
- curPos = 0;
- //int[] nextStates;
- int startsAt = 0;
- mccnewStateCnt = 43;
- int i = 1;
- mccstateSet[0] = startState;
- int /*j,*/ kind = Int32.MaxValue;
- for (;;)
- {
- if (++mccround == Int32.MaxValue)
- ReInitRounds();
- if (curChar < 64)
- {
- long l = 1L << curChar;
- do
- {
- switch(mccstateSet[--i])
- {
- case 5:
- if ((287948901175001088 & l) != 0L)
- mccCheckNAddStates(0, 3);
- else if (curChar == 36)
- {
- if (kind > 27)
- kind = 27;
- mccCheckNAdd(27);
- }
- else if (curChar == 39)
- mccCheckNAddStates(4, 6);
- else if (curChar == 46)
- mccCheckNAdd(17);
- else if (curChar == 47)
- mccstateSet[mccnewStateCnt++] = 6;
- else if (curChar == 45)
- mccstateSet[mccnewStateCnt++] = 0;
- if ((287667426198290432 & l) != 0L)
- {
- if (kind > 21)
- kind = 21;
- mccCheckNAddTwoStates(14, 15);
- }
- else if (curChar == 48)
- {
- if (kind > 23)
- kind = 23;
- mccCheckNAddTwoStates(40, 42);
- }
- break;
- case 0:
- if (curChar == 45)
- mccCheckNAddStates(7, 9);
- break;
- case 1:
- if ((-9217 & l) != 0L)
- mccCheckNAddStates(7, 9);
- break;
- case 2:
- if ((9216 & l) != 0L && kind > 6)
- kind = 6;
- break;
- case 3:
- if (curChar == 10 && kind > 6)
- kind = 6;
- break;
- case 4:
- if (curChar == 13)
- mccstateSet[mccnewStateCnt++] = 3;
- break;
- case 6:
- if (curChar == 42)
- mccCheckNAddTwoStates(7, 8);
- break;
- case 7:
- if ((-4398046511105 & l) != 0L)
- mccCheckNAddTwoStates(7, 8);
- break;
- case 8:
- if (curChar == 42)
- mccCheckNAddStates(10, 12);
- break;
- case 9:
- if ((-145135534866433 & l) != 0L)
- mccCheckNAddTwoStates(10, 8);
- break;
- case 10:
- if ((-4398046511105 & l) != 0L)
- mccCheckNAddTwoStates(10, 8);
- break;
- case 11:
- if (curChar == 47 && kind > 7)
- kind = 7;
- break;
- case 12:
- if (curChar == 47)
- mccstateSet[mccnewStateCnt++] = 6;
- break;
- case 13:
- if ((287667426198290432 & l) == 0L)
- break;
- if (kind > 21)
- kind = 21;
- mccCheckNAddTwoStates(14, 15);
- break;
- case 14:
- if ((287948901175001088 & l) == 0L)
- break;
- if (kind > 21)
- kind = 21;
- mccCheckNAddTwoStates(14, 15);
- break;
- case 16:
- if (curChar == 46)
- mccCheckNAdd(17);
- break;
- case 17:
- if ((287948901175001088 & l) == 0L)
- break;
- if (kind > 24)
- kind = 24;
- mccCheckNAddTwoStates(17, 18);
- break;
- case 19:
- if ((43980465111040 & l) != 0L)
- mccCheckNAdd(20);
- break;
- case 20:
- if ((287948901175001088 & l) == 0L)
- break;
- if (kind > 24)
- kind = 24;
- mccCheckNAdd(20);
- break;
- case 21:
- case 22:
- if (curChar == 39)
- mccCheckNAddStates(4, 6);
- break;
- case 23:
- if (curChar == 39)
- mccstateSet[mccnewStateCnt++] = 22;
- break;
- case 24:
- if ((-549755813889 & l) != 0L)
- mccCheckNAddStates(4, 6);
- break;
- case 25:
- if (curChar == 39 && kind > 26)
- kind = 26;
- break;
- case 26:
- if (curChar != 36)
- break;
- if (kind > 27)
- kind = 27;
- mccCheckNAdd(27);
- break;
- case 27:
- if ((287948969894477824 & l) == 0L)
- break;
- if (kind > 27)
- kind = 27;
- mccCheckNAdd(27);
- break;
- case 28:
- if ((287948901175001088 & l) != 0L)
- mccCheckNAddStates(0, 3);
- break;
- case 29:
- if ((287948901175001088 & l) != 0L)
- mccCheckNAddTwoStates(29, 30);
- break;
- case 30:
- if (curChar != 46)
- break;
- if (kind > 24)
- kind = 24;
- mccCheckNAddTwoStates(31, 32);
- break;
- case 31:
- if ((287948901175001088 & l) == 0L)
- break;
- if (kind > 24)
- kind = 24;
- mccCheckNAddTwoStates(31, 32);
- break;
- case 33:
- if ((43980465111040 & l) != 0L)
- mccCheckNAdd(34);
- break;
- case 34:
- if ((287948901175001088 & l) == 0L)
- break;
- if (kind > 24)
- kind = 24;
- mccCheckNAdd(34);
- break;
- case 35:
- if ((287948901175001088 & l) != 0L)
- mccCheckNAddTwoStates(35, 36);
- break;
- case 37:
- if ((43980465111040 & l) != 0L)
- mccCheckNAdd(38);
- break;
- case 38:
- if ((287948901175001088 & l) == 0L)
- break;
- if (kind > 24)
- kind = 24;
- mccCheckNAdd(38);
- break;
- case 39:
- if (curChar != 48)
- break;
- if (kind > 23)
- kind = 23;
- mccCheckNAddTwoStates(40, 42);
- break;
- case 41:
- if ((287948901175001088 & l) == 0L)
- break;
- if (kind > 22)
- kind = 22;
- mccstateSet[mccnewStateCnt++] = 41;
- break;
- case 42:
- if ((71776119061217280 & l) == 0L)
- break;
- if (kind > 23)
- kind = 23;
- mccCheckNAdd(42);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- else if (curChar < 128)
- {
- long l = 1L << (curChar & 63);
- do
- {
- switch(mccstateSet[--i])
- {
- case 5:
- case 27:
- if ((576460745995190270 & l) == 0L)
- break;
- if (kind > 27)
- kind = 27;
- mccCheckNAdd(27);
- break;
- case 1:
- mccAddStates(7, 9);
- break;
- case 7:
- mccCheckNAddTwoStates(7, 8);
- break;
- case 9:
- case 10:
- mccCheckNAddTwoStates(10, 8);
- break;
- case 15:
- if ((17592186048512 & l) != 0L && kind > 21)
- kind = 21;
- break;
- case 18:
- if ((137438953504 & l) != 0L)
- mccAddStates(13, 14);
- break;
- case 24:
- mccAddStates(4, 6);
- break;
- case 32:
- if ((137438953504 & l) != 0L)
- mccAddStates(15, 16);
- break;
- case 36:
- if ((137438953504 & l) != 0L)
- mccAddStates(17, 18);
- break;
- case 40:
- if ((72057594054705152 & l) != 0L)
- mccCheckNAdd(41);
- break;
- case 41:
- if ((541165879422 & l) == 0L)
- break;
- if (kind > 22)
- kind = 22;
- mccCheckNAdd(41);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- else
- {
- int hiByte = (curChar >> 8);
- int i1 = hiByte >> 6;
- long l1 = 1L << (hiByte & 63);
- int i2 = (curChar & 0xff) >> 6;
- long l2 = 1L << (curChar & 63);
- do
- {
- switch(mccstateSet[--i])
- {
- case 1:
- if (mccCanMove_0(hiByte, i1, i2, l1, l2))
- mccAddStates(7, 9);
- break;
- case 7:
- if (mccCanMove_0(hiByte, i1, i2, l1, l2))
- mccCheckNAddTwoStates(7, 8);
- break;
- case 9:
- case 10:
- if (mccCanMove_0(hiByte, i1, i2, l1, l2))
- mccCheckNAddTwoStates(10, 8);
- break;
- case 24:
- if (mccCanMove_0(hiByte, i1, i2, l1, l2))
- mccAddStates(4, 6);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- if (kind != Int32.MaxValue)
- {
- mccmatchedKind = kind;
- mccmatchedPos = curPos;
- kind = Int32.MaxValue;
- }
- ++curPos;
- if ((i = mccnewStateCnt) == (startsAt = 43 - (mccnewStateCnt = startsAt)))
- break;
- try { curChar = input_stream.ReadChar(); }
- catch(System.IO.IOException) { break; }
- }
- if (mccmatchedPos > strPos)
- return curPos;
-
- int toRet = Math.Max(curPos, seenUpto);
-
- if (curPos < toRet)
- for (i = toRet - Math.Min(curPos, seenUpto); i-- > 0; )
- try { curChar = input_stream.ReadChar(); }
- catch(System.IO.IOException) { throw new Exception("Internal Error : Please send a bug report."); }
-
- if (mccmatchedPos < strPos)
- {
- mccmatchedKind = strKind;
- mccmatchedPos = strPos;
- }
- else if (mccmatchedPos == strPos && mccmatchedKind > strKind)
- mccmatchedKind = strKind;
-
- return toRet;
-}
+};
+private int mccMoveNfa_0(int startState, int curPos)
+{
+ int strKind = mccmatchedKind;
+ int strPos = mccmatchedPos;
+ int seenUpto = curPos + 1;
+ input_stream.Backup(seenUpto);
+ try { curChar = input_stream.ReadChar(); }
+ catch(System.IO.IOException) { throw new Exception("Internal Error"); }
+ curPos = 0;
+ //int[] nextStates;
+ int startsAt = 0;
+ mccnewStateCnt = 43;
+ int i = 1;
+ mccstateSet[0] = startState;
+ int /*j,*/ kind = Int32.MaxValue;
+ for (;;)
+ {
+ if (++mccround == Int32.MaxValue)
+ ReInitRounds();
+ if (curChar < 64)
+ {
+ long l = 1L << curChar;
+ do
+ {
+ switch(mccstateSet[--i])
+ {
+ case 5:
+ if ((287948901175001088 & l) != 0L)
+ mccCheckNAddStates(0, 3);
+ else if (curChar == 36)
+ {
+ if (kind > 27)
+ kind = 27;
+ mccCheckNAdd(27);
+ }
+ else if (curChar == 39)
+ mccCheckNAddStates(4, 6);
+ else if (curChar == 46)
+ mccCheckNAdd(17);
+ else if (curChar == 47)
+ mccstateSet[mccnewStateCnt++] = 6;
+ else if (curChar == 45)
+ mccstateSet[mccnewStateCnt++] = 0;
+ if ((287667426198290432 & l) != 0L)
+ {
+ if (kind > 21)
+ kind = 21;
+ mccCheckNAddTwoStates(14, 15);
+ }
+ else if (curChar == 48)
+ {
+ if (kind > 23)
+ kind = 23;
+ mccCheckNAddTwoStates(40, 42);
+ }
+ break;
+ case 0:
+ if (curChar == 45)
+ mccCheckNAddStates(7, 9);
+ break;
+ case 1:
+ if ((-9217 & l) != 0L)
+ mccCheckNAddStates(7, 9);
+ break;
+ case 2:
+ if ((9216 & l) != 0L && kind > 6)
+ kind = 6;
+ break;
+ case 3:
+ if (curChar == 10 && kind > 6)
+ kind = 6;
+ break;
+ case 4:
+ if (curChar == 13)
+ mccstateSet[mccnewStateCnt++] = 3;
+ break;
+ case 6:
+ if (curChar == 42)
+ mccCheckNAddTwoStates(7, 8);
+ break;
+ case 7:
+ if ((-4398046511105 & l) != 0L)
+ mccCheckNAddTwoStates(7, 8);
+ break;
+ case 8:
+ if (curChar == 42)
+ mccCheckNAddStates(10, 12);
+ break;
+ case 9:
+ if ((-145135534866433 & l) != 0L)
+ mccCheckNAddTwoStates(10, 8);
+ break;
+ case 10:
+ if ((-4398046511105 & l) != 0L)
+ mccCheckNAddTwoStates(10, 8);
+ break;
+ case 11:
+ if (curChar == 47 && kind > 7)
+ kind = 7;
+ break;
+ case 12:
+ if (curChar == 47)
+ mccstateSet[mccnewStateCnt++] = 6;
+ break;
+ case 13:
+ if ((287667426198290432 & l) == 0L)
+ break;
+ if (kind > 21)
+ kind = 21;
+ mccCheckNAddTwoStates(14, 15);
+ break;
+ case 14:
+ if ((287948901175001088 & l) == 0L)
+ break;
+ if (kind > 21)
+ kind = 21;
+ mccCheckNAddTwoStates(14, 15);
+ break;
+ case 16:
+ if (curChar == 46)
+ mccCheckNAdd(17);
+ break;
+ case 17:
+ if ((287948901175001088 & l) == 0L)
+ break;
+ if (kind > 24)
+ kind = 24;
+ mccCheckNAddTwoStates(17, 18);
+ break;
+ case 19:
+ if ((43980465111040 & l) != 0L)
+ mccCheckNAdd(20);
+ break;
+ case 20:
+ if ((287948901175001088 & l) == 0L)
+ break;
+ if (kind > 24)
+ kind = 24;
+ mccCheckNAdd(20);
+ break;
+ case 21:
+ case 22:
+ if (curChar == 39)
+ mccCheckNAddStates(4, 6);
+ break;
+ case 23:
+ if (curChar == 39)
+ mccstateSet[mccnewStateCnt++] = 22;
+ break;
+ case 24:
+ if ((-549755813889 & l) != 0L)
+ mccCheckNAddStates(4, 6);
+ break;
+ case 25:
+ if (curChar == 39 && kind > 26)
+ kind = 26;
+ break;
+ case 26:
+ if (curChar != 36)
+ break;
+ if (kind > 27)
+ kind = 27;
+ mccCheckNAdd(27);
+ break;
+ case 27:
+ if ((287948969894477824 & l) == 0L)
+ break;
+ if (kind > 27)
+ kind = 27;
+ mccCheckNAdd(27);
+ break;
+ case 28:
+ if ((287948901175001088 & l) != 0L)
+ mccCheckNAddStates(0, 3);
+ break;
+ case 29:
+ if ((287948901175001088 & l) != 0L)
+ mccCheckNAddTwoStates(29, 30);
+ break;
+ case 30:
+ if (curChar != 46)
+ break;
+ if (kind > 24)
+ kind = 24;
+ mccCheckNAddTwoStates(31, 32);
+ break;
+ case 31:
+ if ((287948901175001088 & l) == 0L)
+ break;
+ if (kind > 24)
+ kind = 24;
+ mccCheckNAddTwoStates(31, 32);
+ break;
+ case 33:
+ if ((43980465111040 & l) != 0L)
+ mccCheckNAdd(34);
+ break;
+ case 34:
+ if ((287948901175001088 & l) == 0L)
+ break;
+ if (kind > 24)
+ kind = 24;
+ mccCheckNAdd(34);
+ break;
+ case 35:
+ if ((287948901175001088 & l) != 0L)
+ mccCheckNAddTwoStates(35, 36);
+ break;
+ case 37:
+ if ((43980465111040 & l) != 0L)
+ mccCheckNAdd(38);
+ break;
+ case 38:
+ if ((287948901175001088 & l) == 0L)
+ break;
+ if (kind > 24)
+ kind = 24;
+ mccCheckNAdd(38);
+ break;
+ case 39:
+ if (curChar != 48)
+ break;
+ if (kind > 23)
+ kind = 23;
+ mccCheckNAddTwoStates(40, 42);
+ break;
+ case 41:
+ if ((287948901175001088 & l) == 0L)
+ break;
+ if (kind > 22)
+ kind = 22;
+ mccstateSet[mccnewStateCnt++] = 41;
+ break;
+ case 42:
+ if ((71776119061217280 & l) == 0L)
+ break;
+ if (kind > 23)
+ kind = 23;
+ mccCheckNAdd(42);
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ else if (curChar < 128)
+ {
+ long l = 1L << (curChar & 63);
+ do
+ {
+ switch(mccstateSet[--i])
+ {
+ case 5:
+ case 27:
+ if ((576460745995190270 & l) == 0L)
+ break;
+ if (kind > 27)
+ kind = 27;
+ mccCheckNAdd(27);
+ break;
+ case 1:
+ mccAddStates(7, 9);
+ break;
+ case 7:
+ mccCheckNAddTwoStates(7, 8);
+ break;
+ case 9:
+ case 10:
+ mccCheckNAddTwoStates(10, 8);
+ break;
+ case 15:
+ if ((17592186048512 & l) != 0L && kind > 21)
+ kind = 21;
+ break;
+ case 18:
+ if ((137438953504 & l) != 0L)
+ mccAddStates(13, 14);
+ break;
+ case 24:
+ mccAddStates(4, 6);
+ break;
+ case 32:
+ if ((137438953504 & l) != 0L)
+ mccAddStates(15, 16);
+ break;
+ case 36:
+ if ((137438953504 & l) != 0L)
+ mccAddStates(17, 18);
+ break;
+ case 40:
+ if ((72057594054705152 & l) != 0L)
+ mccCheckNAdd(41);
+ break;
+ case 41:
+ if ((541165879422 & l) == 0L)
+ break;
+ if (kind > 22)
+ kind = 22;
+ mccCheckNAdd(41);
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ else
+ {
+ int hiByte = (curChar >> 8);
+ int i1 = hiByte >> 6;
+ long l1 = 1L << (hiByte & 63);
+ int i2 = (curChar & 0xff) >> 6;
+ long l2 = 1L << (curChar & 63);
+ do
+ {
+ switch(mccstateSet[--i])
+ {
+ case 1:
+ if (mccCanMove_0(hiByte, i1, i2, l1, l2))
+ mccAddStates(7, 9);
+ break;
+ case 7:
+ if (mccCanMove_0(hiByte, i1, i2, l1, l2))
+ mccCheckNAddTwoStates(7, 8);
+ break;
+ case 9:
+ case 10:
+ if (mccCanMove_0(hiByte, i1, i2, l1, l2))
+ mccCheckNAddTwoStates(10, 8);
+ break;
+ case 24:
+ if (mccCanMove_0(hiByte, i1, i2, l1, l2))
+ mccAddStates(4, 6);
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ if (kind != Int32.MaxValue)
+ {
+ mccmatchedKind = kind;
+ mccmatchedPos = curPos;
+ kind = Int32.MaxValue;
+ }
+ ++curPos;
+ if ((i = mccnewStateCnt) == (startsAt = 43 - (mccnewStateCnt = startsAt)))
+ break;
+ try { curChar = input_stream.ReadChar(); }
+ catch(System.IO.IOException) { break; }
+ }
+ if (mccmatchedPos > strPos)
+ return curPos;
+
+ int toRet = Math.Max(curPos, seenUpto);
+
+ if (curPos < toRet)
+ for (i = toRet - Math.Min(curPos, seenUpto); i-- > 0; )
+ try { curChar = input_stream.ReadChar(); }
+ catch(System.IO.IOException) { throw new Exception("Internal Error : Please send a bug report."); }
+
+ if (mccmatchedPos < strPos)
+ {
+ mccmatchedKind = strKind;
+ mccmatchedPos = strPos;
+ }
+ else if (mccmatchedPos == strPos && mccmatchedKind > strKind)
+ mccmatchedKind = strKind;
+
+ return toRet;
+}
static readonly int[] mccnextStates = {
29, 30, 35, 36, 23, 24, 25, 1, 2, 4, 8, 9, 11, 19, 20, 33,
34, 37, 38,
-};
-private static bool mccCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
-{
- switch(hiByte)
- {
- case 0:
- return ((mccbitVec2[i2] & l2) != 0L);
- default :
- if ((mccbitVec0[i1] & l1) != 0L)
- if ((mccbitVec1[i2] & l2) == 0L)
- return false;
- else
- return true;
- return false;
- }
-}
-public static readonly string[] mccstrLiteralImages = {
-"", null, null, null, null, null, null, null, null, null, null, null, null,
-null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-null, "=", "<>", ">", ">=", "<", "<=", "(", ",", ")", "+", "-", "*", "/", "%", };
-public static readonly string[] lexStateNames = {
- "DEFAULT",
-};
+};
+private static bool mccCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
+{
+ switch(hiByte)
+ {
+ case 0:
+ return ((mccbitVec2[i2] & l2) != 0L);
+ default :
+ if ((mccbitVec0[i1] & l1) != 0L)
+ if ((mccbitVec1[i2] & l2) == 0L)
+ return false;
+ else
+ return true;
+ return false;
+ }
+}
+public static readonly string[] mccstrLiteralImages = {
+"", null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, "=", "<>", ">", ">=", "<", "<=", "(", ",", ")", "+", "-", "*", "/", "%", };
+public static readonly string[] lexStateNames = {
+ "DEFAULT",
+};
static readonly long[] mcctoToken = {
4398012956417,
-};
+};
static readonly long[] mcctoSkip = {
254,
-};
+};
static readonly long[] mcctoSpecial = {
62,
-};
-protected SimpleCharStream input_stream;
-private readonly int[] mccrounds = new int[43];
-private readonly int[] mccstateSet = new int[86];
-protected char curChar;
-public SelectorParserTokenManager(SimpleCharStream stream) {
- if (SimpleCharStream.staticFlag)
- throw new System.SystemException("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
- input_stream = stream;
-}
-public SelectorParserTokenManager(SimpleCharStream stream, int lexState)
- : this(stream) {
- SwitchTo(lexState);
-}
-public void ReInit(SimpleCharStream stream) {
- mccmatchedPos = mccnewStateCnt = 0;
- curLexState = defaultLexState;
- input_stream = stream;
- ReInitRounds();
-}
-private void ReInitRounds()
-{
- int i;
- mccround = -2147483647;
- for (i = 43; i-- > 0;)
- mccrounds[i] = Int32.MinValue;
-}
-public void ReInit(SimpleCharStream stream, int lexState) {
- ReInit(stream);
- SwitchTo(lexState);
-}
-public void SwitchTo(int lexState) {
- if (lexState >= 1 || lexState < 0)
- throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.InvalidLexicalState);
- else
- curLexState = lexState;
-}
-
-protected Token mccFillToken()
-{
- Token t = Token.NewToken(mccmatchedKind);
- t.kind = mccmatchedKind;
- string im = mccstrLiteralImages[mccmatchedKind];
- t.image = (im == null) ? input_stream.GetImage() : im;
- t.beginLine = input_stream.BeginLine;
- t.beginColumn = input_stream.BeginColumn;
- t.endLine = input_stream.EndLine;
- t.endColumn = input_stream.EndColumn;
- return t;
-}
-
-int curLexState = 0;
-int defaultLexState = 0;
-int mccnewStateCnt;
-int mccround;
-int mccmatchedPos;
-int mccmatchedKind;
-
-public Token GetNextToken() {
- //int kind;
- Token specialToken = null;
- Token matchedToken;
- int curPos = 0;
-
-for (;;) {
- try {
- curChar = input_stream.BeginToken();
- } catch(System.IO.IOException) {
- mccmatchedKind = 0;
- matchedToken = mccFillToken();
- matchedToken.specialToken = specialToken;
- return matchedToken;
- }
-
- mccmatchedKind = Int32.MaxValue;
- mccmatchedPos = 0;
- curPos = mccMoveStringLiteralDfa0_0();
- if (mccmatchedKind != Int32.MaxValue) {
- if (mccmatchedPos + 1 < curPos)
- input_stream.Backup(curPos - mccmatchedPos - 1);
- if ((mcctoToken[mccmatchedKind >> 6] & (1L << (mccmatchedKind & 63))) != 0L) {
- matchedToken = mccFillToken();
- matchedToken.specialToken = specialToken;
- return matchedToken;
- }
- else
- {
- if ((mcctoSpecial[mccmatchedKind >> 6] & (1L << (mccmatchedKind & 63))) != 0L) {
- matchedToken = mccFillToken();
- if (specialToken == null)
- specialToken = matchedToken;
- else {
- matchedToken.specialToken = specialToken;
- specialToken = (specialToken.next = matchedToken);
- }
- }
- goto EOFLoop;
- }
- }
- int error_line = input_stream.EndLine;
- int error_column = input_stream.EndColumn;
- string error_after = null;
- bool EOFSeen = false;
- try { input_stream.ReadChar(); input_stream.Backup(1); }
- catch (System.IO.IOException) {
- EOFSeen = true;
- error_after = curPos <= 1 ? "" : input_stream.GetImage();
- if (curChar == '\n' || curChar == '\r') {
- error_line++;
- error_column = 0;
- } else
- error_column++;
- }
- if (!EOFSeen) {
- input_stream.Backup(1);
- error_after = curPos <= 1 ? "" : input_stream.GetImage();
- }
- throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LexicalError);
-EOFLoop: ;
- }
-}
-
-}
+};
+protected SimpleCharStream input_stream;
+private readonly int[] mccrounds = new int[43];
+private readonly int[] mccstateSet = new int[86];
+protected char curChar;
+public SelectorParserTokenManager(SimpleCharStream stream) {
+ if (SimpleCharStream.staticFlag)
+ throw new System.SystemException("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+ input_stream = stream;
+}
+public SelectorParserTokenManager(SimpleCharStream stream, int lexState)
+ : this(stream) {
+ SwitchTo(lexState);
+}
+public void ReInit(SimpleCharStream stream) {
+ mccmatchedPos = mccnewStateCnt = 0;
+ curLexState = defaultLexState;
+ input_stream = stream;
+ ReInitRounds();
+}
+private void ReInitRounds()
+{
+ int i;
+ mccround = -2147483647;
+ for (i = 43; i-- > 0;)
+ mccrounds[i] = Int32.MinValue;
+}
+public void ReInit(SimpleCharStream stream, int lexState) {
+ ReInit(stream);
+ SwitchTo(lexState);
+}
+public void SwitchTo(int lexState) {
+ if (lexState >= 1 || lexState < 0)
+ throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.InvalidLexicalState);
+ else
+ curLexState = lexState;
+}
+
+protected Token mccFillToken()
+{
+ Token t = Token.NewToken(mccmatchedKind);
+ t.kind = mccmatchedKind;
+ string im = mccstrLiteralImages[mccmatchedKind];
+ t.image = (im == null) ? input_stream.GetImage() : im;
+ t.beginLine = input_stream.BeginLine;
+ t.beginColumn = input_stream.BeginColumn;
+ t.endLine = input_stream.EndLine;
+ t.endColumn = input_stream.EndColumn;
+ return t;
+}
+
+int curLexState = 0;
+int defaultLexState = 0;
+int mccnewStateCnt;
+int mccround;
+int mccmatchedPos;
+int mccmatchedKind;
+
+public Token GetNextToken() {
+ //int kind;
+ Token specialToken = null;
+ Token matchedToken;
+ int curPos = 0;
+
+for (;;) {
+ try {
+ curChar = input_stream.BeginToken();
+ } catch(System.IO.IOException) {
+ mccmatchedKind = 0;
+ matchedToken = mccFillToken();
+ matchedToken.specialToken = specialToken;
+ return matchedToken;
+ }
+
+ mccmatchedKind = Int32.MaxValue;
+ mccmatchedPos = 0;
+ curPos = mccMoveStringLiteralDfa0_0();
+ if (mccmatchedKind != Int32.MaxValue) {
+ if (mccmatchedPos + 1 < curPos)
+ input_stream.Backup(curPos - mccmatchedPos - 1);
+ if ((mcctoToken[mccmatchedKind >> 6] & (1L << (mccmatchedKind & 63))) != 0L) {
+ matchedToken = mccFillToken();
+ matchedToken.specialToken = specialToken;
+ return matchedToken;
+ }
+ else
+ {
+ if ((mcctoSpecial[mccmatchedKind >> 6] & (1L << (mccmatchedKind & 63))) != 0L) {
+ matchedToken = mccFillToken();
+ if (specialToken == null)
+ specialToken = matchedToken;
+ else {
+ matchedToken.specialToken = specialToken;
+ specialToken = (specialToken.next = matchedToken);
+ }
+ }
+ goto EOFLoop;
+ }
+ }
+ int error_line = input_stream.EndLine;
+ int error_column = input_stream.EndColumn;
+ string error_after = null;
+ bool EOFSeen = false;
+ try { input_stream.ReadChar(); input_stream.Backup(1); }
+ catch (System.IO.IOException) {
+ EOFSeen = true;
+ error_after = curPos <= 1 ? "" : input_stream.GetImage();
+ if (curChar == '\n' || curChar == '\r') {
+ error_line++;
+ error_column = 0;
+ } else
+ error_column++;
+ }
+ if (!EOFSeen) {
+ input_stream.Backup(1);
+ error_after = curPos <= 1 ? "" : input_stream.GetImage();
+ }
+ throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LexicalError);
+EOFLoop: ;
+ }
+}
+
+}
diff --git a/src/main/csharp/Selector/SimpleCharStream.cs b/src/main/csharp/Selector/SimpleCharStream.cs
index a49a9da..1e45359 100644
--- a/src/main/csharp/Selector/SimpleCharStream.cs
+++ b/src/main/csharp/Selector/SimpleCharStream.cs
@@ -1,366 +1,366 @@
-/* Generated By:CSharpCC: Do not edit this line. SimpleCharStream.cs Version 3.3 */
-/// <summary>
-/// An implementation of interface CharStream, where the stream is assumed to
-/// contain only ASCII characters (without unicode processing).
-/// </summary>
-
-public class SimpleCharStream {
- public static readonly bool staticFlag = false;
- int bufsize;
- int available;
- int tokenBegin;
- public int bufpos = -1;
- protected int[] bufline;
- protected int[] bufcolumn;
-
- protected int column = 0;
- protected int line = 1;
-
- protected bool prevCharIsCR = false;
- protected bool prevCharIsLF = false;
-
- protected System.IO.TextReader inputStream;
-
- protected char[] buffer;
- protected int maxNextCharInd = 0;
- protected int inBuf = 0;
-
- protected void ExpandBuff(bool wrapAround)
- {
- char[] newbuffer = new char[bufsize + 2048];
- int[] newbufline = new int[bufsize + 2048];
- int[] newbufcolumn = new int[bufsize + 2048];
-
- try {
- if (wrapAround) {
- System.Array.Copy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
- System.Array.Copy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
- buffer = newbuffer;
-
- System.Array.Copy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
- System.Array.Copy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
- bufline = newbufline;
-
- System.Array.Copy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
- System.Array.Copy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
- bufcolumn = newbufcolumn;
-
- maxNextCharInd = (bufpos += (bufsize - tokenBegin));
- } else {
- System.Array.Copy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
- buffer = newbuffer;
-
- System.Array.Copy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
- bufline = newbufline;
-
- System.Array.Copy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
- bufcolumn = newbufcolumn;
-
- maxNextCharInd = (bufpos -= tokenBegin);
- }
- } catch (System.Exception e) {
- throw new System.SystemException(e.Message);
- }
-
-
- bufsize += 2048;
- available = bufsize;
- tokenBegin = 0;
- }
-
- protected void FillBuff() {
- if (maxNextCharInd == available) {
- if (available == bufsize) {
- if (tokenBegin > 2048) {
- bufpos = maxNextCharInd = 0;
- available = tokenBegin;
- } else if (tokenBegin < 0)
- bufpos = maxNextCharInd = 0;
- else
- ExpandBuff(false);
- } else if (available > tokenBegin)
- available = bufsize;
- else if ((tokenBegin - available) < 2048)
- ExpandBuff(true);
- else
- available = tokenBegin;
- }
-
- int i;
- try {
- if ((i = inputStream.Read(buffer, maxNextCharInd,
- available - maxNextCharInd)) == -1) {
- inputStream.Close();
- throw new System.IO.IOException();
- } else
- maxNextCharInd += i;
- return;
- } catch(System.IO.IOException e) {
- --bufpos;
- Backup(0);
- if (tokenBegin == -1)
- tokenBegin = bufpos;
- throw e;
- }
- }
-
- public char BeginToken() {
- tokenBegin = -1;
- try {
- char c = ReadChar();
- tokenBegin = bufpos;
- return c;
- } catch (System.IO.EndOfStreamException e) {
- if (tokenBegin == -1)
- tokenBegin = bufpos;
- throw e;
- }
- }
-
- protected void UpdateLineColumn(char c) {
- column++;
-
- if (prevCharIsLF) {
- prevCharIsLF = false;
- line += (column = 1);
- } else if (prevCharIsCR) {
- prevCharIsCR = false;
- if (c == '\n') {
- prevCharIsLF = true;
- } else
- line += (column = 1);
- }
-
- switch (c) {
- case '\r' :
- prevCharIsCR = true;
- break;
- case '\n' :
- prevCharIsLF = true;
- break;
- case '\t' :
- column--;
- column += (8 - (column & 07));
- break;
- default :
- break;
- }
-
- bufline[bufpos] = line;
- bufcolumn[bufpos] = column;
- }
-
- public char ReadChar() {
- if (inBuf > 0) {
- --inBuf;
-
- if (++bufpos == bufsize)
- bufpos = 0;
-
- return buffer[bufpos];
- }
-
- if (++bufpos >= maxNextCharInd)
- FillBuff();
- if (bufpos >= maxNextCharInd) {
- bufpos--;
- if (bufpos < 0)
- bufpos += bufsize;
- throw new System.IO.EndOfStreamException();
- }
-
- char c = buffer[bufpos];
-
- UpdateLineColumn(c);
- return (c);
- }
-
-[System.Obsolete("Deprecated - use EndColumn instead.", false)]
-
- public int Column {
- get {
- return bufcolumn[bufpos];
- }
- }
-
-[System.Obsolete("Deprecated - use EndLine instead.", false)]
-
- public int Line {
- get {
- return bufline[bufpos];
- }
- }
-
- public int EndColumn {
- get {
- return bufcolumn[bufpos];
- }
- }
-
- public int EndLine {
- get {
- return bufline[bufpos];
- }
- }
-
- public int BeginColumn {
- get {
- return bufcolumn[tokenBegin];
- }
- }
-
- public int BeginLine {
- get {
- return bufline[tokenBegin];
- }
- }
-
- public void Backup(int amount) {
-
- inBuf += amount;
- if ((bufpos -= amount) < 0)
- bufpos += bufsize;
- }
-
- public SimpleCharStream(System.IO.TextReader dstream, int startline,
- int startcolumn, int buffersize) {
- inputStream = dstream;
- line = startline;
- column = startcolumn - 1;
-
- available = bufsize = buffersize;
- buffer = new char[buffersize];
- bufline = new int[buffersize];
- bufcolumn = new int[buffersize];
- }
-
- public SimpleCharStream(System.IO.TextReader dstream, int startline,
- int startcolumn) :
- this(dstream, startline, startcolumn, 4096) {
- }
-
- public SimpleCharStream(System.IO.TextReader dstream) :
- this(dstream, 1, 1, 4096) {
- }
- public void ReInit(System.IO.TextReader dstream, int startline,
- int startcolumn, int buffersize) {
- inputStream = dstream;
- line = startline;
- column = startcolumn - 1;
-
- if (buffer == null || buffersize != buffer.Length) {
- available = bufsize = buffersize;
- buffer = new char[buffersize];
- bufline = new int[buffersize];
- bufcolumn = new int[buffersize];
- }
- prevCharIsLF = prevCharIsCR = false;
- tokenBegin = inBuf = maxNextCharInd = 0;
- bufpos = -1;
- }
-
- public void ReInit(System.IO.TextReader dstream, int startline,
- int startcolumn) {
- ReInit(dstream, startline, startcolumn, 4096);
- }
-
- public void ReInit(System.IO.TextReader dstream) {
- ReInit(dstream, 1, 1, 4096);
- }
- public SimpleCharStream(System.IO.Stream dstream, int startline,
- int startcolumn, int buffersize) :
- this(new System.IO.StreamReader(dstream), startline, startcolumn, 4096) {
- }
-
- public SimpleCharStream(System.IO.Stream dstream, int startline,
- int startcolumn) :
- this(dstream, startline, startcolumn, 4096) {
- }
-
- public SimpleCharStream(System.IO.Stream dstream) :
- this(dstream, 1, 1, 4096) {
- }
-
- public void ReInit(System.IO.Stream dstream, int startline,
- int startcolumn, int buffersize) {
- ReInit(new System.IO.StreamReader(dstream), startline, startcolumn, 4096);
- }
-
- public void ReInit(System.IO.Stream dstream) {
- ReInit(dstream, 1, 1, 4096);
- }
- public void ReInit(System.IO.Stream dstream, int startline,
- int startcolumn) {
- ReInit(dstream, startline, startcolumn, 4096);
- }
- public string GetImage() {
- if (bufpos >= tokenBegin)
- return new string(buffer, tokenBegin, bufpos - tokenBegin + 1);
- else
- return new string(buffer, tokenBegin, bufsize - tokenBegin) +
- new string(buffer, 0, bufpos + 1);
- }
-
- public char[] GetSuffix(int len) {
- char[] ret = new char[len];
-
- if ((bufpos + 1) >= len)
- System.Array.Copy(buffer, bufpos - len + 1, ret, 0, len);
- else {
- System.Array.Copy(buffer, bufsize - (len - bufpos - 1), ret, 0,
- len - bufpos - 1);
- System.Array.Copy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
- }
-
- return ret;
- }
-
- public void Done()
- {
- buffer = null;
- bufline = null;
- bufcolumn = null;
- }
-
- /// <summary>
- /// Method to adjust line and column numbers for the start of a token.
- /// </summary>
- public void AdjustBeginLineColumn(int newLine, int newCol) {
- int start = tokenBegin;
- int len;
-
- if (bufpos >= tokenBegin) {
- len = bufpos - tokenBegin + inBuf + 1;
- } else {
- len = bufsize - tokenBegin + bufpos + 1 + inBuf;
- }
-
- int i = 0, j = 0, k = 0;
- int nextColDiff = 0, columnDiff = 0;
-
- while (i < len &&
- bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) {
- bufline[j] = newLine;
- nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
- bufcolumn[j] = newCol + columnDiff;
- columnDiff = nextColDiff;
- i++;
- }
-
- if (i < len) {
- bufline[j] = newLine++;
- bufcolumn[j] = newCol + columnDiff;
-
- while (i++ < len) {
- if (bufline[j = start % bufsize] != bufline[++start % bufsize])
- bufline[j] = newLine++;
- else
- bufline[j] = newLine;
- }
- }
-
- line = bufline[j];
- column = bufcolumn[j];
- }
-
-}
+/* Generated By:CSharpCC: Do not edit this charLine. SimpleCharStream.cs Version 3.3 */
+/// <summary>
+/// An implementation of interface CharStream, where the stream is assumed to
+/// contain only ASCII characters (without unicode processing).
+/// </summary>
+
+public class SimpleCharStream {
+ public static readonly bool staticFlag = false;
+ int bufsize;
+ int available;
+ int tokenBegin;
+ public int bufpos = -1;
+ protected int[] bufline;
+ protected int[] bufcolumn;
+
+ protected int charColumn = 0;
+ protected int charLine = 1;
+
+ protected bool prevCharIsCR = false;
+ protected bool prevCharIsLF = false;
+
+ protected System.IO.TextReader inputStream;
+
+ protected char[] buffer;
+ protected int maxNextCharInd = 0;
+ protected int inBuf = 0;
+
+ protected void ExpandBuff(bool wrapAround)
+ {
+ char[] newbuffer = new char[bufsize + 2048];
+ int[] newbufline = new int[bufsize + 2048];
+ int[] newbufcolumn = new int[bufsize + 2048];
+
+ try {
+ if (wrapAround) {
+ System.Array.Copy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ System.Array.Copy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
+ buffer = newbuffer;
+
+ System.Array.Copy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ System.Array.Copy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+ bufline = newbufline;
+
+ System.Array.Copy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+ System.Array.Copy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+ bufcolumn = newbufcolumn;
+
+ maxNextCharInd = (bufpos += (bufsize - tokenBegin));
+ } else {
+ System.Array.Copy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ buffer = newbuffer;
+
+ System.Array.Copy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ bufline = newbufline;
+
+ System.Array.Copy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+ bufcolumn = newbufcolumn;
+
+ maxNextCharInd = (bufpos -= tokenBegin);
+ }
+ } catch (System.Exception e) {
+ throw new System.SystemException(e.Message);
+ }
+
+
+ bufsize += 2048;
+ available = bufsize;
+ tokenBegin = 0;
+ }
+
+ protected void FillBuff() {
+ if (maxNextCharInd == available) {
+ if (available == bufsize) {
+ if (tokenBegin > 2048) {
+ bufpos = maxNextCharInd = 0;
+ available = tokenBegin;
+ } else if (tokenBegin < 0)
+ bufpos = maxNextCharInd = 0;
+ else
+ ExpandBuff(false);
+ } else if (available > tokenBegin)
+ available = bufsize;
+ else if ((tokenBegin - available) < 2048)
+ ExpandBuff(true);
+ else
+ available = tokenBegin;
+ }
+
+ int i;
+ try {
+ if ((i = inputStream.Read(buffer, maxNextCharInd,
+ available - maxNextCharInd)) == -1) {
+ inputStream.Close();
+ throw new System.IO.IOException();
+ } else
+ maxNextCharInd += i;
+ return;
+ } catch(System.IO.IOException e) {
+ --bufpos;
+ Backup(0);
+ if (tokenBegin == -1)
+ tokenBegin = bufpos;
+ throw e;
+ }
+ }
+
+ public char BeginToken() {
+ tokenBegin = -1;
+ try {
+ char c = ReadChar();
+ tokenBegin = bufpos;
+ return c;
+ } catch (System.IO.EndOfStreamException e) {
+ if (tokenBegin == -1)
+ tokenBegin = bufpos;
+ throw e;
+ }
+ }
+
+ protected void UpdateLineColumn(char c) {
+ charColumn++;
+
+ if (prevCharIsLF) {
+ prevCharIsLF = false;
+ charLine += (charColumn = 1);
+ } else if (prevCharIsCR) {
+ prevCharIsCR = false;
+ if (c == '\n') {
+ prevCharIsLF = true;
+ } else
+ charLine += (charColumn = 1);
+ }
+
+ switch (c) {
+ case '\r' :
+ prevCharIsCR = true;
+ break;
+ case '\n' :
+ prevCharIsLF = true;
+ break;
+ case '\t' :
+ charColumn--;
+ charColumn += (8 - (charColumn & 07));
+ break;
+ default :
+ break;
+ }
+
+ bufline[bufpos] = charLine;
+ bufcolumn[bufpos] = charColumn;
+ }
+
+ public char ReadChar() {
+ if (inBuf > 0) {
+ --inBuf;
+
+ if (++bufpos == bufsize)
+ bufpos = 0;
+
+ return buffer[bufpos];
+ }
+
+ if (++bufpos >= maxNextCharInd)
+ FillBuff();
+ if (bufpos >= maxNextCharInd) {
+ bufpos--;
+ if (bufpos < 0)
+ bufpos += bufsize;
+ throw new System.IO.EndOfStreamException();
+ }
+
+ char c = buffer[bufpos];
+
+ UpdateLineColumn(c);
+ return (c);
+ }
+
+[System.Obsolete("Deprecated - use EndColumn instead.", false)]
+
+ public int Column {
+ get {
+ return bufcolumn[bufpos];
+ }
+ }
+
+[System.Obsolete("Deprecated - use EndLine instead.", false)]
+
+ public int Line {
+ get {
+ return bufline[bufpos];
+ }
+ }
+
+ public int EndColumn {
+ get {
+ return bufcolumn[bufpos];
+ }
+ }
+
+ public int EndLine {
+ get {
+ return bufline[bufpos];
+ }
+ }
+
+ public int BeginColumn {
+ get {
+ return bufcolumn[tokenBegin];
+ }
+ }
+
+ public int BeginLine {
+ get {
+ return bufline[tokenBegin];
+ }
+ }
+
+ public void Backup(int amount) {
+
+ inBuf += amount;
+ if ((bufpos -= amount) < 0)
+ bufpos += bufsize;
+ }
+
+ public SimpleCharStream(System.IO.TextReader dstream, int startline,
+ int startcolumn, int buffersize) {
+ inputStream = dstream;
+ charLine = startline;
+ charColumn = startcolumn - 1;
+
+ available = bufsize = buffersize;
+ buffer = new char[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+ }
+
+ public SimpleCharStream(System.IO.TextReader dstream, int startline,
+ int startcolumn) :
+ this(dstream, startline, startcolumn, 4096) {
+ }
+
+ public SimpleCharStream(System.IO.TextReader dstream) :
+ this(dstream, 1, 1, 4096) {
+ }
+ public void ReInit(System.IO.TextReader dstream, int startline,
+ int startcolumn, int buffersize) {
+ inputStream = dstream;
+ charLine = startline;
+ charColumn = startcolumn - 1;
+
+ if (buffer == null || buffersize != buffer.Length) {
+ available = bufsize = buffersize;
+ buffer = new char[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+ }
+ prevCharIsLF = prevCharIsCR = false;
+ tokenBegin = inBuf = maxNextCharInd = 0;
+ bufpos = -1;
+ }
+
+ public void ReInit(System.IO.TextReader dstream, int startline,
+ int startcolumn) {
+ ReInit(dstream, startline, startcolumn, 4096);
+ }
+
+ public void ReInit(System.IO.TextReader dstream) {
+ ReInit(dstream, 1, 1, 4096);
+ }
+ public SimpleCharStream(System.IO.Stream dstream, int startline,
+ int startcolumn, int buffersize) :
+ this(new System.IO.StreamReader(dstream), startline, startcolumn, 4096) {
+ }
+
+ public SimpleCharStream(System.IO.Stream dstream, int startline,
+ int startcolumn) :
+ this(dstream, startline, startcolumn, 4096) {
+ }
+
+ public SimpleCharStream(System.IO.Stream dstream) :
+ this(dstream, 1, 1, 4096) {
+ }
+
+ public void ReInit(System.IO.Stream dstream, int startline,
+ int startcolumn, int buffersize) {
+ ReInit(new System.IO.StreamReader(dstream), startline, startcolumn, 4096);
+ }
+
+ public void ReInit(System.IO.Stream dstream) {
+ ReInit(dstream, 1, 1, 4096);
+ }
+ public void ReInit(System.IO.Stream dstream, int startline,
+ int startcolumn) {
+ ReInit(dstream, startline, startcolumn, 4096);
+ }
+ public string GetImage() {
+ if (bufpos >= tokenBegin)
+ return new string(buffer, tokenBegin, bufpos - tokenBegin + 1);
+ else
+ return new string(buffer, tokenBegin, bufsize - tokenBegin) +
+ new string(buffer, 0, bufpos + 1);
+ }
+
+ public char[] GetSuffix(int len) {
+ char[] ret = new char[len];
+
+ if ((bufpos + 1) >= len)
+ System.Array.Copy(buffer, bufpos - len + 1, ret, 0, len);
+ else {
+ System.Array.Copy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+ len - bufpos - 1);
+ System.Array.Copy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+ }
+
+ return ret;
+ }
+
+ public void Done()
+ {
+ buffer = null;
+ bufline = null;
+ bufcolumn = null;
+ }
+
+ /// <summary>
+ /// Method to adjust charLine and charColumn numbers for the start of a token.
+ /// </summary>
+ public void AdjustBeginLineColumn(int newLine, int newCol) {
+ int start = tokenBegin;
+ int len;
+
+ if (bufpos >= tokenBegin) {
+ len = bufpos - tokenBegin + inBuf + 1;
+ } else {
+ len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+ }
+
+ int i = 0, j = 0, k = 0;
+ int nextColDiff = 0, columnDiff = 0;
+
+ while (i < len &&
+ bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) {
+ bufline[j] = newLine;
+ nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+ bufcolumn[j] = newCol + columnDiff;
+ columnDiff = nextColDiff;
+ i++;
+ }
+
+ if (i < len) {
+ bufline[j] = newLine++;
+ bufcolumn[j] = newCol + columnDiff;
+
+ while (i++ < len) {
+ if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+ bufline[j] = newLine++;
+ else
+ bufline[j] = newLine;
+ }
+ }
+
+ charLine = bufline[j];
+ charColumn = bufcolumn[j];
+ }
+
+}
diff --git a/src/main/csharp/Selector/Token.cs b/src/main/csharp/Selector/Token.cs
index bc5b705..49bc4ea 100644
--- a/src/main/csharp/Selector/Token.cs
+++ b/src/main/csharp/Selector/Token.cs
@@ -1,78 +1,78 @@
-/* Generated By:CSharpCC: Do not edit this line. Token.cs Version 3.0 */
-/// <summary>
-/// Describes the input token stream.
-/// </summary>
-
-public class Token {
-
- /// <summary>
- /// Gets an integer that describes the kind of this token.
- /// </summary>
- /// <remarks>
- /// This numbering system is determined by CSharpCCParser, and
- /// a table of these numbers is stored in the class <see cref="SelectorParserConstants"/>.
- /// </remarks>
- public int kind;
-
- /**
- * beginLine and beginColumn describe the position of the first character
- * of this token; endLine and endColumn describe the position of the
- * last character of this token.
- */
- public int beginLine, beginColumn, endLine, endColumn;
-
- /**
- * The string image of the token.
- */
- public string image;
-
- /**
- * A reference to the next regular (non-special) token from the input
- * stream. If this is the last token from the input stream, or if the
- * token manager has not read tokens beyond this one, this field is
- * set to null. This is true only if this token is also a regular
- * token. Otherwise, see below for a description of the contents of
- * this field.
- */
- public Token next;
-
- /**
- * This field is used to access special tokens that occur prior to this
- * token, but after the immediately preceding regular (non-special) token.
- * If there are no such special tokens, this field is set to null.
- * When there are more than one such special token, this field refers
- * to the last of these special tokens, which in turn refers to the next
- * previous special token through its specialToken field, and so on
- * until the first special token (whose specialToken field is null).
- * The next fields of special tokens refer to other special tokens that
- * immediately follow it (without an intervening regular token). If there
- * is no such token, this field is null.
- */
- public Token specialToken;
-
- /**
- * Returns the image.
- */
- public override string ToString() {
- return image;
- }
-
- /**
- * Returns a new Token object, by default. However, if you want, you
- * can create and return subclass objects based on the value of ofKind.
- * Simply add the cases to the switch for all those special cases.
- * For example, if you have a subclass of Token called IDToken that
- * you want to create if ofKind is ID, simlpy add something like :
- *
- * case MyParserConstants.ID : return new IDToken();
- *
- * to the following switch statement. Then you can cast matchedToken
- * variable to the appropriate type and use it in your lexical actions.
- */
- public static Token NewToken(int ofKind) {
- switch(ofKind) {
- default : return new Token();
- }
- }
-
-}
+/* Generated By:CSharpCC: Do not edit this line. Token.cs Version 3.0 */
+/// <summary>
+/// Describes the input token stream.
+/// </summary>
+
+public class Token {
+
+ /// <summary>
+ /// Gets an integer that describes the kind of this token.
+ /// </summary>
+ /// <remarks>
+ /// This numbering system is determined by CSharpCCParser, and
+ /// a table of these numbers is stored in the class <see cref="SelectorParserConstants"/>.
+ /// </remarks>
+ public int kind;
+
+ /**
+ * beginLine and beginColumn describe the position of the first character
+ * of this token; endLine and endColumn describe the position of the
+ * last character of this token.
+ */
+ public int beginLine, beginColumn, endLine, endColumn;
+
+ /**
+ * The string image of the token.
+ */
+ public string image;
+
+ /**
+ * A reference to the next regular (non-special) token from the input
+ * stream. If this is the last token from the input stream, or if the
+ * token manager has not read tokens beyond this one, this field is
+ * set to null. This is true only if this token is also a regular
+ * token. Otherwise, see below for a description of the contents of
+ * this field.
+ */
+ public Token next;
+
+ /**
+ * This field is used to access special tokens that occur prior to this
+ * token, but after the immediately preceding regular (non-special) token.
+ * If there are no such special tokens, this field is set to null.
+ * When there are more than one such special token, this field refers
+ * to the last of these special tokens, which in turn refers to the next
+ * previous special token through its specialToken field, and so on
+ * until the first special token (whose specialToken field is null).
+ * The next fields of special tokens refer to other special tokens that
+ * immediately follow it (without an intervening regular token). If there
+ * is no such token, this field is null.
+ */
+ public Token specialToken;
+
+ /**
+ * Returns the image.
+ */
+ public override string ToString() {
+ return image;
+ }
+
+ /**
+ * Returns a new Token object, by default. However, if you want, you
+ * can create and return subclass objects based on the value of ofKind.
+ * Simply add the cases to the switch for all those special cases.
+ * For example, if you have a subclass of Token called IDToken that
+ * you want to create if ofKind is ID, simlpy add something like :
+ *
+ * case MyParserConstants.ID : return new IDToken();
+ *
+ * to the following switch statement. Then you can cast matchedToken
+ * variable to the appropriate type and use it in your lexical actions.
+ */
+ public static Token NewToken(int ofKind) {
+ switch(ofKind) {
+ default : return new Token();
+ }
+ }
+
+}
diff --git a/src/main/csharp/Selector/TokenMgrError.cs b/src/main/csharp/Selector/TokenMgrError.cs
index b011703..f525134 100644
--- a/src/main/csharp/Selector/TokenMgrError.cs
+++ b/src/main/csharp/Selector/TokenMgrError.cs
@@ -1,130 +1,130 @@
-/* Generated By:CSharpCC: Do not edit this line. TokenMgrError.cs Version 3.0 */
-public class TokenMgrError : System.SystemException
-{
- /*
- * Ordinals for various reasons why an Exceptions of this type can be thrown.
- */
-
- /**
- * Lexical error occured.
- */
- internal static readonly int LexicalError = 0;
-
- /**
- * An attempt wass made to create a second instance of a static token manager.
- */
- internal static readonly int StaticLexerError = 1;
-
- /**
- * Tried to change to an invalid lexical state.
- */
- internal static readonly int InvalidLexicalState = 2;
-
- /**
- * Detected (and bailed out of) an infinite loop in the token manager.
- */
- internal static readonly int LoopDetected = 3;
-
- /**
- * Indicates the reason why the exception is thrown. It will have
- * one of the above 4 values.
- */
- int errorCode;
-
- /**
- * Replaces unprintable characters by their espaced (or unicode escaped)
- * equivalents in the given string
- */
- protected static string AddEscapes(string str) {
- System.Text.StringBuilder retval = new System.Text.StringBuilder();
- char ch;
- for (int i = 0; i < str.Length; i++) {
- switch (str[i]) {
- case '\0' :
- continue;
- case '\b':
- retval.Append("\\b");
- continue;
- case '\t':
- retval.Append("\\t");
- continue;
- case '\n':
- retval.Append("\\n");
- continue;
- case '\f':
- retval.Append("\\f");
- continue;
- case '\r':
- retval.Append("\\r");
- continue;
- case '\"':
- retval.Append("\\\"");
- continue;
- case '\'':
- retval.Append("\\\'");
- continue;
- case '\\':
- retval.Append("\\\\");
- continue;
- default:
- if ((ch = str[i]) < 0x20 || ch > 0x7e) {
- string s = "0000" + System.Convert.ToString((int)ch, 16);
- retval.Append("\\u" + s.Substring(s.Length - 4, s.Length - (s.Length - 4)));
- } else {
- retval.Append(ch);
- }
- continue;
- }
- }
- return retval.ToString();
- }
-
- /**
- * Returns a detailed message for the Exception when it is thrown by the
- * token manager to indicate a lexical error.
- * Parameters :
- * EOFSeen : indicates if EOF caused the lexicl error
- * curLexState : lexical state in which this error occured
- * errorLine : line number when the error occured
- * errorColumn : column number when the error occured
- * errorAfter : prefix that was seen before this error occured
- * curchar : the offending character
- * Note: You can customize the lexical error message by modifying this method.
- */
- protected static string GetLexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, string errorAfter, char curChar) {
- return("Lexical error at line " +
- errorLine + ", column " +
- errorColumn + ". Encountered: " +
- (EOFSeen ? "<EOF> " : ("\"" + AddEscapes(curChar.ToString()) + "\"") + " (" + (int)curChar + "), ") +
- "after : \"" + AddEscapes(errorAfter) + "\"");
- }
-
- /**
- * You can also modify the body of this method to customize your error messages.
- * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
- * of end-users concern, so you can return something like :
- *
- * "Internal Error : Please file a bug report .... "
- *
- * from this method for such cases in the release version of your parser.
- */
- public override string Message {
- get { return base.Message; }
- }
-
- /*
- * Constructors of various flavors follow.
- */
-
- public TokenMgrError() {
- }
-
- public TokenMgrError(string message, int reason) :
- base(message) {
- errorCode = reason;
- }
-
- public TokenMgrError(bool EOFSeen, int lexState, int errorLine, int errorColumn, string errorAfter, char curChar, int reason) :
- this(GetLexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason) {
- }
-}
+/* Generated By:CSharpCC: Do not edit this line. TokenMgrError.cs Version 3.0 */
+public class TokenMgrError : System.SystemException
+{
+ /*
+ * Ordinals for various reasons why an Exceptions of this type can be thrown.
+ */
+
+ /*
+ * Lexical error occured.
+ */
+ internal static readonly int LexicalError = 0;
+
+ /*
+ * An attempt wass made to create a second instance of a static token manager.
+ */
+ internal static readonly int StaticLexerError = 1;
+
+ /*
+ * Tried to change to an invalid lexical state.
+ */
+ internal static readonly int InvalidLexicalState = 2;
+
+ /*
+ * Detected (and bailed out of) an infinite loop in the token manager.
+ */
+ internal static readonly int LoopDetected = 3;
+
+ /*
+ * Indicates the reason why the exception is thrown. It will have
+ * one of the above 4 values.
+ */
+ int errorCode;
+
+ /*
+ * Replaces unprintable characters by their espaced (or unicode escaped)
+ * equivalents in the given string
+ */
+ protected static string AddEscapes(string str) {
+ System.Text.StringBuilder retval = new System.Text.StringBuilder();
+ char ch;
+ for (int i = 0; i < str.Length; i++) {
+ switch (str[i]) {
+ case '\0' :
+ continue;
+ case '\b':
+ retval.Append("\\b");
+ continue;
+ case '\t':
+ retval.Append("\\t");
+ continue;
+ case '\n':
+ retval.Append("\\n");
+ continue;
+ case '\f':
+ retval.Append("\\f");
+ continue;
+ case '\r':
+ retval.Append("\\r");
+ continue;
+ case '\"':
+ retval.Append("\\\"");
+ continue;
+ case '\'':
+ retval.Append("\\\'");
+ continue;
+ case '\\':
+ retval.Append("\\\\");
+ continue;
+ default:
+ if ((ch = str[i]) < 0x20 || ch > 0x7e) {
+ string s = "0000" + System.Convert.ToString((int)ch, 16);
+ retval.Append("\\u" + s.Substring(s.Length - 4, s.Length - (s.Length - 4)));
+ } else {
+ retval.Append(ch);
+ }
+ continue;
+ }
+ }
+ return retval.ToString();
+ }
+
+ /*
+ * Returns a detailed message for the Exception when it is thrown by the
+ * token manager to indicate a lexical error.
+ * Parameters :
+ * EOFSeen : indicates if EOF caused the lexicl error
+ * curLexState : lexical state in which this error occured
+ * errorLine : line number when the error occured
+ * errorColumn : column number when the error occured
+ * errorAfter : prefix that was seen before this error occured
+ * curchar : the offending character
+ * Note: You can customize the lexical error message by modifying this method.
+ */
+ protected static string GetLexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, string errorAfter, char curChar) {
+ return("Lexical error at line " +
+ errorLine + ", column " +
+ errorColumn + ". Encountered: " +
+ (EOFSeen ? "<EOF> " : ("\"" + AddEscapes(curChar.ToString()) + "\"") + " (" + (int)curChar + "), ") +
+ "after : \"" + AddEscapes(errorAfter) + "\"");
+ }
+
+ /*
+ * You can also modify the body of this method to customize your error messages.
+ * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+ * of end-users concern, so you can return something like :
+ *
+ * "Internal Error : Please file a bug report .... "
+ *
+ * from this method for such cases in the release version of your parser.
+ */
+ public override string Message {
+ get { return base.Message; }
+ }
+
+ /*
+ * Constructors of various flavors follow.
+ */
+
+ public TokenMgrError() {
+ }
+
+ public TokenMgrError(string message, int reason) :
+ base(message) {
+ errorCode = reason;
+ }
+
+ public TokenMgrError(bool EOFSeen, int lexState, int errorLine, int errorColumn, string errorAfter, char curChar, int reason) :
+ this(GetLexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason) {
+ }
+}
diff --git a/src/main/csharp/Selector/UnaryExpression.cs b/src/main/csharp/Selector/UnaryExpression.cs
index 4ccbbc0..14d0262 100644
--- a/src/main/csharp/Selector/UnaryExpression.cs
+++ b/src/main/csharp/Selector/UnaryExpression.cs
@@ -1,66 +1,65 @@
-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.
- /// </summary>
- public abstract class UnaryExpression : IExpression
- {
- protected IExpression rightExpression;
- public IExpression Right
- {
- get { return rightExpression; }
- set { rightExpression = value; }
- }
-
- protected abstract string ExpressionSymbol
- {
- get;
- }
-
- public UnaryExpression(IExpression left)
- {
- this.rightExpression = left;
- }
-
- public abstract object Evaluate(MessageEvaluationContext message);
-
- public override string ToString()
- {
- return "(" + ExpressionSymbol + " " + rightExpression.ToString() + ")";
- }
-
- public static IExpression CreateNegate(IExpression left)
- {
- return new NegateExpression(left);
- }
-
- public static IBooleanExpression CreateNOT(IBooleanExpression left)
- {
- return new NOTExpression(left);
- }
-
- public static IBooleanExpression CreateBooleanCast(IExpression left)
- {
- return new BooleanCastExpression(left);
- }
- }
-}
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Selector
+{
+ /// <summary>
+ /// An expression which performs an operation on one expression value.
+ /// </summary>
+ public abstract class UnaryExpression : IExpression
+ {
+ protected IExpression rightExpression;
+ public IExpression Right
+ {
+ get { return rightExpression; }
+ set { rightExpression = value; }
+ }
+
+ protected abstract string ExpressionSymbol
+ {
+ get;
+ }
+
+ public UnaryExpression(IExpression left)
+ {
+ this.rightExpression = left;
+ }
+
+ public abstract object Evaluate(MessageEvaluationContext message);
+
+ public override string ToString()
+ {
+ return "(" + ExpressionSymbol + " " + rightExpression.ToString() + ")";
+ }
+
+ public static IExpression CreateNegate(IExpression left)
+ {
+ return new NegateExpression(left);
+ }
+
+ public static IBooleanExpression CreateNOT(IBooleanExpression left)
+ {
+ return new NOTExpression(left);
+ }
+
+ public static IBooleanExpression CreateBooleanCast(IExpression left)
+ {
+ return new BooleanCastExpression(left);
+ }
+ }
+}
diff --git a/src/main/csharp/Session.cs b/src/main/csharp/Session.cs
index b64c6ae..531dce2 100644
--- a/src/main/csharp/Session.cs
+++ b/src/main/csharp/Session.cs
@@ -70,6 +70,12 @@
public IMessageConsumer CreateConsumer(IDestination destination, string selector, bool noLocal)
{
+ // Bad consumer test
+ if(destination == null)
+ {
+ throw new NMSException("Consumer destination cannot be null");
+ }
+
MessageQueue queue = MessageConverter.ToMsmqDestination(destination);
return new MessageConsumer(this, acknowledgementMode, queue, selector);
}
@@ -178,6 +184,9 @@
throw new InvalidOperationException("You cannot perform a Commit() on a non-transacted session. Acknowlegement mode is: " + acknowledgementMode);
}
messageQueueTransaction.Commit();
+
+ // Start a new transaction
+ MessageQueueTransaction = new MessageQueueTransaction();
}
public void Rollback()
@@ -187,6 +196,9 @@
throw new InvalidOperationException("You cannot perform a Commit() on a non-transacted session. Acknowlegement mode is: " + acknowledgementMode);
}
messageQueueTransaction.Abort();
+
+ // Start a new transaction
+ MessageQueueTransaction = new MessageQueueTransaction();
}
public void Recover()
@@ -221,17 +233,17 @@
public MessageQueueTransaction MessageQueueTransaction
{
- get
+ get { return messageQueueTransaction; }
+ set
{
+ messageQueueTransaction = value;
+
if(null != messageQueueTransaction
&& messageQueueTransaction.Status != MessageQueueTransactionStatus.Pending)
{
messageQueueTransaction.Begin();
}
-
- return messageQueueTransaction;
}
- set { messageQueueTransaction = value; }
}
public IMessageConverter MessageConverter
diff --git a/src/test/csharp/AsyncConsumeTest.cs b/src/test/csharp/AsyncConsumeTest.cs
new file mode 100644
index 0000000..4d38b1a
--- /dev/null
+++ b/src/test/csharp/AsyncConsumeTest.cs
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+
+using System.Threading;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class AsyncConsumeTest : NMSTest
+ {
+ protected string RESPONSE_CLIENT_ID;
+ protected AutoResetEvent semaphore;
+ protected bool received;
+ protected IMessage receivedMsg;
+
+ public AsyncConsumeTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ semaphore = new AutoResetEvent(false);
+ received = false;
+ receivedMsg = null;
+
+ RESPONSE_CLIENT_ID = GetTestClientId() + ":RESPONSE";
+ }
+
+ //[TearDown]
+ public override void TearDown()
+ {
+ receivedMsg = null;
+ base.TearDown();
+ }
+
+ //[Test]
+ public virtual void TestAsynchronousConsume(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ // IBM WMQ doesn't support both synchronous and asynchronous operations
+ // in the same session. Needs 2 separate sessions.
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IDestination producerDestination = GetClearDestinationByNodeReference(producerSession, testDestRef))
+ using(IDestination consumerDestination = GetClearDestinationByNodeReference(consumerSession, testDestRef))
+ using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))
+ using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ consumer.Listener += new MessageListener(OnMessage);
+
+ IMessage request = producerSession.CreateMessage();
+ request.NMSCorrelationID = "AsyncConsume";
+ request.NMSType = "Test";
+ producer.Send(request);
+
+ WaitForMessageToArrive();
+ Assert.AreEqual(request.NMSCorrelationID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ }
+ }
+
+ //[Test]
+ public virtual void TestCreateConsumerAfterSend(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IDestination producerDestination = GetClearDestinationByNodeReference(producerSession, testDestRef))
+ using(IDestination consumerDestination = GetDestinationByNodeReference(consumerSession, testDestRef))
+ {
+ string correlationId = "AsyncConsumeAfterSend";
+
+ using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMessage request = producerSession.CreateMessage();
+ request.NMSCorrelationID = correlationId;
+ request.NMSType = "Test";
+ producer.Send(request);
+ }
+
+ using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))
+ {
+ consumer.Listener += new MessageListener(OnMessage);
+ WaitForMessageToArrive();
+ Assert.AreEqual(correlationId, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestCreateConsumerBeforeSendAddListenerAfterSend(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IDestination producerDestination = GetClearDestinationByNodeReference(producerSession, testDestRef))
+ using(IDestination consumerDestination = GetDestinationByNodeReference(consumerSession, testDestRef))
+ using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))
+ using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))
+ {
+ producer.DeliveryMode = deliveryMode;
+
+ IMessage request = producerSession.CreateMessage();
+ request.NMSCorrelationID = "AsyncConsumeAfterSendLateListener";
+ request.NMSType = "Test";
+ producer.Send(request);
+
+ // now lets add the listener
+ consumer.Listener += new MessageListener(OnMessage);
+ WaitForMessageToArrive();
+ Assert.AreEqual(request.NMSCorrelationID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ }
+ }
+
+ //[Test]
+ public virtual void TestAsynchronousTextMessageConsume(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IDestination producerDestination = GetClearDestinationByNodeReference(producerSession, testDestRef))
+ using(IDestination consumerDestination = GetDestinationByNodeReference(consumerSession, testDestRef))
+ using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))
+ using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))
+ {
+ consumer.Listener += new MessageListener(OnMessage);
+ producer.DeliveryMode = deliveryMode;
+
+ ITextMessage request = producerSession.CreateTextMessage("Hello, World!");
+ request.NMSCorrelationID = "AsyncConsumeTextMessage";
+ request.Properties["NMSXGroupID"] = "cheese";
+ request.Properties["myHeader"] = "James";
+
+ producer.Send(request);
+
+ WaitForMessageToArrive();
+ Assert.AreEqual(request.NMSCorrelationID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ Assert.AreEqual(request.Properties["NMSXGroupID"], receivedMsg.Properties["NMSXGroupID"], "Invalid NMSXGroupID.");
+ Assert.AreEqual(request.Properties["myHeader"], receivedMsg.Properties["myHeader"], "Invalid myHeader.");
+ Assert.AreEqual(request.Text, ((ITextMessage) receivedMsg).Text, "Invalid text body.");
+ }
+ }
+
+ //[Test]
+ public virtual void TestTemporaryQueueAsynchronousConsume(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ITemporaryQueue tempReplyDestination = session.CreateTemporaryQueue())
+ using(IDestination destination = GetClearDestinationByNodeReference(session, testDestRef))
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageConsumer tempConsumer = session.CreateConsumer(tempReplyDestination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ tempConsumer.Listener += new MessageListener(OnMessage);
+ consumer.Listener += new MessageListener(OnQueueMessage);
+
+ IMessage request = session.CreateMessage();
+ request.NMSCorrelationID = "TemqQueueAsyncConsume";
+ request.NMSType = "Test";
+ request.NMSReplyTo = tempReplyDestination;
+ producer.Send(request);
+
+ WaitForMessageToArrive();
+ Assert.AreEqual("TempQueueAsyncResponse", receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ }
+ }
+
+ protected void OnQueueMessage(IMessage message)
+ {
+ Assert.AreEqual("TemqQueueAsyncConsume", message.NMSCorrelationID, "Invalid correlation ID.");
+ using(IConnection connection = CreateConnectionAndStart(RESPONSE_CLIENT_ID))
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IMessageProducer producer = session.CreateProducer(message.NMSReplyTo))
+ {
+ producer.DeliveryMode = message.NMSDeliveryMode;
+
+ ITextMessage response = session.CreateTextMessage("Asynchronous Response Message Text");
+ response.NMSCorrelationID = "TempQueueAsyncResponse";
+ response.NMSType = message.NMSType;
+ producer.Send(response);
+ }
+ }
+
+ protected void OnMessage(IMessage message)
+ {
+ receivedMsg = message;
+ received = true;
+ semaphore.Set();
+ }
+
+ protected void WaitForMessageToArrive()
+ {
+ semaphore.WaitOne((int) receiveTimeout.TotalMilliseconds, true);
+ Assert.IsTrue(received, "Should have received a message by now!");
+ }
+ }
+}
diff --git a/src/test/csharp/BadConsumeTest.cs b/src/test/csharp/BadConsumeTest.cs
new file mode 100644
index 0000000..76f7cfc
--- /dev/null
+++ b/src/test/csharp/BadConsumeTest.cs
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+using System;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class BadConsumeTest : NMSTest
+ {
+ protected IConnection connection;
+ protected ISession session;
+
+ protected BadConsumeTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[SetUp]
+ public override void SetUp()
+ {
+ connection = CreateConnection(GetTestClientId());
+ connection.Start();
+ session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ }
+
+ //[TearDown]
+ public override void TearDown()
+ {
+ if(null != session)
+ {
+ session.Dispose();
+ session = null;
+ }
+
+ if(null != connection)
+ {
+ connection.Dispose();
+ connection = null;
+ }
+ }
+
+ //[Test]
+ //[ExpectedException(Handler="ExceptionValidationCheck")]
+ public virtual void TestBadConsumerException()
+ {
+ session.CreateConsumer(null);
+ }
+
+ public void ExceptionValidationCheck(Exception ex)
+ {
+ Assert.IsNotNull(ex as NMSException, "Invalid exception was thrown.");
+ }
+ }
+}
diff --git a/src/test/csharp/BytesMessageTest.cs b/src/test/csharp/BytesMessageTest.cs
new file mode 100644
index 0000000..8e6468f
--- /dev/null
+++ b/src/test/csharp/BytesMessageTest.cs
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class BytesMessageTest : NMSTest
+ {
+ protected byte[] msgContent = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ protected BytesMessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void SendReceiveBytesMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMessage request = session.CreateBytesMessage(msgContent);
+ producer.Send(request);
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertMessageIsReadOnly(message);
+ AssertBytesMessageEqual(request, message);
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void SendReceiveBytesMessageContent(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IBytesMessage request = session.CreateBytesMessage();
+
+ request.WriteBoolean(true);
+ request.WriteByte((byte) 1);
+ request.WriteBytes(new byte[1]);
+ request.WriteBytes(new byte[3], 0, 2);
+ request.WriteChar('a');
+ request.WriteDouble(1.5);
+ request.WriteSingle((float) 1.5);
+ request.WriteInt32(1);
+ request.WriteInt64(1);
+ request.WriteObject("stringobj");
+ request.WriteInt16((short) 1);
+ request.WriteString("utfstring");
+
+ producer.Send(request);
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertMessageIsReadOnly(message);
+ AssertBytesMessageEqual(request, message);
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ }
+ }
+ }
+ }
+
+ protected void AssertMessageIsReadOnly(IMessage message)
+ {
+ Type writeableExceptionType = typeof(MessageNotWriteableException);
+ IBytesMessage theMessage = message as IBytesMessage;
+ Assert.IsNotNull(theMessage);
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBoolean(true); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteByte((byte) 1); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBytes(new byte[1]); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBytes(new byte[3], 0, 2); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteChar('a'); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteDouble(1.5); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteSingle((float) 1.5); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt32(1); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt64(1); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteObject("stringobj"); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt16((short) 1); });
+ Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteString("utfstring"); });
+ }
+
+ /// <summary>
+ /// Assert that two messages are IBytesMessages and their contents are equal.
+ /// </summary>
+ /// <param name="expected"></param>
+ /// <param name="actual"></param>
+ protected void AssertBytesMessageEqual(IMessage expected, IMessage actual)
+ {
+ IBytesMessage expectedBytesMsg = expected as IBytesMessage;
+ expectedBytesMsg.Reset();
+ Assert.IsNotNull(expectedBytesMsg, "'expected' message not a bytes message");
+ IBytesMessage actualBytesMsg = actual as IBytesMessage;
+ Assert.IsNotNull(actualBytesMsg, "'actual' message not a bytes message");
+ Assert.AreEqual(expectedBytesMsg.Content, actualBytesMsg.Content, "Bytes message contents do not match.");
+ }
+ }
+}
diff --git a/src/test/csharp/Commands/BytesMessage.cs b/src/test/csharp/Commands/BytesMessage.cs
new file mode 100644
index 0000000..02fb23d
--- /dev/null
+++ b/src/test/csharp/Commands/BytesMessage.cs
@@ -0,0 +1,511 @@
+/*
+ * 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.
+ */
+
+using Apache.NMS;
+using Apache.NMS.Util;
+using System;
+using System.Collections;
+using System.IO;
+
+namespace Apache.NMS.Commands
+{
+ public class BytesMessage : Message, IBytesMessage
+ {
+ private EndianBinaryReader dataIn = null;
+ private EndianBinaryWriter dataOut = null;
+ private MemoryStream outputBuffer = null;
+ private int length = 0;
+
+ public override Object Clone()
+ {
+ StoreContent();
+ return base.Clone();
+ }
+
+ public override void ClearBody()
+ {
+ base.ClearBody();
+ this.outputBuffer = null;
+ this.dataIn = null;
+ this.dataOut = null;
+ this.length = 0;
+ }
+
+ public long BodyLength
+ {
+ get
+ {
+ InitializeReading();
+ return this.length;
+ }
+ }
+
+ public byte ReadByte()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadByte();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteByte( byte value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public bool ReadBoolean()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadBoolean();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteBoolean( bool value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public char ReadChar()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadChar();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteChar( char value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public short ReadInt16()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadInt16();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteInt16( short value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public int ReadInt32()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadInt32();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteInt32( int value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public long ReadInt64()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadInt64();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteInt64( long value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public float ReadSingle()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadSingle();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteSingle( float value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public double ReadDouble()
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.ReadDouble();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteDouble( double value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public int ReadBytes( byte[] value )
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.Read( value, 0, value.Length );
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public int ReadBytes( byte[] value, int length )
+ {
+ InitializeReading();
+ try
+ {
+ return dataIn.Read( value, 0, length );
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteBytes( byte[] value )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value, 0, value.Length );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteBytes( byte[] value, int offset, int length )
+ {
+ InitializeWriting();
+ try
+ {
+ dataOut.Write( value, offset, length );
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public string ReadString()
+ {
+ InitializeReading();
+ try
+ {
+ // JMS, CMS and NMS all encode the String using a 16 bit size header.
+ return dataIn.ReadString16();
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteString( string value )
+ {
+ InitializeWriting();
+ try
+ {
+ // JMS, CMS and NMS all encode the String using a 16 bit size header.
+ dataOut.WriteString16(value);
+ }
+ catch(Exception e)
+ {
+ throw NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteObject( System.Object value )
+ {
+ InitializeWriting();
+ if( value is System.Byte )
+ {
+ this.dataOut.Write( (byte) value );
+ }
+ else if( value is Char )
+ {
+ this.dataOut.Write( (char) value );
+ }
+ else if( value is Boolean )
+ {
+ this.dataOut.Write( (bool) value );
+ }
+ else if( value is Int16 )
+ {
+ this.dataOut.Write( (short) value );
+ }
+ else if( value is Int32 )
+ {
+ this.dataOut.Write( (int) value );
+ }
+ else if( value is Int64 )
+ {
+ this.dataOut.Write( (long) value );
+ }
+ else if( value is Single )
+ {
+ this.dataOut.Write( (float) value );
+ }
+ else if( value is Double )
+ {
+ this.dataOut.Write( (double) value );
+ }
+ else if( value is byte[] )
+ {
+ this.dataOut.Write( (byte[]) value );
+ }
+ else if( value is String )
+ {
+ this.dataOut.WriteString16( (string) value );
+ }
+ else
+ {
+ throw new MessageFormatException("Cannot write non-primitive type:" + value.GetType());
+ }
+ }
+
+ public new byte[] Content
+ {
+ get
+ {
+ byte[] buffer = null;
+ InitializeReading();
+ if(this.length != 0)
+ {
+ buffer = new byte[this.length];
+ this.dataIn.Read(buffer, 0, buffer.Length);
+ }
+ return buffer;
+ }
+
+ set
+ {
+ InitializeWriting();
+ this.dataOut.Write(value, 0, value.Length);
+ }
+ }
+
+ public void Reset()
+ {
+ StoreContent();
+ this.dataIn = null;
+ this.dataOut = null;
+ this.outputBuffer = null;
+ this.ReadOnlyBody = true;
+ }
+
+ private void InitializeReading()
+ {
+ FailIfWriteOnlyBody();
+ if(this.dataIn == null)
+ {
+ byte[] data = base.Content;
+
+ if(base.Content == null)
+ {
+ data = new byte[0];
+ }
+
+ Stream target = new MemoryStream(data, false);
+
+ this.length = data.Length;
+ this.dataIn = new EndianBinaryReader(target);
+ }
+ }
+
+ private void InitializeWriting()
+ {
+ FailIfReadOnlyBody();
+ if(this.dataOut == null)
+ {
+ this.outputBuffer = new MemoryStream();
+ this.dataOut = new EndianBinaryWriter(this.outputBuffer);
+ }
+ }
+
+ private void StoreContent()
+ {
+ if(this.dataOut != null)
+ {
+ this.dataOut.Close();
+ base.Content = outputBuffer.ToArray();
+
+ this.dataOut = null;
+ this.outputBuffer = null;
+ }
+ }
+
+ }
+}
+
diff --git a/src/test/csharp/Commands/Destination.cs b/src/test/csharp/Commands/Destination.cs
new file mode 100644
index 0000000..58c7749
--- /dev/null
+++ b/src/test/csharp/Commands/Destination.cs
@@ -0,0 +1,380 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Specialized;
+using Apache.NMS.Util;
+
+namespace Apache.NMS.Commands
+{
+ /// <summary>
+ /// Summary description for Destination.
+ /// </summary>
+ public abstract class Destination : IDestination, ICloneable
+ {
+ /// <summary>
+ /// Topic Destination object
+ /// </summary>
+ public const int TOPIC = 1;
+ /// <summary>
+ /// Temporary Topic Destination object
+ /// </summary>
+ public const int TEMPORARY_TOPIC = 2;
+ /// <summary>
+ /// Queue Destination object
+ /// </summary>
+ public const int QUEUE = 3;
+ /// <summary>
+ /// Temporary Queue Destination object
+ /// </summary>
+ public const int TEMPORARY_QUEUE = 4;
+
+ private const String TEMP_PREFIX = "{TD{";
+ private const String TEMP_POSTFIX = "}TD}";
+
+ private String physicalName = "";
+ private StringDictionary options = null;
+
+ private bool disposed = false;
+
+ /// <summary>
+ /// The Default Constructor
+ /// </summary>
+ protected Destination()
+ {
+ }
+
+ /// <summary>
+ /// Construct the Destination with a defined physical name;
+ /// </summary>
+ /// <param name="name"></param>
+ protected Destination(String name)
+ {
+ setPhysicalName(name);
+ }
+
+ ~Destination()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if(disposed)
+ {
+ return;
+ }
+
+ if(disposing)
+ {
+ try
+ {
+ OnDispose();
+ }
+ catch(Exception ex)
+ {
+ Tracer.ErrorFormat("Exception disposing Destination {0}: {1}", this.physicalName, ex.Message);
+ }
+ }
+
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Child classes can override this method to perform clean-up logic.
+ /// </summary>
+ protected virtual void OnDispose()
+ {
+ }
+
+ public bool IsTopic
+ {
+ get
+ {
+ int destinationType = GetDestinationType();
+ return TOPIC == destinationType
+ || TEMPORARY_TOPIC == destinationType;
+ }
+ }
+
+ public bool IsQueue
+ {
+ get
+ {
+ int destinationType = GetDestinationType();
+ return QUEUE == destinationType
+ || TEMPORARY_QUEUE == destinationType;
+ }
+ }
+
+ public bool IsTemporary
+ {
+ get
+ {
+ int destinationType = GetDestinationType();
+ return TEMPORARY_QUEUE == destinationType
+ || TEMPORARY_TOPIC == destinationType;
+ }
+ }
+
+ /// <summary>
+ /// Dictionary of name/value pairs representing option values specified
+ /// in the URI used to create this Destination. A null value is returned
+ /// if no options were specified.
+ /// </summary>
+ internal StringDictionary Options
+ {
+ get { return this.options; }
+ }
+
+ private void setPhysicalName(string name)
+ {
+ this.physicalName = name;
+
+ int p = name.IndexOf('?');
+ if(p >= 0)
+ {
+ String optstring = physicalName.Substring(p + 1);
+ this.physicalName = name.Substring(0, p);
+ options = URISupport.ParseQuery(optstring);
+ }
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <param name="destination"></param>
+ /// <returns></returns>
+ public static Destination Transform(IDestination destination)
+ {
+ Destination result = null;
+ if(destination != null)
+ {
+ if(destination is Destination)
+ {
+ result = (Destination) destination;
+ }
+ else
+ {
+ if(destination is ITemporaryQueue)
+ {
+ result = new TempQueue(((IQueue) destination).QueueName);
+ }
+ else if(destination is ITemporaryTopic)
+ {
+ result = new TempTopic(((ITopic) destination).TopicName);
+ }
+ else if(destination is IQueue)
+ {
+ result = new Queue(((IQueue) destination).QueueName);
+ }
+ else if(destination is ITopic)
+ {
+ result = new Topic(((ITopic) destination).TopicName);
+ }
+ }
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Create a temporary name from the clientId
+ /// </summary>
+ /// <param name="clientId"></param>
+ /// <returns></returns>
+ public static String CreateTemporaryName(String clientId)
+ {
+ return TEMP_PREFIX + clientId + TEMP_POSTFIX;
+ }
+
+ /// <summary>
+ /// From a temporary destination find the clientId of the Connection that created it
+ /// </summary>
+ /// <param name="destination"></param>
+ /// <returns>the clientId or null if not a temporary destination</returns>
+ public static String GetClientId(Destination destination)
+ {
+ String answer = null;
+ if(destination != null && destination.IsTemporary)
+ {
+ String name = destination.PhysicalName;
+ int start = name.IndexOf(TEMP_PREFIX);
+ if(start >= 0)
+ {
+ start += TEMP_PREFIX.Length;
+ int stop = name.LastIndexOf(TEMP_POSTFIX);
+ if(stop > start && stop < name.Length)
+ {
+ answer = name.Substring(start, stop);
+ }
+ }
+ }
+ return answer;
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <param name="o">object to compare</param>
+ /// <returns>1 if this is less than o else 0 if they are equal or -1 if this is less than o</returns>
+ public int CompareTo(Object o)
+ {
+ if(o is Destination)
+ {
+ return CompareTo((Destination) o);
+ }
+ return -1;
+ }
+
+ /// <summary>
+ /// Lets sort by name first then lets sort topics greater than queues
+ /// </summary>
+ /// <param name="that">another destination to compare against</param>
+ /// <returns>1 if this is less than o else 0 if they are equal or -1 if this is less than o</returns>
+ public int CompareTo(Destination that)
+ {
+ int answer = 0;
+ if(physicalName != that.physicalName)
+ {
+ if(physicalName == null)
+ {
+ return -1;
+ }
+ else if(that.physicalName == null)
+ {
+ return 1;
+ }
+ answer = physicalName.CompareTo(that.physicalName);
+ }
+
+ if(answer == 0)
+ {
+ if(IsTopic)
+ {
+ if(that.IsQueue)
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ if(that.IsTopic)
+ {
+ return -1;
+ }
+ }
+ }
+ return answer;
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <returns>Returns the Destination type</returns>
+ public abstract int GetDestinationType();
+
+ public String PhysicalName
+ {
+ get { return this.physicalName; }
+ set
+ {
+ this.physicalName = value;
+ }
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <returns>string representation of this instance</returns>
+ public override String ToString()
+ {
+ switch(DestinationType)
+ {
+ case DestinationType.Topic:
+ return "topic://" + PhysicalName;
+
+ case DestinationType.TemporaryTopic:
+ return "temp-topic://" + PhysicalName;
+
+ case DestinationType.TemporaryQueue:
+ return "temp-queue://" + PhysicalName;
+
+ default:
+ return "queue://" + PhysicalName;
+ }
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <returns>hashCode for this instance</returns>
+ public override int GetHashCode()
+ {
+ int answer = 37;
+
+ if(this.physicalName != null)
+ {
+ answer = physicalName.GetHashCode();
+ }
+ if(IsTopic)
+ {
+ answer ^= 0xfabfab;
+ }
+ return answer;
+ }
+
+ /// <summary>
+ /// if the object passed in is equivalent, return true
+ /// </summary>
+ /// <param name="obj">the object to compare</param>
+ /// <returns>true if this instance and obj are equivalent</returns>
+ public override bool Equals(Object obj)
+ {
+ bool result = this == obj;
+ if(!result && obj != null && obj is Destination)
+ {
+ Destination other = (Destination) obj;
+ result = this.GetDestinationType() == other.GetDestinationType()
+ && this.physicalName.Equals(other.physicalName);
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Factory method to create a child destination if this destination is a composite
+ /// </summary>
+ /// <param name="name"></param>
+ /// <returns>the created Destination</returns>
+ public abstract Destination CreateDestination(String name);
+
+ public abstract DestinationType DestinationType
+ {
+ get;
+ }
+
+ public virtual Object Clone()
+ {
+ // Since we are the lowest level base class, do a
+ // shallow copy which will include the derived classes.
+ // From here we would do deep cloning of other objects
+ // if we had any.
+ return this.MemberwiseClone();
+ }
+ }
+}
+
diff --git a/src/test/csharp/Commands/MapMessage.cs b/src/test/csharp/Commands/MapMessage.cs
new file mode 100644
index 0000000..34de7aa
--- /dev/null
+++ b/src/test/csharp/Commands/MapMessage.cs
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.IO;
+using Apache.NMS;
+using Apache.NMS.Util;
+
+namespace Apache.NMS.Commands
+{
+ public class MapMessage : Message, IMapMessage
+ {
+ private PrimitiveMap body;
+ private PrimitiveMapInterceptor typeConverter;
+
+ public MapMessage() : base()
+ {
+ }
+
+ public MapMessage(PrimitiveMap body) : base()
+ {
+ this.body = body;
+ this.typeConverter = new PrimitiveMapInterceptor(this, this.body);
+ }
+
+ public override void ClearBody()
+ {
+ this.body = null;
+ this.typeConverter = null;
+ base.ClearBody();
+ }
+
+ public override bool ReadOnlyBody
+ {
+ get { return base.ReadOnlyBody; }
+
+ set
+ {
+ if(this.typeConverter != null)
+ {
+ this.typeConverter.ReadOnly = true;
+ }
+
+ base.ReadOnlyBody = value;
+ }
+ }
+
+
+ public IPrimitiveMap Body
+ {
+ get
+ {
+ if(this.body == null)
+ {
+ this.body = new PrimitiveMap();
+ this.typeConverter = new PrimitiveMapInterceptor(this, this.body);
+ }
+
+ return this.typeConverter;
+ }
+
+ set
+ {
+ this.body = value as PrimitiveMap;
+ if(value != null)
+ {
+ this.typeConverter = new PrimitiveMapInterceptor(this, value);
+ }
+ else
+ {
+ this.typeConverter = null;
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/Commands/Message.cs b/src/test/csharp/Commands/Message.cs
new file mode 100644
index 0000000..dcb38d6
--- /dev/null
+++ b/src/test/csharp/Commands/Message.cs
@@ -0,0 +1,329 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections;
+
+using Apache.NMS.Util;
+
+namespace Apache.NMS.Commands
+{
+ public class Message : IMessage, ICloneable
+ {
+ private IDestination destination;
+ private string transactionId;
+ private string messageId;
+ private string groupID;
+ private int groupSequence;
+ private string correlationId;
+ private bool persistent;
+ private long expiration;
+ private byte priority;
+ private IDestination replyTo;
+ private long timestamp;
+ private string type;
+ private bool redelivered;
+ private byte[] content;
+ private bool readOnlyMsgProperties;
+ private bool readOnlyMsgBody;
+
+ private MessagePropertyIntercepter propertyHelper;
+ private PrimitiveMap properties;
+
+ ///
+ /// <summery>
+ /// Clone this object and return a new instance that the caller now owns.
+ /// </summery>
+ ///
+ public virtual Object Clone()
+ {
+ // Since we are the lowest level base class, do a
+ // shallow copy which will include the derived classes.
+ // From here we would do deep cloning of other objects
+ // if we had any.
+ Message o = (Message) this.MemberwiseClone();
+
+ if(this.messageId != null)
+ {
+ o.NMSMessageId = (string) this.messageId.Clone();
+ }
+
+ return o;
+ }
+
+ ///
+ /// <summery>
+ /// Returns a string containing the information for this DataStructure
+ /// such as its type and value of its elements.
+ /// </summery>
+ ///
+ public override string ToString()
+ {
+ return GetType().Name + "[" +
+ "Destination=" + destination + ", " +
+ "TransactionId=" + transactionId + ", " +
+ "MessageId=" + messageId + ", " +
+ "GroupID=" + groupID + ", " +
+ "GroupSequence=" + groupSequence + ", " +
+ "CorrelationId=" + correlationId + ", " +
+ "Expiration=" + expiration + ", " +
+ "Priority=" + priority + ", " +
+ "ReplyTo=" + replyTo + ", " +
+ "Timestamp=" + timestamp + ", " +
+ "Type=" + type + ", " +
+ "Redelivered=" + redelivered +
+ "]";
+ }
+
+ public void Acknowledge()
+ {
+ }
+
+ public virtual void ClearBody()
+ {
+ this.content = null;
+ }
+
+ public virtual void ClearProperties()
+ {
+ this.properties.Clear();
+ }
+
+ protected void FailIfReadOnlyBody()
+ {
+ if(ReadOnlyBody == true)
+ {
+ throw new MessageNotWriteableException("Message is in Read-Only mode.");
+ }
+ }
+
+ protected void FailIfWriteOnlyBody()
+ {
+ if(ReadOnlyBody == false)
+ {
+ throw new MessageNotReadableException("Message is in Write-Only mode.");
+ }
+ }
+
+ #region Properties
+
+ public string TransactionId
+ {
+ get { return this.transactionId; }
+ set { this.transactionId = value; }
+ }
+
+ public byte[] Content
+ {
+ get { return content; }
+ set { this.content = value; }
+ }
+
+ public virtual bool ReadOnlyProperties
+ {
+ get { return this.readOnlyMsgProperties; }
+ set { this.readOnlyMsgProperties = value; }
+ }
+
+ public virtual bool ReadOnlyBody
+ {
+ get { return this.readOnlyMsgBody; }
+ set { this.readOnlyMsgBody = value; }
+ }
+
+ public IPrimitiveMap Properties
+ {
+ get
+ {
+ if(null == properties)
+ {
+ properties = new PrimitiveMap();
+ propertyHelper = new MessagePropertyIntercepter(this, properties, this.ReadOnlyProperties);
+ propertyHelper.AllowByteArrays = false;
+ }
+
+ return propertyHelper;
+ }
+ }
+
+ /// <summary>
+ /// The correlation ID used to correlate messages with conversations or long running business processes
+ /// </summary>
+ public string NMSCorrelationID
+ {
+ get { return correlationId; }
+ set { correlationId = value; }
+ }
+
+ /// <summary>
+ /// The destination of the message
+ /// </summary>
+ public IDestination NMSDestination
+ {
+ get { return destination; }
+ set { this.destination = Destination.Transform(value); }
+ }
+
+ private TimeSpan timeToLive = TimeSpan.FromMilliseconds(0);
+ /// <summary>
+ /// The time in milliseconds that this message should expire in
+ /// </summary>
+ public TimeSpan NMSTimeToLive
+ {
+ get { return timeToLive; }
+
+ set
+ {
+ timeToLive = value;
+ if(timeToLive.TotalMilliseconds > 0)
+ {
+ long timeStamp = timestamp;
+
+ if(timeStamp == 0)
+ {
+ timeStamp = DateUtils.ToJavaTimeUtc(DateTime.UtcNow);
+ }
+
+ expiration = timeStamp + (long) timeToLive.TotalMilliseconds;
+ }
+ else
+ {
+ expiration = 0;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The timestamp the broker added to the message
+ /// </summary>
+ public DateTime NMSTimestamp
+ {
+ get { return DateUtils.ToDateTime(timestamp); }
+ set
+ {
+ timestamp = DateUtils.ToJavaTimeUtc(value);
+ if(timeToLive.TotalMilliseconds > 0)
+ {
+ expiration = timestamp + (long) timeToLive.TotalMilliseconds;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The message ID which is set by the provider
+ /// </summary>
+ public string NMSMessageId
+ {
+ get { return this.messageId; }
+ set { this.messageId = value; }
+ }
+
+ /// <summary>
+ /// Whether or not this message is persistent
+ /// </summary>
+ public MsgDeliveryMode NMSDeliveryMode
+ {
+ get { return (persistent ? MsgDeliveryMode.Persistent : MsgDeliveryMode.NonPersistent); }
+ set { persistent = (MsgDeliveryMode.Persistent == value); }
+ }
+
+ /// <summary>
+ /// The Priority on this message
+ /// </summary>
+ public MsgPriority NMSPriority
+ {
+ get { return (MsgPriority) priority; }
+ set { priority = (byte) value; }
+ }
+
+ /// <summary>
+ /// Returns true if this message has been redelivered to this or another consumer before being acknowledged successfully.
+ /// </summary>
+ public bool NMSRedelivered
+ {
+ get { return this.redelivered; }
+ set { this.redelivered = value; }
+ }
+
+ /// <summary>
+ /// The destination that the consumer of this message should send replies to
+ /// </summary>
+ public IDestination NMSReplyTo
+ {
+ get { return replyTo; }
+ set { replyTo = Destination.Transform(value); }
+ }
+
+ /// <summary>
+ /// The type name of this message
+ /// </summary>
+ public string NMSType
+ {
+ get { return type; }
+ set { type = value; }
+ }
+
+ #endregion
+
+ #region NMS Extension headers
+
+ /// <summary>
+ /// Returns the number of times this message has been redelivered to other consumers without being acknowledged successfully.
+ /// </summary>
+ public int NMSXDeliveryCount
+ {
+ get { return 0; }
+ }
+
+ /// <summary>
+ /// The Message Group ID used to group messages together to the same consumer for the same group ID value
+ /// </summary>
+ public string NMSXGroupID
+ {
+ get { return groupID; }
+ set { groupID = value; }
+ }
+ /// <summary>
+ /// The Message Group Sequence counter to indicate the position in a group
+ /// </summary>
+ public int NMSXGroupSeq
+ {
+ get { return groupSequence; }
+ set { groupSequence = value; }
+ }
+
+ /// <summary>
+ /// Returns the ID of the producers transaction
+ /// </summary>
+ public string NMSXProducerTXID
+ {
+ get
+ {
+ if(null != transactionId)
+ {
+ return transactionId;
+ }
+
+ return String.Empty;
+ }
+ }
+
+ #endregion
+
+ };
+}
+
diff --git a/src/test/csharp/Commands/ObjectMessage.cs b/src/test/csharp/Commands/ObjectMessage.cs
new file mode 100644
index 0000000..4db9de6
--- /dev/null
+++ b/src/test/csharp/Commands/ObjectMessage.cs
@@ -0,0 +1,44 @@
+/*
+* 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.
+*/
+
+using System;
+using System.Collections;
+using System.IO;
+
+using Apache.NMS;
+
+namespace Apache.NMS.Commands
+{
+ public class ObjectMessage : Message, IObjectMessage
+ {
+ private object body;
+
+ public override string ToString() {
+ return GetType().Name + "["
+ + " ]";
+ }
+
+ // Properties
+
+ public object Body
+ {
+ get { return body; }
+ set { body = value; }
+ }
+
+ }
+}
diff --git a/src/test/csharp/Commands/Queue.cs b/src/test/csharp/Commands/Queue.cs
new file mode 100644
index 0000000..342156f
--- /dev/null
+++ b/src/test/csharp/Commands/Queue.cs
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Commands
+{
+ /// <summary>
+ /// Summary description for Queue.
+ /// </summary>
+ public class Queue : Destination, IQueue
+ {
+ public Queue()
+ : base()
+ {
+ }
+
+ public Queue(String name)
+ : base(name)
+ {
+ }
+
+ override public DestinationType DestinationType
+ {
+ get
+ {
+ return DestinationType.Queue;
+ }
+ }
+
+ public String QueueName
+ {
+ get { return PhysicalName; }
+ }
+
+ public override int GetDestinationType()
+ {
+ return QUEUE;
+ }
+
+ public override Destination CreateDestination(String name)
+ {
+ return new Queue(name);
+ }
+
+ public override Object Clone()
+ {
+ // Since we are a derived class use the base's Clone()
+ // to perform the shallow copy. Since it is shallow it
+ // will include our derived class. Since we are derived,
+ // this method is an override.
+ Queue o = (Queue) base.Clone();
+
+ // Now do the deep work required
+ // If any new variables are added then this routine will
+ // likely need updating
+
+ return o;
+ }
+ }
+}
+
diff --git a/src/test/csharp/Commands/StreamMessage.cs b/src/test/csharp/Commands/StreamMessage.cs
new file mode 100644
index 0000000..86e4e28
--- /dev/null
+++ b/src/test/csharp/Commands/StreamMessage.cs
@@ -0,0 +1,901 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.IO;
+using System.Collections;
+
+using Apache.NMS;
+using Apache.NMS.Util;
+
+namespace Apache.NMS.Commands
+{
+ public class StreamMessage : Message, IStreamMessage
+ {
+ private EndianBinaryReader dataIn = null;
+ private EndianBinaryWriter dataOut = null;
+ private MemoryStream byteBuffer = null;
+ private int bytesRemaining = -1;
+
+ public bool ReadBoolean()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.BOOLEAN_TYPE)
+ {
+ return this.dataIn.ReadBoolean();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Boolean.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a bool");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Boolean type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public byte ReadByte()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Byte.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a byte");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Byte type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public char ReadChar()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.CHAR_TYPE)
+ {
+ return this.dataIn.ReadChar();
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a char");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Char type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public short ReadInt16()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.SHORT_TYPE)
+ {
+ return this.dataIn.ReadInt16();
+ }
+ else if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Int16.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a short");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Int16 type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public int ReadInt32()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.INTEGER_TYPE)
+ {
+ return this.dataIn.ReadInt32();
+ }
+ else if(type == PrimitiveMap.SHORT_TYPE)
+ {
+ return this.dataIn.ReadInt16();
+ }
+ else if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Int32.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a int");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Int32 type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public long ReadInt64()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.LONG_TYPE)
+ {
+ return this.dataIn.ReadInt64();
+ }
+ else if(type == PrimitiveMap.INTEGER_TYPE)
+ {
+ return this.dataIn.ReadInt32();
+ }
+ else if(type == PrimitiveMap.SHORT_TYPE)
+ {
+ return this.dataIn.ReadInt16();
+ }
+ else if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Int64.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a long");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Int64 type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public float ReadSingle()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.FLOAT_TYPE)
+ {
+ return this.dataIn.ReadSingle();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Single.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a float");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Single type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public double ReadDouble()
+ {
+ InitializeReading();
+
+ try
+ {
+ long startingPos = this.byteBuffer.Position;
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.DOUBLE_TYPE)
+ {
+ return this.dataIn.ReadDouble();
+ }
+ else if(type == PrimitiveMap.FLOAT_TYPE)
+ {
+ return this.dataIn.ReadSingle();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return Single.Parse(this.dataIn.ReadString16());
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new NMSException("Cannot convert Null type to a double");
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a Double type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public string ReadString()
+ {
+ InitializeReading();
+
+ long startingPos = this.byteBuffer.Position;
+
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.BIG_STRING_TYPE)
+ {
+ return this.dataIn.ReadString32();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return this.dataIn.ReadString16();
+ }
+ else if(type == PrimitiveMap.LONG_TYPE)
+ {
+ return this.dataIn.ReadInt64().ToString();
+ }
+ else if(type == PrimitiveMap.INTEGER_TYPE)
+ {
+ return this.dataIn.ReadInt32().ToString();
+ }
+ else if(type == PrimitiveMap.SHORT_TYPE)
+ {
+ return this.dataIn.ReadInt16().ToString();
+ }
+ else if(type == PrimitiveMap.FLOAT_TYPE)
+ {
+ return this.dataIn.ReadSingle().ToString();
+ }
+ else if(type == PrimitiveMap.DOUBLE_TYPE)
+ {
+ return this.dataIn.ReadDouble().ToString();
+ }
+ else if(type == PrimitiveMap.CHAR_TYPE)
+ {
+ return this.dataIn.ReadChar().ToString();
+ }
+ else if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte().ToString();
+ }
+ else if(type == PrimitiveMap.BOOLEAN_TYPE)
+ {
+ return this.dataIn.ReadBoolean().ToString();
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ return null;
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a known type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public int ReadBytes(byte[] value)
+ {
+ InitializeReading();
+
+ if(value == null)
+ {
+ throw new NullReferenceException("Passed Byte Array is null");
+ }
+
+ try
+ {
+ if(this.bytesRemaining == -1)
+ {
+ long startingPos = this.byteBuffer.Position;
+ byte type = this.dataIn.ReadByte();
+
+ if(type != PrimitiveMap.BYTE_ARRAY_TYPE)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Not a byte array");
+ }
+
+ this.bytesRemaining = this.dataIn.ReadInt32();
+ }
+ else if(this.bytesRemaining == 0)
+ {
+ this.bytesRemaining = -1;
+ return -1;
+ }
+
+ if(value.Length <= this.bytesRemaining)
+ {
+ // small buffer
+ this.bytesRemaining -= value.Length;
+ this.dataIn.Read(value, 0, value.Length);
+ return value.Length;
+ }
+ else
+ {
+ // big buffer
+ int rc = this.dataIn.Read(value, 0, this.bytesRemaining);
+ this.bytesRemaining = 0;
+ return rc;
+ }
+ }
+ catch(EndOfStreamException ex)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(ex);
+ }
+ catch(IOException ex)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(ex);
+ }
+ }
+
+ public Object ReadObject()
+ {
+ InitializeReading();
+
+ long startingPos = this.byteBuffer.Position;
+
+ try
+ {
+ int type = this.dataIn.ReadByte();
+
+ if(type == PrimitiveMap.BIG_STRING_TYPE)
+ {
+ return this.dataIn.ReadString32();
+ }
+ else if(type == PrimitiveMap.STRING_TYPE)
+ {
+ return this.dataIn.ReadString16();
+ }
+ else if(type == PrimitiveMap.LONG_TYPE)
+ {
+ return this.dataIn.ReadInt64();
+ }
+ else if(type == PrimitiveMap.INTEGER_TYPE)
+ {
+ return this.dataIn.ReadInt32();
+ }
+ else if(type == PrimitiveMap.SHORT_TYPE)
+ {
+ return this.dataIn.ReadInt16();
+ }
+ else if(type == PrimitiveMap.FLOAT_TYPE)
+ {
+ return this.dataIn.ReadSingle();
+ }
+ else if(type == PrimitiveMap.DOUBLE_TYPE)
+ {
+ return this.dataIn.ReadDouble();
+ }
+ else if(type == PrimitiveMap.CHAR_TYPE)
+ {
+ return this.dataIn.ReadChar();
+ }
+ else if(type == PrimitiveMap.BYTE_TYPE)
+ {
+ return this.dataIn.ReadByte();
+ }
+ else if(type == PrimitiveMap.BOOLEAN_TYPE)
+ {
+ return this.dataIn.ReadBoolean();
+ }
+ else if(type == PrimitiveMap.BYTE_ARRAY_TYPE)
+ {
+ int length = this.dataIn.ReadInt32();
+ byte[] data = new byte[length];
+ this.dataIn.Read(data, 0, length);
+ return data;
+ }
+ else if(type == PrimitiveMap.NULL)
+ {
+ return null;
+ }
+ else
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw new MessageFormatException("Value is not a known type.");
+ }
+ }
+ catch(FormatException e)
+ {
+ this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ catch(EndOfStreamException e)
+ {
+ throw NMSExceptionSupport.CreateMessageEOFException(e);
+ }
+ catch(IOException e)
+ {
+ throw NMSExceptionSupport.CreateMessageFormatException(e);
+ }
+ }
+
+ public void WriteBoolean(bool value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.BOOLEAN_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteByte(byte value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.BYTE_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteBytes(byte[] value)
+ {
+ InitializeWriting();
+ this.WriteBytes(value, 0, value.Length);
+ }
+
+ public void WriteBytes(byte[] value, int offset, int length)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.BYTE_ARRAY_TYPE);
+ this.dataOut.Write((int) length);
+ this.dataOut.Write(value, offset, length);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteChar(char value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.CHAR_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteInt16(short value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.SHORT_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteInt32(int value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.INTEGER_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteInt64(long value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.LONG_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteSingle(float value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.FLOAT_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteDouble(double value)
+ {
+ InitializeWriting();
+ try
+ {
+ this.dataOut.Write(PrimitiveMap.DOUBLE_TYPE);
+ this.dataOut.Write(value);
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteString(string value)
+ {
+ InitializeWriting();
+ try
+ {
+ if( value.Length > 8192 )
+ {
+ this.dataOut.Write(PrimitiveMap.BIG_STRING_TYPE);
+ this.dataOut.WriteString32(value);
+ }
+ else
+ {
+ this.dataOut.Write(PrimitiveMap.STRING_TYPE);
+ this.dataOut.WriteString16(value);
+ }
+ }
+ catch(IOException e)
+ {
+ NMSExceptionSupport.Create(e);
+ }
+ }
+
+ public void WriteObject(Object value)
+ {
+ InitializeWriting();
+ if( value is System.Byte )
+ {
+ this.WriteByte( (byte) value );
+ }
+ else if( value is Char )
+ {
+ this.WriteChar( (char) value );
+ }
+ else if( value is Boolean )
+ {
+ this.WriteBoolean( (bool) value );
+ }
+ else if( value is Int16 )
+ {
+ this.WriteInt16( (short) value );
+ }
+ else if( value is Int32 )
+ {
+ this.WriteInt32( (int) value );
+ }
+ else if( value is Int64 )
+ {
+ this.WriteInt64( (long) value );
+ }
+ else if( value is Single )
+ {
+ this.WriteSingle( (float) value );
+ }
+ else if( value is Double )
+ {
+ this.WriteDouble( (double) value );
+ }
+ else if( value is byte[] )
+ {
+ this.WriteBytes( (byte[]) value );
+ }
+ else if( value is String )
+ {
+ this.WriteString( (string) value );
+ }
+ else
+ {
+ throw new MessageFormatException("Cannot write non-primitive type:" + value.GetType());
+ }
+ }
+
+ public override Object Clone()
+ {
+ StoreContent();
+ return base.Clone();
+ }
+
+ public override void ClearBody()
+ {
+ base.ClearBody();
+ this.byteBuffer = null;
+ this.dataIn = null;
+ this.dataOut = null;
+ this.bytesRemaining = -1;
+ }
+
+ public void Reset()
+ {
+ StoreContent();
+ this.dataIn = null;
+ this.dataOut = null;
+ this.byteBuffer = null;
+ this.bytesRemaining = -1;
+ this.ReadOnlyBody = true;
+ }
+
+ private void InitializeReading()
+ {
+ FailIfWriteOnlyBody();
+ if(this.dataIn == null)
+ {
+ this.byteBuffer = new MemoryStream(this.Content, false);
+ this.dataIn = new EndianBinaryReader(this.byteBuffer);
+ }
+ }
+
+ private void InitializeWriting()
+ {
+ FailIfReadOnlyBody();
+ if(this.dataOut == null)
+ {
+ this.byteBuffer = new MemoryStream();
+ this.dataOut = new EndianBinaryWriter(this.byteBuffer);
+ }
+ }
+
+ private void StoreContent()
+ {
+ if( dataOut != null)
+ {
+ dataOut.Close();
+
+ this.Content = byteBuffer.ToArray();
+ this.dataOut = null;
+ this.byteBuffer = null;
+ }
+ }
+
+ }
+}
+
diff --git a/src/test/csharp/Commands/TempDestination.cs b/src/test/csharp/Commands/TempDestination.cs
new file mode 100644
index 0000000..1e085c9
--- /dev/null
+++ b/src/test/csharp/Commands/TempDestination.cs
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+using System;
+
+namespace Apache.NMS.Commands
+{
+ public abstract class TempDestination : Destination
+ {
+ /// <summary>
+ /// Method CreateDestination
+ /// </summary>
+ /// <returns>An Destination</returns>
+ /// <param name="name">A String</param>
+ public override Destination CreateDestination(String name)
+ {
+ return null;
+ }
+
+ abstract override public DestinationType DestinationType
+ {
+ get;
+ }
+
+ public TempDestination()
+ : base()
+ {
+ }
+
+ public TempDestination(String name)
+ : base(name)
+ {
+ }
+
+ public override Object Clone()
+ {
+ // Since we are a derived class use the base's Clone()
+ // to perform the shallow copy. Since it is shallow it
+ // will include our derived class. Since we are derived,
+ // this method is an override.
+ TempDestination o = (TempDestination) base.Clone();
+
+ // Now do the deep work required
+ // If any new variables are added then this routine will
+ // likely need updating
+
+ return o;
+ }
+
+ public void Delete()
+ {
+ throw new NotSupportedException("Stomp Cannot Delete Temporary Destinations");
+ }
+ }
+}
+
diff --git a/src/test/csharp/Commands/TempQueue.cs b/src/test/csharp/Commands/TempQueue.cs
new file mode 100644
index 0000000..b8ee277
--- /dev/null
+++ b/src/test/csharp/Commands/TempQueue.cs
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Commands
+{
+ /// <summary>
+ /// A Temporary Queue
+ /// </summary>
+ public class TempQueue : TempDestination, ITemporaryQueue
+ {
+ public TempQueue()
+ : base()
+ {
+ }
+
+ public TempQueue(String name)
+ : base(name)
+ {
+ }
+
+ override public DestinationType DestinationType
+ {
+ get
+ {
+ return DestinationType.TemporaryQueue;
+ }
+ }
+
+ public String QueueName
+ {
+ get { return PhysicalName; }
+ }
+
+ public String GetQueueName()
+ {
+ return PhysicalName;
+ }
+
+ public override int GetDestinationType()
+ {
+ return TEMPORARY_QUEUE;
+ }
+
+ public override Destination CreateDestination(String name)
+ {
+ return new TempQueue(name);
+ }
+
+ public override Object Clone()
+ {
+ // Since we are a derived class use the base's Clone()
+ // to perform the shallow copy. Since it is shallow it
+ // will include our derived class. Since we are derived,
+ // this method is an override.
+ TempQueue o = (TempQueue) base.Clone();
+
+ // Now do the deep work required
+ // If any new variables are added then this routine will
+ // likely need updating
+
+ return o;
+ }
+
+ }
+}
+
diff --git a/src/test/csharp/Commands/TempTopic.cs b/src/test/csharp/Commands/TempTopic.cs
new file mode 100644
index 0000000..2ba499e
--- /dev/null
+++ b/src/test/csharp/Commands/TempTopic.cs
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Commands
+{
+
+ /// <summary>
+ /// A Temporary Topic
+ /// </summary>
+ public class TempTopic : TempDestination, ITemporaryTopic
+ {
+ public TempTopic() : base()
+ {
+ }
+
+ public TempTopic(String name) : base(name)
+ {
+ }
+
+ override public DestinationType DestinationType
+ {
+ get { return DestinationType.TemporaryTopic; }
+ }
+
+ public String TopicName
+ {
+ get { return PhysicalName; }
+ }
+
+ public String GetTopicName()
+ {
+ return PhysicalName;
+ }
+
+ public override int GetDestinationType()
+ {
+ return TEMPORARY_TOPIC;
+ }
+
+ public override Destination CreateDestination(String name)
+ {
+ return new TempTopic(name);
+ }
+
+ public override Object Clone()
+ {
+ // Since we are a derived class use the base's Clone()
+ // to perform the shallow copy. Since it is shallow it
+ // will include our derived class. Since we are derived,
+ // this method is an override.
+ TempTopic o = (TempTopic) base.Clone();
+
+ // Now do the deep work required
+ // If any new variables are added then this routine will
+ // likely need updating
+
+ return o;
+ }
+
+ }
+}
+
diff --git a/src/test/csharp/Commands/TextMessage.cs b/src/test/csharp/Commands/TextMessage.cs
new file mode 100644
index 0000000..b36f4ba
--- /dev/null
+++ b/src/test/csharp/Commands/TextMessage.cs
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.IO;
+
+using Apache.NMS;
+using Apache.NMS.Util;
+
+namespace Apache.NMS.Commands
+{
+ public class TextMessage : Message, ITextMessage
+ {
+ private String text = null;
+
+ public TextMessage()
+ {
+ }
+
+ public TextMessage(String text)
+ {
+ this.Text = text;
+ }
+
+ public override string ToString()
+ {
+ string text = this.Text;
+
+ if(text != null && text.Length > 63)
+ {
+ text = text.Substring(0, 45) + "..." + text.Substring(text.Length - 12);
+ }
+ return base.ToString() + " Text = " + (text ?? "null");
+ }
+
+ public override void ClearBody()
+ {
+ base.ClearBody();
+ this.text = null;
+ }
+
+ // Properties
+
+ public string Text
+ {
+ get { return this.text; }
+ set
+ {
+ FailIfReadOnlyBody();
+ this.text = value;
+ this.Content = null;
+ }
+ }
+ }
+}
+
diff --git a/src/test/csharp/Commands/Topic.cs b/src/test/csharp/Commands/Topic.cs
new file mode 100644
index 0000000..bbab902
--- /dev/null
+++ b/src/test/csharp/Commands/Topic.cs
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+using System;
+
+namespace Apache.NMS.Commands
+{
+
+ /// <summary>
+ /// Summary description for Topic.
+ /// </summary>
+ public class Topic : Destination, ITopic
+ {
+ public Topic() : base()
+ {
+ }
+
+ public Topic(String name) : base(name)
+ {
+ }
+
+ override public DestinationType DestinationType
+ {
+ get
+ {
+ return DestinationType.Topic;
+ }
+ }
+
+ public String TopicName
+ {
+ get { return PhysicalName; }
+ }
+
+ public override int GetDestinationType()
+ {
+ return TOPIC;
+ }
+
+ public override Destination CreateDestination(String name)
+ {
+ return new Topic(name);
+ }
+
+ public override Object Clone()
+ {
+ // Since we are a derived class use the base's Clone()
+ // to perform the shallow copy. Since it is shallow it
+ // will include our derived class. Since we are derived,
+ // this method is an override.
+ Topic o = (Topic) base.Clone();
+
+ // Now do the deep work required
+ // If any new variables are added then this routine will
+ // likely need updating
+
+ return o;
+ }
+ }
+}
+
diff --git a/src/test/csharp/ConnectionTest.cs b/src/test/csharp/ConnectionTest.cs
new file mode 100644
index 0000000..0718f83
--- /dev/null
+++ b/src/test/csharp/ConnectionTest.cs
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+using System;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class ConnectionTest : NMSTest
+ {
+ IConnection startedConnection = null;
+ IConnection stoppedConnection = null;
+
+ protected ConnectionTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+
+ startedConnection = CreateConnection(null);
+ startedConnection.Start();
+ stoppedConnection = CreateConnection(null);
+ }
+
+ //[TearDown]
+ public override void TearDown()
+ {
+ startedConnection.Close();
+ stoppedConnection.Close();
+
+ base.TearDown();
+ }
+
+ /// <summary>
+ /// Verify that it is possible to create multiple connections to the broker.
+ /// There was a bug in the connection factory which set the clientId member which made
+ /// it impossible to create an additional connection.
+ /// </summary>
+ //[Test]
+ public virtual void TestTwoConnections()
+ {
+ using(IConnection connection1 = CreateConnection(null))
+ {
+ connection1.Start();
+ using(IConnection connection2 = CreateConnection(null))
+ {
+ // with the bug present we'll get an exception in connection2.start()
+ connection2.Start();
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestCreateAndDisposeWithConsumer(
+ //[Values(true, false)]
+ bool disposeConsumer, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection("DisposalTestConnection"))
+ {
+ connection.Start();
+
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+
+ connection.Stop();
+ if(disposeConsumer)
+ {
+ consumer.Dispose();
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestCreateAndDisposeWithProducer(
+ //[Values(true, false)]
+ bool disposeProducer, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection("DisposalTestConnection"))
+ {
+ connection.Start();
+
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+
+ connection.Stop();
+ if(disposeProducer)
+ {
+ producer.Dispose();
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestStartAfterSend(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode,
+ string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+
+ // Send the messages
+ SendMessages(session, destination, deliveryMode, 1);
+
+ // Start the conncection after the message was sent.
+ connection.Start();
+
+ // Make sure only 1 message was delivered.
+ Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(1000)));
+ Assert.IsNull(consumer.ReceiveNoWait());
+ }
+ }
+
+ /// <summary>
+ /// Tests if the consumer receives the messages that were sent before the
+ /// connection was started.
+ /// </summary>
+ //[Test]
+ public virtual void TestStoppedConsumerHoldsMessagesTillStarted(string testDestRef)
+ {
+ ISession startedSession = startedConnection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ISession stoppedSession = stoppedConnection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+
+ // Setup the consumers.
+ IDestination destination = GetClearDestinationByNodeReference(startedSession, testDestRef);
+ IMessageConsumer startedConsumer = startedSession.CreateConsumer(destination);
+ IMessageConsumer stoppedConsumer = stoppedSession.CreateConsumer(destination);
+
+ // Send the message.
+ IMessageProducer producer = startedSession.CreateProducer(destination);
+ ITextMessage message = startedSession.CreateTextMessage("Hello");
+ producer.Send(message);
+
+ // Test the assertions.
+ IMessage m;
+ if(destination.IsTopic)
+ {
+ m = startedConsumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(m);
+ }
+
+ m = stoppedConsumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNull(m);
+
+ stoppedConnection.Start();
+ m = stoppedConsumer.Receive(TimeSpan.FromMilliseconds(5000));
+ Assert.IsNotNull(m);
+
+ startedSession.Close();
+ stoppedSession.Close();
+ }
+
+ /// <summary>
+ /// Tests if the consumer is able to receive messages even when the
+ /// connecction restarts multiple times.
+ /// </summary>
+ //[Test]
+ public virtual void TestMultipleConnectionStops(string testDestRef)
+ {
+ TestStoppedConsumerHoldsMessagesTillStarted(testDestRef);
+ stoppedConnection.Stop();
+ TestStoppedConsumerHoldsMessagesTillStarted(testDestRef);
+ stoppedConnection.Stop();
+ TestStoppedConsumerHoldsMessagesTillStarted(testDestRef);
+ }
+ }
+}
diff --git a/src/test/csharp/ConsumerTest.cs b/src/test/csharp/ConsumerTest.cs
new file mode 100644
index 0000000..ebe761a
--- /dev/null
+++ b/src/test/csharp/ConsumerTest.cs
@@ -0,0 +1,596 @@
+/*
+ * 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.
+ */
+using System;
+using System.Threading;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class ConsumerTest : NMSTest
+ {
+ protected const int COUNT = 25;
+ protected const string VALUE_NAME = "value";
+
+ private bool dontAck;
+
+ protected ConsumerTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+// The .NET CF does not have the ability to interrupt threads, so this test is impossible.
+#if !NETCF
+ //[Test]
+ public virtual void TestNoTimeoutConsumer(
+ string testDestRef,
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ // Launch a thread to perform IMessageConsumer.Receive().
+ // If it doesn't fail in less than three seconds, no exception was thrown.
+ Thread receiveThread = new Thread(new ThreadStart(TimeoutConsumerThreadProc));
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(this.timeoutConsumer = session.CreateConsumer(destination))
+ {
+ receiveThread.Start();
+ if(receiveThread.Join(3000))
+ {
+ Assert.Fail("IMessageConsumer.Receive() returned without blocking. Test failed.");
+ }
+ else
+ {
+ try
+ {
+ // Kill the thread - otherwise it'll sit in Receive() until a message arrives.
+ receiveThread.Interrupt();
+ // MSMQ MessageQueue.Receive is interrupted neither by Thread.Interrupt, nor by
+ // Thread.Abort. Send a dummy message to stop the background thread.
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateMessage());
+ }
+ catch
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected IMessageConsumer timeoutConsumer;
+
+ protected void TimeoutConsumerThreadProc()
+ {
+ try
+ {
+ timeoutConsumer.Receive();
+ }
+ catch(ArgumentOutOfRangeException e)
+ {
+ // The test failed. We will know because the timeout will expire inside TestNoTimeoutConsumer().
+ Assert.Fail("Test failed with exception: " + e.Message);
+ }
+ catch(ThreadInterruptedException)
+ {
+ // The test succeeded! We were still blocked when we were interrupted.
+ }
+ catch(Exception e)
+ {
+ // Some other exception occurred.
+ Assert.Fail("Test failed with exception: " + e.Message);
+ }
+ }
+
+ //[Test]
+ public virtual void TestSyncReceiveConsumerClose(
+ string testDestRef,
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ // Launch a thread to perform IMessageConsumer.Receive().
+ // If it doesn't fail in less than three seconds, no exception was thrown.
+ Thread receiveThread = new Thread(new ThreadStart(TimeoutConsumerThreadProc));
+ using (IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using (ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using (this.timeoutConsumer = session.CreateConsumer(destination))
+ {
+ receiveThread.Start();
+ if (receiveThread.Join(3000))
+ {
+ Assert.Fail("IMessageConsumer.Receive() returned without blocking. Test failed.");
+ }
+ else
+ {
+ // Kill the thread - otherwise it'll sit in Receive() until a message arrives.
+ this.timeoutConsumer.Close();
+ receiveThread.Join(10000);
+ if (receiveThread.IsAlive)
+ {
+ Assert.Fail("IMessageConsumer.Receive() thread is still alive, Close should have killed it.");
+ try
+ {
+ // Kill the thread - otherwise it'll sit in Receive() until a message arrives.
+ receiveThread.Interrupt();
+ // MSMQ MessageQueue.Receive is interrupted neither by Thread.Interrupt, nor by
+ // Thread.Abort. Send a dummy message to stop the background thread.
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateMessage());
+ }
+ catch
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ internal class ThreadArg
+ {
+ internal IConnection connection = null;
+ internal ISession session = null;
+ internal IDestination destination = null;
+ }
+
+ protected void DelayedProducerThreadProc(Object arg)
+ {
+ try
+ {
+ ThreadArg args = arg as ThreadArg;
+
+ using(ISession session = args.connection.CreateSession())
+ {
+ using(IMessageProducer producer = session.CreateProducer(args.destination))
+ {
+ // Give the consumer time to enter the receive.
+ Thread.Sleep(5000);
+
+ producer.Send(args.session.CreateTextMessage("Hello World"));
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ // Some other exception occurred.
+ Assert.Fail("Test failed with exception: " + e.Message);
+ }
+ }
+
+ //[Test]
+ public virtual void TestDoChangeSentMessage(
+ string testDestRef,
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode,
+ //[Values(true, false)]
+ bool doClear)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ IMessageProducer producer = session.CreateProducer(destination);
+ ITextMessage message = session.CreateTextMessage();
+
+ string prefix = "ConsumerTest - TestDoChangeSentMessage: ";
+
+ for(int i = 0; i < COUNT; i++)
+ {
+ message.Properties[VALUE_NAME] = i;
+ message.Text = prefix + Convert.ToString(i);
+
+ producer.Send(message);
+
+ if(doClear)
+ {
+ message.ClearBody();
+ message.ClearProperties();
+ }
+ }
+
+ if(ackMode == AcknowledgementMode.Transactional)
+ {
+ session.Commit();
+ }
+
+ for(int i = 0; i < COUNT; i++)
+ {
+ ITextMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000)) as ITextMessage;
+ Assert.AreEqual(msg.Text, prefix + Convert.ToString(i));
+ Assert.AreEqual(msg.Properties.GetInt(VALUE_NAME), i);
+ }
+
+ if(ackMode == AcknowledgementMode.Transactional)
+ {
+ session.Commit();
+ }
+
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestConsumerReceiveBeforeMessageDispatched(
+ string testDestRef,
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ // Launch a thread to perform a delayed send.
+ Thread sendThread = new Thread(DelayedProducerThreadProc);
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ ThreadArg arg = new ThreadArg();
+
+ arg.connection = connection;
+ arg.session = session;
+ arg.destination = destination;
+
+ sendThread.Start(arg);
+ IMessage message = consumer.Receive(TimeSpan.FromMinutes(1));
+ Assert.IsNotNull(message);
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestDontStart(
+ string testDestRef,
+ //[Values(MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ ISession session = connection.CreateSession();
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+
+ // Send the messages
+ SendMessages(session, destination, deliveryMode, 1);
+
+ // Make sure no messages were delivered.
+ Assert.IsNull(consumer.Receive(TimeSpan.FromMilliseconds(1000)));
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveTransacted(
+ string testDestRef,
+ //[Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ // Send a message to the broker.
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.Transactional);
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ IMessageProducer producer = session.CreateProducer(destination);
+
+ producer.DeliveryMode = deliveryMode;
+ producer.Send(session.CreateTextMessage("Test"));
+
+ // Message should not be delivered until commit.
+ Thread.Sleep(1000);
+ Assert.IsNull(consumer.ReceiveNoWait());
+ session.Commit();
+
+ // Make sure only 1 message was delivered.
+ IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(message);
+ Assert.IsFalse(message.NMSRedelivered);
+ Assert.IsNull(consumer.ReceiveNoWait());
+
+ // Message should be redelivered is rollback is used.
+ session.Rollback();
+
+ // Make sure only 1 message was delivered.
+ message = consumer.Receive(TimeSpan.FromMilliseconds(2000));
+ Assert.IsNotNull(message);
+ Assert.IsTrue(message.NMSRedelivered);
+ Assert.IsNull(consumer.ReceiveNoWait());
+
+ // If we commit now, the message should not be redelivered.
+ session.Commit();
+ Thread.Sleep(1000);
+ Assert.IsNull(consumer.ReceiveNoWait());
+ }
+ }
+
+ //[Test]
+ public virtual void TestAckedMessageAreConsumed(string testDestRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateTextMessage("Hello"));
+
+ // Consume the message...
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(msg);
+ msg.Acknowledge();
+
+ // Reset the session.
+ session.Close();
+ session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+
+ // Attempt to Consume the message...
+ consumer = session.CreateConsumer(destination);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNull(msg);
+
+ session.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestLastMessageAcked(string testDestRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateTextMessage("Hello"));
+ producer.Send(session.CreateTextMessage("Hello2"));
+ producer.Send(session.CreateTextMessage("Hello3"));
+
+ // Consume the message...
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(msg);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(msg);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(msg);
+ msg.Acknowledge();
+
+ // Reset the session.
+ session.Close();
+ session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+
+ // Attempt to Consume the message...
+ consumer = session.CreateConsumer(destination);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNull(msg);
+
+ session.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestUnAckedMessageAreNotConsumedOnSessionClose(string testDestRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateTextMessage("Hello"));
+
+ // Consume the message...
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(msg);
+ // Don't ack the message.
+
+ // Reset the session. This should cause the unacknowledged message to be re-delivered.
+ session.Close();
+ session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+
+ // Attempt to Consume the message...
+ consumer = session.CreateConsumer(destination);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(2000));
+ Assert.IsNotNull(msg);
+ msg.Acknowledge();
+
+ session.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestAsyncAckedMessageAreConsumed(string testDestRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateTextMessage("Hello"));
+
+ // Consume the message...
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ consumer.Listener += new MessageListener(OnMessage);
+
+ Thread.Sleep(5000);
+
+ // Reset the session.
+ session.Close();
+
+ session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+
+ // Attempt to Consume the message...
+ consumer = session.CreateConsumer(destination);
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNull(msg);
+
+ session.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestAsyncUnAckedMessageAreNotConsumedOnSessionClose(string testDestRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ // don't aknowledge message on onMessage() call
+ dontAck = true;
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.Send(session.CreateTextMessage("Hello"));
+
+ // Consume the message...
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ consumer.Listener += new MessageListener(OnMessage);
+ // Don't ack the message.
+ }
+
+ // Reset the session. This should cause the Unacked message to be
+ // redelivered.
+ session.Close();
+
+ Thread.Sleep(5000);
+ session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ // Attempt to Consume the message...
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000));
+ Assert.IsNotNull(msg);
+ msg.Acknowledge();
+ }
+
+ session.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestAddRemoveAsnycMessageListener(DestinationType destType, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+
+ ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+
+ consumer.Listener += OnMessage;
+ consumer.Listener -= OnMessage;
+ consumer.Listener += OnMessage;
+
+ consumer.Close();
+ }
+ }
+
+ public void OnMessage(IMessage message)
+ {
+ Assert.IsNotNull(message);
+
+ if(!dontAck)
+ {
+ try
+ {
+ message.Acknowledge();
+ }
+ catch(Exception)
+ {
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestReceiveNoWait(
+ string testDestRef,
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode,
+ //[Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ const int RETRIES = 20;
+
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage message = session.CreateTextMessage("TEST");
+ producer.Send(message);
+
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+ }
+
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ IMessage message = null;
+
+ for(int i = 0; i < RETRIES && message == null; ++i)
+ {
+ message = consumer.ReceiveNoWait();
+ Thread.Sleep(100);
+ }
+
+ Assert.IsNotNull(message);
+ message.Acknowledge();
+
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+ }
+ }
+ }
+ }
+
+#endif
+
+ }
+}
diff --git a/src/test/csharp/DurableTest.cs b/src/test/csharp/DurableTest.cs
new file mode 100644
index 0000000..aa38931
--- /dev/null
+++ b/src/test/csharp/DurableTest.cs
@@ -0,0 +1,267 @@
+/*
+ * 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.
+ */
+using System;
+using System.Threading;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class DurableTest : NMSTest
+ {
+ protected static string DURABLE_SELECTOR = "2 > 1";
+
+ protected string TEST_CLIENT_AND_CONSUMER_ID;
+ protected string SEND_CLIENT_ID;
+
+ protected DurableTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+
+ TEST_CLIENT_AND_CONSUMER_ID = GetTestClientId();
+ SEND_CLIENT_ID = GetTestClientId();
+ }
+
+ //[Test]
+ public virtual void TestSendWhileClosed(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode, string testTopicRef)
+ {
+ try
+ {
+ using(IConnection connection = CreateConnection(TEST_CLIENT_AND_CONSUMER_ID))
+ {
+ connection.Start();
+
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ ITopic topic = (ITopic)GetClearDestinationByNodeReference(session, testTopicRef);
+ IMessageProducer producer = session.CreateProducer(topic);
+
+ producer.DeliveryMode = MsgDeliveryMode.Persistent;
+
+ ISession consumeSession = connection.CreateSession(ackMode);
+ IMessageConsumer consumer = consumeSession.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, null, false);
+ Thread.Sleep(1000);
+ consumer.Dispose();
+ consumer = null;
+
+ ITextMessage message = session.CreateTextMessage("DurableTest-TestSendWhileClosed");
+ message.Properties.SetString("test", "test");
+ message.NMSType = "test";
+ producer.Send(message);
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+
+ Thread.Sleep(1000);
+ consumer = consumeSession.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, null, false);
+ ITextMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000)) as ITextMessage;
+ msg.Acknowledge();
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ consumeSession.Commit();
+ }
+
+ Assert.IsNotNull(msg);
+ Assert.AreEqual(msg.Text, "DurableTest-TestSendWhileClosed");
+ Assert.AreEqual(msg.NMSType, "test");
+ Assert.AreEqual(msg.Properties.GetString("test"), "test");
+ }
+ }
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail(ex.Message);
+ }
+ finally
+ {
+ // Pause to allow Stomp to unregister at the broker.
+ Thread.Sleep(500);
+
+ UnregisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, TEST_CLIENT_AND_CONSUMER_ID);
+ }
+ }
+
+ //[Test]
+ public void TestDurableConsumerSelectorChange(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode, string testTopicRef)
+ {
+ try
+ {
+ using(IConnection connection = CreateConnection(TEST_CLIENT_AND_CONSUMER_ID))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ ITopic topic = (ITopic)GetClearDestinationByNodeReference(session, testTopicRef);
+ IMessageProducer producer = session.CreateProducer(topic);
+ IMessageConsumer consumer = session.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, "color='red'", false);
+
+ producer.DeliveryMode = MsgDeliveryMode.Persistent;
+
+ // Send the messages
+ ITextMessage sendMessage = session.CreateTextMessage("1st");
+ sendMessage.Properties["color"] = "red";
+ producer.Send(sendMessage);
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+
+ ITextMessage receiveMsg = consumer.Receive(receiveTimeout) as ITextMessage;
+ Assert.IsNotNull(receiveMsg, "Failed to retrieve 1st durable message.");
+ Assert.AreEqual("1st", receiveMsg.Text);
+ Assert.AreEqual(MsgDeliveryMode.Persistent, receiveMsg.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ receiveMsg.Acknowledge();
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+
+ // Change the subscription, allowing some time for the Broker to purge the
+ // consumers resources.
+ consumer.Dispose();
+ Thread.Sleep(1000);
+
+ consumer = session.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, "color='blue'", false);
+
+ sendMessage = session.CreateTextMessage("2nd");
+ sendMessage.Properties["color"] = "red";
+ producer.Send(sendMessage);
+ sendMessage = session.CreateTextMessage("3rd");
+ sendMessage.Properties["color"] = "blue";
+ producer.Send(sendMessage);
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+
+ // Selector should skip the 2nd message.
+ receiveMsg = consumer.Receive(receiveTimeout) as ITextMessage;
+ Assert.IsNotNull(receiveMsg, "Failed to retrieve durable message.");
+ Assert.AreEqual("3rd", receiveMsg.Text, "Retrieved the wrong durable message.");
+ Assert.AreEqual(MsgDeliveryMode.Persistent, receiveMsg.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ receiveMsg.Acknowledge();
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+
+ // Make sure there are no pending messages.
+ Assert.IsNull(consumer.ReceiveNoWait(), "Wrong number of messages in durable subscription.");
+ }
+ }
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail(ex.Message);
+ }
+ finally
+ {
+ // Pause to allow Stomp to unregister at the broker.
+ Thread.Sleep(500);
+
+ UnregisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, TEST_CLIENT_AND_CONSUMER_ID);
+ }
+ }
+
+ //[Test]
+ public void TestDurableConsumer(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ // AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode, string testDurableTopicName)
+ {
+ try
+ {
+ RegisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, testDurableTopicName, TEST_CLIENT_AND_CONSUMER_ID, null, false);
+ RunTestDurableConsumer(testDurableTopicName, ackMode);
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ RunTestDurableConsumer(testDurableTopicName, ackMode);
+ }
+ }
+ finally
+ {
+ // Pause to allow Stomp to unregister at the broker.
+ Thread.Sleep(500);
+
+ UnregisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, TEST_CLIENT_AND_CONSUMER_ID);
+ }
+ }
+
+ protected void RunTestDurableConsumer(string topicName, AcknowledgementMode ackMode)
+ {
+ SendDurableMessage(topicName);
+ SendDurableMessage(topicName);
+
+ using(IConnection connection = CreateConnection(TEST_CLIENT_AND_CONSUMER_ID))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ ITopic topic = SessionUtil.GetTopic(session, topicName);
+ using(IMessageConsumer consumer = session.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, null, false))
+ {
+ IMessage msg = consumer.Receive(receiveTimeout);
+ Assert.IsNotNull(msg, "Did not receive first durable message.");
+ msg.Acknowledge();
+
+ msg = consumer.Receive(receiveTimeout);
+ Assert.IsNotNull(msg, "Did not receive second durable message.");
+ msg.Acknowledge();
+
+ if(AcknowledgementMode.Transactional == ackMode)
+ {
+ session.Commit();
+ }
+ }
+ }
+ }
+ }
+
+ protected void SendDurableMessage(string topicName)
+ {
+ using(IConnection connection = CreateConnection(SEND_CLIENT_ID))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ ITopic topic = SessionUtil.GetTopic(session, topicName);
+ using(IMessageProducer producer = session.CreateProducer(topic))
+ {
+ ITextMessage message = session.CreateTextMessage("Durable Hello");
+
+ producer.DeliveryMode = MsgDeliveryMode.Persistent;
+ producer.Send(message);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/EndianBinaryReaderTest.cs b/src/test/csharp/EndianBinaryReaderTest.cs
new file mode 100644
index 0000000..d2b392a
--- /dev/null
+++ b/src/test/csharp/EndianBinaryReaderTest.cs
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+using System.IO;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ [TestFixture]
+ public class EndianBinaryReaderTest
+ {
+ public void readString16Helper(byte[] input, char[] expect)
+ {
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ char[] result = reader.ReadString16().ToCharArray();
+
+ for(int i = 0; i < expect.Length; ++i)
+ {
+ Assert.AreEqual(expect[i], result[i]);
+ }
+ }
+
+ [Test]
+ public void testReadString16_1byteUTF8encoding()
+ {
+ // Test data with 1-byte UTF8 encoding.
+ char[] expect = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
+ byte[] input = { 0x00, 0x0E, 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };
+
+ readString16Helper(input, expect);
+ }
+
+ [Test]
+ public void testReadString16_2byteUTF8encoding()
+ {
+ // Test data with 2-byte UT8 encoding.
+ char[] expect = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
+ byte[] input = { 0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
+ readString16Helper(input, expect);
+ }
+
+ [Test]
+ public void testReadString16_1byteAnd2byteEmbeddedNULLs()
+ {
+ // Test data with 1-byte and 2-byte encoding with embedded NULL's.
+ char[] expect = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
+ byte[] input = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ readString16Helper(input, expect);
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testReadString16_UTF8Missing2ndByte()
+ {
+ // Test with bad UTF-8 encoding, missing 2nd byte of two byte value
+ byte[] input = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ reader.ReadString16();
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testReadString16_3byteEncodingMissingLastByte()
+ {
+ // Test with three byte encode that's missing a last byte.
+ byte[] input = { 0x00, 0x02, 0xE8, 0xA8 };
+
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ reader.ReadString16();
+ }
+
+ public void readString32Helper(byte[] input, char[] expect)
+ {
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ char[] result = reader.ReadString32().ToCharArray();
+
+ for(int i = 0; i < expect.Length; ++i)
+ {
+ Assert.AreEqual(expect[i], result[i]);
+ }
+ }
+
+ [Test]
+ public void testReadString32_1byteUTF8encoding()
+ {
+ // Test data with 1-byte UTF8 encoding.
+ char[] expect = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
+ byte[] input = { 0x00, 0x00, 0x00, 0x0E, 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };
+
+ readString32Helper(input, expect);
+ }
+
+ [Test]
+ public void testReadString32_2byteUTF8encoding()
+ {
+ // Test data with 2-byte UT8 encoding.
+ char[] expect = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
+ byte[] input = { 0x00, 0x00, 0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
+ readString32Helper(input, expect);
+ }
+
+ [Test]
+ public void testReadString32_1byteAnd2byteEmbeddedNULLs()
+ {
+ // Test data with 1-byte and 2-byte encoding with embedded NULL's.
+ char[] expect = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
+ byte[] input = { 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ readString32Helper(input, expect);
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testReadString32_UTF8Missing2ndByte()
+ {
+ // Test with bad UTF-8 encoding, missing 2nd byte of two byte value
+ byte[] input = { 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ reader.ReadString32();
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testReadString32_3byteEncodingMissingLastByte()
+ {
+ // Test with three byte encode that's missing a last byte.
+ byte[] input = { 0x00, 0x00, 0x00, 0x02, 0xE8, 0xA8 };
+
+ MemoryStream stream = new MemoryStream(input);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+
+ reader.ReadString32();
+ }
+ }
+}
diff --git a/src/test/csharp/EndianBinaryWriterTest.cs b/src/test/csharp/EndianBinaryWriterTest.cs
new file mode 100644
index 0000000..5baf66f
--- /dev/null
+++ b/src/test/csharp/EndianBinaryWriterTest.cs
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.IO;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ [TestFixture]
+ public class EndianBinaryWriterTest
+ {
+ void writeString16TestHelper(char[] input, byte[] expect)
+ {
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+
+ String str = new String(input);
+
+ writer.WriteString16(str);
+
+ byte[] result = stream.GetBuffer();
+
+ Assert.AreEqual(result[0], 0x00);
+ Assert.AreEqual(result[1], expect.Length);
+
+ for(int i = 4; i < expect.Length; ++i)
+ {
+ Assert.AreEqual(result[i], expect[i - 2]);
+ }
+ }
+
+ [Test]
+ public void testWriteString16_1byteUTF8encoding()
+ {
+ // Test data with 1-byte UTF8 encoding.
+ char[] input = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
+ byte[] expect = { 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };
+
+ writeString16TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString16_2byteUTF8encoding()
+ {
+ // Test data with 2-byte UT8 encoding.
+ char[] input = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
+ byte[] expect = { 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
+
+ writeString16TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString16_1byteAnd2byteEmbeddedNULLs()
+ {
+ // Test data with 1-byte and 2-byte encoding with embedded NULL's.
+ char[] input = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
+ byte[] expect = { 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ writeString16TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString16_nullstring()
+ {
+ // test that a null string writes no output.
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ writer.WriteString16(null);
+ Assert.AreEqual(0, stream.Length);
+ }
+
+ [Test]
+ public void testWriteString16_emptystring()
+ {
+ // test that a null string writes no output.
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ writer.WriteString16("");
+
+ stream.Seek(0, SeekOrigin.Begin);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+ Assert.AreEqual(0, reader.ReadInt16());
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testWriteString16_stringTooLong()
+ {
+ // String of length 65536 of Null Characters.
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ String testStr = new String('a', 65536);
+ writer.Write(testStr);
+ }
+
+ [Test]
+ public void testWriteString16_maxStringLength()
+ {
+ // String of length 65535 of non Null Characters since Null encodes as UTF-8.
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ String testStr = new String('a', 65535);
+ writer.Write(testStr);
+ }
+
+ [Test]
+ [ExpectedException(typeof(IOException))]
+ public void testWriteString16_invalidEncodingHeader()
+ {
+ // Set one of the 65535 bytes to a value that will result in a 2 byte UTF8 encoded sequence.
+ // This will cause the string of length 65535 to have a utf length of 65536.
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ String testStr = new String('a', 65535);
+ char[] array = testStr.ToCharArray();
+ array[0] = '\u0000';
+ testStr = new String(array);
+ writer.Write(testStr);
+ }
+
+ void writeString32TestHelper(char[] input, byte[] expect)
+ {
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+
+ String str = new String(input);
+
+ writer.WriteString32(str);
+
+ byte[] result = stream.GetBuffer();
+
+ Assert.AreEqual(result[0], 0x00);
+ Assert.AreEqual(result[1], 0x00);
+ Assert.AreEqual(result[2], 0x00);
+ Assert.AreEqual(result[3], expect.Length);
+
+ for(int i = 4; i < expect.Length; ++i)
+ {
+ Assert.AreEqual(result[i], expect[i - 4]);
+ }
+ }
+
+ [Test]
+ public void testWriteString32_1byteUTF8encoding()
+ {
+ // Test data with 1-byte UTF8 encoding.
+ char[] input = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
+ byte[] expect = { 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };
+
+ writeString32TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString32_2byteUTF8encoding()
+ {
+ // Test data with 2-byte UT8 encoding.
+ char[] input = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
+ byte[] expect = { 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
+
+ writeString32TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString32_1byteAnd2byteEmbeddedNULLs()
+ {
+ // Test data with 1-byte and 2-byte encoding with embedded NULL's.
+ char[] input = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
+ byte[] expect = { 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };
+
+ writeString32TestHelper(input, expect);
+ }
+
+ [Test]
+ public void testWriteString32_nullstring()
+ {
+ // test that a null strings writes a -1
+ MemoryStream stream = new MemoryStream();
+ EndianBinaryWriter writer = new EndianBinaryWriter(stream);
+ writer.WriteString32(null);
+
+ stream.Seek(0, SeekOrigin.Begin);
+ EndianBinaryReader reader = new EndianBinaryReader(stream);
+ Assert.AreEqual(-1, reader.ReadInt32());
+ }
+ }
+}
diff --git a/src/test/csharp/EndianTest.cs b/src/test/csharp/EndianTest.cs
new file mode 100644
index 0000000..ad9ce08
--- /dev/null
+++ b/src/test/csharp/EndianTest.cs
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+using System.IO;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ [TestFixture]
+ public class EndianTest
+ {
+ [Test]
+ public void TestLongEndian()
+ {
+ long value = 0x0102030405060708L;
+ long newValue = EndianSupport.SwitchEndian(value);
+ Assert.AreEqual(0x0807060504030201L, newValue);
+ long actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestIntEndian()
+ {
+ int value = 0x12345678;
+ int newValue = EndianSupport.SwitchEndian(value);
+ Assert.AreEqual(0x78563412, newValue);
+ int actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestCharEndian()
+ {
+ char value = 'J';
+ char newValue = EndianSupport.SwitchEndian(value);
+ char actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestShortEndian()
+ {
+ short value = 0x1234;
+ short newValue = EndianSupport.SwitchEndian(value);
+ Assert.AreEqual(0x3412, newValue);
+ short actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestNegativeLongEndian()
+ {
+ long value = -0x0102030405060708L;
+ long newValue = EndianSupport.SwitchEndian(value);
+ long actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestNegativeIntEndian()
+ {
+ int value = -0x12345678;
+ int newValue = EndianSupport.SwitchEndian(value);
+ int actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestNegativeShortEndian()
+ {
+ short value = -0x1234;
+ short newValue = EndianSupport.SwitchEndian(value);
+ short actual = EndianSupport.SwitchEndian(newValue);
+ Assert.AreEqual(value, actual);
+ }
+
+ [Test]
+ public void TestFloatDontNeedEndianSwitch()
+ {
+ float value = -1.223F;
+
+ // Convert to int so we can compare to Java version.
+ MemoryStream ms = new MemoryStream(4);
+ BinaryWriter bw = new BinaryWriter(ms);
+ bw.Write(value);
+ bw.Close();
+ ms = new MemoryStream(ms.ToArray());
+ BinaryReader br = new BinaryReader(ms);
+
+ // System.out.println(Integer.toString(Float.floatToIntBits(-1.223F), 16));
+ Assert.AreEqual(-0x406374bc, br.ReadInt32());
+ }
+
+ [Test]
+ public void TestDoublDontNeedEndianSwitch()
+ {
+ double value = -1.223D;
+
+ // Convert to int so we can compare to Java version.
+ MemoryStream ms = new MemoryStream(4);
+ BinaryWriter bw = new BinaryWriter(ms);
+ bw.Write(value);
+ bw.Close();
+ ms = new MemoryStream(ms.ToArray());
+ BinaryReader br = new BinaryReader(ms);
+ long longVersion = br.ReadInt64();
+
+ // System.out.println(Long.toString(Double.doubleToLongBits(-1.223D), 16));
+ Assert.AreEqual(-0x400c6e978d4fdf3b, longVersion);
+ }
+ }
+}
+
+
+
diff --git a/src/test/csharp/ForeignMessageTransformationTest.cs b/src/test/csharp/ForeignMessageTransformationTest.cs
new file mode 100644
index 0000000..225ae88
--- /dev/null
+++ b/src/test/csharp/ForeignMessageTransformationTest.cs
@@ -0,0 +1,315 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Commands;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class ForeignMessageTransformationTest : NMSTest
+ {
+ private string propertyName = "Test-Property";
+ private string propertyValue = "Test-Property-Value";
+ private string mapElementName = "Test-Map-Property";
+ private string mapElementValue = "Test-Map-Property-Value";
+ private string textBody = "This is a TextMessage from a Foreign Provider";
+ private byte[] bytesContent = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ private bool a = true;
+ private byte b = 123;
+ private char c = 'c';
+ private short d = 0x1234;
+ private int e = 0x12345678;
+ private long f = 0x1234567812345678;
+ private string g = "Hello World!";
+ private bool h = false;
+ private byte i = 0xFF;
+ private short j = -0x1234;
+ private int k = -0x12345678;
+ private long l = -0x1234567812345678;
+ private float m = 2.1F;
+ private double n = 2.3;
+
+ protected ForeignMessageTransformationTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveForeignMessage(
+ //[Values(DEFAULT_TEST_QUEUE, DEFAULT_TEST_TOPIC)]
+ string testDestRef,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ Message request = new Message();
+ request.Properties[propertyName] = propertyValue;
+
+ producer.Send(request);
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // use generic API to access entries
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);
+
+ // use type safe APIs
+ Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName), "map entry: " + propertyName);
+ }
+ catch(NotSupportedException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveForeignTextMessage(
+ //[Values(DEFAULT_TEST_QUEUE, DEFAULT_TEST_TOPIC)]
+ string testDestRef,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ TextMessage request = new TextMessage();
+ request.Properties[propertyName] = propertyValue;
+ request.Text = textBody;
+
+ producer.Send(request);
+
+ ITextMessage message = consumer.Receive(receiveTimeout) as ITextMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // Check the body
+ Assert.AreEqual(textBody, message.Text, "TextMessage body was wrong.");
+
+ // use generic API to access entries
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);
+
+ // use type safe APIs
+ Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName), "map entry: " + propertyName);
+ }
+ catch(NotSupportedException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveForeignBytesMessage(
+ //[Values(DEFAULT_TEST_QUEUE, DEFAULT_TEST_TOPIC)]
+ string testDestRef,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ BytesMessage request = new BytesMessage();
+ request.Properties[propertyName] = propertyValue;
+ request.WriteBytes(bytesContent);
+
+ producer.Send(request);
+
+ IBytesMessage message = consumer.Receive(receiveTimeout) as IBytesMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // Check the body
+ byte[] content = new byte[bytesContent.Length];
+ Assert.AreEqual(bytesContent.Length, message.ReadBytes(content));
+ Assert.AreEqual(bytesContent, content, "BytesMessage body was wrong.");
+
+ // use generic API to access entries
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);
+
+ // use type safe APIs
+ Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName), "map entry: " + propertyName);
+ }
+ catch(NotSupportedException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveForeignMapMessage(
+ //[Values(DEFAULT_TEST_QUEUE, DEFAULT_TEST_TOPIC)]
+ string testDestRef,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ MapMessage request = new MapMessage();
+ request.Properties[propertyName] = propertyValue;
+ request.Body[mapElementName] = mapElementValue;
+
+ producer.Send(request);
+
+ IMapMessage message = consumer.Receive(receiveTimeout) as IMapMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // Check the body
+ Assert.AreEqual(request.Body.Count, message.Body.Count);
+ Assert.AreEqual(mapElementValue, message.Body[mapElementName], "MapMessage body was wrong.");
+
+ // use generic API to access entries
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);
+
+ // use type safe APIs
+ Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName), "map entry: " + propertyName);
+ }
+ catch(NotSupportedException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveForeignStreamMessage(
+ //[Values(DEFAULT_TEST_QUEUE, DEFAULT_TEST_TOPIC)]
+ string testDestRef,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ StreamMessage request = new StreamMessage();
+ request.Properties[propertyName] = propertyValue;
+
+ request.WriteBoolean(a);
+ request.WriteByte(b);
+ request.WriteChar(c);
+ request.WriteInt16(d);
+ request.WriteInt32(e);
+ request.WriteInt64(f);
+ request.WriteString(g);
+ request.WriteBoolean(h);
+ request.WriteByte(i);
+ request.WriteInt16(j);
+ request.WriteInt32(k);
+ request.WriteInt64(l);
+ request.WriteSingle(m);
+ request.WriteDouble(n);
+
+ producer.Send(request);
+
+ IStreamMessage message = consumer.Receive(receiveTimeout) as IStreamMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // Check the body
+ Assert.AreEqual(a, message.ReadBoolean(), "Stream Boolean Value: a");
+ Assert.AreEqual(b, message.ReadByte(), "Stream Byte Value: b");
+ Assert.AreEqual(c, message.ReadChar(), "Stream Char Value: c");
+ Assert.AreEqual(d, message.ReadInt16(), "Stream Int16 Value: d");
+ Assert.AreEqual(e, message.ReadInt32(), "Stream Int32 Value: e");
+ Assert.AreEqual(f, message.ReadInt64(), "Stream Int64 Value: f");
+ Assert.AreEqual(g, message.ReadString(), "Stream String Value: g");
+ Assert.AreEqual(h, message.ReadBoolean(), "Stream Boolean Value: h");
+ Assert.AreEqual(i, message.ReadByte(), "Stream Byte Value: i");
+ Assert.AreEqual(j, message.ReadInt16(), "Stream Int16 Value: j");
+ Assert.AreEqual(k, message.ReadInt32(), "Stream Int32 Value: k");
+ Assert.AreEqual(l, message.ReadInt64(), "Stream Int64 Value: l");
+ Assert.AreEqual(m, message.ReadSingle(), "Stream Single Value: m");
+ Assert.AreEqual(n, message.ReadDouble(), "Stream Double Value: n");
+
+ // use generic API to access entries
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);
+
+ // use type safe APIs
+ Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName), "map entry: " + propertyName);
+ }
+ catch(NotSupportedException)
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQAsyncConsumeTest.cs b/src/test/csharp/MSMQAsyncConsumeTest.cs
new file mode 100644
index 0000000..4aabb1e
--- /dev/null
+++ b/src/test/csharp/MSMQAsyncConsumeTest.cs
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+using System.Threading;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQAsyncConsumeTest : AsyncConsumeTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public MSMQAsyncConsumeTest() :
+ base(new MSMQTestSupport())
+ {
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [TearDown]
+ public override void TearDown()
+ {
+ base.TearDown();
+ }
+
+ [Test]
+ public void TestAsynchronousConsume(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestAsynchronousConsume(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestCreateConsumerAfterSend(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestCreateConsumerAfterSend(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestCreateConsumerBeforeSendAddListenerAfterSend(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestCreateConsumerBeforeSendAddListenerAfterSend(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestAsynchronousTextMessageConsume(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestAsynchronousTextMessageConsume(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ [Ignore("Temporary queues are not supported")]
+ public void TestTemporaryQueueAsynchronousConsume(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))
+ using(ISession syncSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession asyncSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(IDestination destination = GetClearDestinationByNodeReference(syncSession, DEFAULT_TEST_QUEUE))
+ using(ITemporaryQueue tempReplyDestination = syncSession.CreateTemporaryQueue())
+ using(IMessageConsumer consumer = asyncSession.CreateConsumer(destination))
+ using(IMessageConsumer tempConsumer = asyncSession.CreateConsumer(tempReplyDestination))
+ using(IMessageProducer producer = syncSession.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ tempConsumer.Listener += new MessageListener(OnMessage);
+ consumer.Listener += new MessageListener(OnQueueMessage);
+
+ IMessage request = syncSession.CreateMessage();
+ request.NMSCorrelationID = "TemqQueueAsyncConsume";
+ request.NMSType = "Test";
+ request.NMSReplyTo = tempReplyDestination;
+ producer.Send(request);
+
+ WaitForMessageToArrive();
+ Assert.AreEqual("TempQueueAsyncResponse", receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQBadConsumeTest.cs b/src/test/csharp/MSMQBadConsumeTest.cs
new file mode 100644
index 0000000..b8e9089
--- /dev/null
+++ b/src/test/csharp/MSMQBadConsumeTest.cs
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+using System;
+using NUnit.Framework;
+using Apache.NMS.Test;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQBadConsumeTest : BadConsumeTest
+ {
+ public MSMQBadConsumeTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [TearDown]
+ public override void TearDown()
+ {
+ base.TearDown();
+ }
+
+ [Test]
+ [ExpectedException(Handler="ExceptionValidationCheck")]
+ public override void TestBadConsumerException()
+ {
+ base.TestBadConsumerException();
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQBytesMessageTest.cs b/src/test/csharp/MSMQBytesMessageTest.cs
new file mode 100644
index 0000000..5c58bc9
--- /dev/null
+++ b/src/test/csharp/MSMQBytesMessageTest.cs
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQBytesMessageTest : BytesMessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public MSMQBytesMessageTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public void SendReceiveBytesMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.SendReceiveBytesMessage(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void SendReceiveBytesMessageContent(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.SendReceiveBytesMessageContent(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQConnectionTest.cs b/src/test/csharp/MSMQConnectionTest.cs
new file mode 100644
index 0000000..cc3d2d4
--- /dev/null
+++ b/src/test/csharp/MSMQConnectionTest.cs
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQConnectionTest : ConnectionTest
+ {
+ protected const string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+ protected const string DEFAULT_TEST_TOPIC = "defaultTestTopic";
+
+ public MSMQConnectionTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [TearDown]
+ public override void TearDown()
+ {
+ base.TearDown();
+ }
+
+ /// <summary>
+ /// Verify that it is possible to create multiple connections to the broker.
+ /// There was a bug in the connection factory which set the clientId member which made
+ /// it impossible to create an additional connection.
+ /// </summary>
+ [Test]
+ public override void TestTwoConnections()
+ {
+ base.TestTwoConnections();
+ }
+
+ [Test]
+ public void TestCreateAndDisposeWithConsumer(
+ [Values(true, false)]
+ bool disposeConsumer)
+ {
+ base.TestCreateAndDisposeWithConsumer(disposeConsumer, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestCreateAndDisposeWithProducer(
+ [Values(true, false)]
+ bool disposeProducer)
+ {
+ base.TestCreateAndDisposeWithProducer(disposeProducer, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestStartAfterSend(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestStartAfterSend(deliveryMode, testDestRef);
+ }
+
+ /// <summary>
+ /// Tests if the consumer receives the messages that were sent before the
+ /// connection was started.
+ /// </summary>
+ [Test]
+ public override void TestStoppedConsumerHoldsMessagesTillStarted(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef)
+ {
+ base.TestStoppedConsumerHoldsMessagesTillStarted(testDestRef);
+ }
+
+ /// <summary>
+ /// Tests if the consumer is able to receive messages even when the
+ /// connecction restarts multiple times.
+ /// </summary>
+ [Test]
+ public override void TestMultipleConnectionStops(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef)
+ {
+ base.TestMultipleConnectionStops(testDestRef);
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQConsumerTest.cs b/src/test/csharp/MSMQConsumerTest.cs
new file mode 100644
index 0000000..b7f7478
--- /dev/null
+++ b/src/test/csharp/MSMQConsumerTest.cs
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+using System;
+using System.Threading;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQConsumerTest : ConsumerTest
+ {
+ protected const string DEFAULT_TEST_QUEUE = "transactionTestQueue";
+ protected const string DEFAULT_TEST_TOPIC = "defaultTestTopic";
+
+ public MSMQConsumerTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+// The .NET CF does not have the ability to interrupt threads, so this test is impossible.
+#if !NETCF
+ [Test]
+ public override void TestNoTimeoutConsumer(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ base.TestNoTimeoutConsumer(testDestRef, ackMode);
+ }
+
+ [Test]
+ public override void TestSyncReceiveConsumerClose(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ base.TestSyncReceiveConsumerClose(testDestRef, ackMode);
+ }
+
+ [Test]
+ public override void TestDoChangeSentMessage(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode,
+ [Values(true, false)] bool doClear)
+ {
+ base.TestDoChangeSentMessage(testDestRef, ackMode, doClear);
+ }
+
+ [Test]
+ public override void TestConsumerReceiveBeforeMessageDispatched(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ base.TestConsumerReceiveBeforeMessageDispatched(testDestRef, ackMode);
+ }
+
+ [Test]
+ public override void TestDontStart(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestDontStart(testDestRef, deliveryMode);
+ }
+
+ [Test]
+ public override void TestSendReceiveTransacted(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC, DEFAULT_TEST_TEMP_QUEUE, DEFAULT_TEST_TEMP_TOPIC*/)]
+ string testDestRef,
+ [Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveTransacted(testDestRef, deliveryMode);
+ }
+
+ [Test]
+ public void TestAckedMessageAreConsumed()
+ {
+ base.TestAckedMessageAreConsumed(DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestLastMessageAcked()
+ {
+ base.TestLastMessageAcked(DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestUnAckedMessageAreNotConsumedOnSessionClose()
+ {
+ base.TestUnAckedMessageAreNotConsumedOnSessionClose(DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestAsyncAckedMessageAreConsumed()
+ {
+ base.TestAsyncAckedMessageAreConsumed(DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestAsyncUnAckedMessageAreNotConsumedOnSessionClose()
+ {
+ base.TestAsyncUnAckedMessageAreNotConsumedOnSessionClose(DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public /*override*/ void TestAddRemoveAsnycMessageListener()
+ {
+ base.TestAddRemoveAsnycMessageListener(DestinationType.Queue, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public override void TestReceiveNoWait(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode,
+ [Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestReceiveNoWait(testDestRef, ackMode, deliveryMode);
+ }
+
+#endif
+
+ }
+}
diff --git a/src/test/csharp/MSMQDurableTest.cs b/src/test/csharp/MSMQDurableTest.cs
new file mode 100644
index 0000000..fe1d5b5
--- /dev/null
+++ b/src/test/csharp/MSMQDurableTest.cs
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ [Ignore("Topics are not supported")]
+ public class MSMQDurableTest : DurableTest
+ {
+ protected const string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+ protected const string DEFAULT_TEST_TOPIC = "defaultTestTopic";
+ protected const string DURABLE_TEST_TOPIC = "durableConsumerTestTopic";
+
+ public MSMQDurableTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [Test]
+ public void TestSendWhileClosed(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ base.TestSendWhileClosed(ackMode, DEFAULT_TEST_TOPIC);
+ }
+
+ [Test]
+ public void TestDurableConsumerSelectorChange(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ base.TestDurableConsumerSelectorChange(ackMode, DEFAULT_TEST_TOPIC);
+ }
+
+ [Test]
+ public void TestDurableConsumer(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,
+ AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]
+ AcknowledgementMode ackMode)
+ {
+ string testDurableTopicURI = GetDestinationURI(DURABLE_TEST_TOPIC);
+
+ base.TestDurableConsumer(ackMode, testDurableTopicURI);
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQForeignMessageTransformationTest.cs b/src/test/csharp/MSMQForeignMessageTransformationTest.cs
new file mode 100644
index 0000000..17043f3
--- /dev/null
+++ b/src/test/csharp/MSMQForeignMessageTransformationTest.cs
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQForeignMessageTransformationTest : ForeignMessageTransformationTest
+ {
+ protected const string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+ protected const string DEFAULT_TEST_TOPIC = "defaultTestTopic";
+
+ public MSMQForeignMessageTransformationTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public override void TestSendReceiveForeignMessage(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveForeignMessage(testDestRef, deliveryMode);
+ }
+
+ [Test]
+ public override void TestSendReceiveForeignTextMessage(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveForeignTextMessage(testDestRef, deliveryMode);
+ }
+
+ [Test]
+ public override void TestSendReceiveForeignBytesMessage(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveForeignBytesMessage(testDestRef, deliveryMode);
+ }
+
+ [Test]
+ public override void TestSendReceiveForeignMapMessage(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveForeignMapMessage(testDestRef, deliveryMode);
+ }
+
+ [Test]
+ public override void TestSendReceiveForeignStreamMessage(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC*/)]
+ string testDestRef,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveForeignStreamMessage(testDestRef, deliveryMode);
+ }
+ }
+}
+
diff --git a/src/test/csharp/MSMQMapMessageTest.cs b/src/test/csharp/MSMQMapMessageTest.cs
new file mode 100644
index 0000000..3afbcbe
--- /dev/null
+++ b/src/test/csharp/MSMQMapMessageTest.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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQMapMessageTest : MapMessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public MSMQMapMessageTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveMapMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveMapMessage(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestSendReceiveNestedMapMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveNestedMapMessage(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQMessageSelectorTest.cs b/src/test/csharp/MSMQMessageSelectorTest.cs
new file mode 100644
index 0000000..5a108cd
--- /dev/null
+++ b/src/test/csharp/MSMQMessageSelectorTest.cs
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Test;
+using NUnit.Framework;
+using System.Globalization;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ [Category("LongRunning")]
+ public class MSMQMessageSelectorTest : MessageSelectorTest
+ {
+ protected const string SELECTOR_TEST_QUEUE = "messageSelectorTestQueue";
+ protected const string SELECTOR_TEST_TOPIC = "messageSelectorTestTopic";
+
+ public MSMQMessageSelectorTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public override void TestFilterIgnoredMessages(
+ [Values(SELECTOR_TEST_QUEUE /*, SELECTOR_TEST_TOPIC*/)]
+ string testDestRef)
+ {
+ base.TestFilterIgnoredMessages(testDestRef);
+ }
+
+ [Test]
+ public override void TestFilterIgnoredMessagesSlowConsumer(
+ [Values(SELECTOR_TEST_QUEUE /*, SELECTOR_TEST_TOPIC*/)]
+ string testDestRef)
+ {
+ base.TestFilterIgnoredMessagesSlowConsumer(testDestRef);
+ }
+
+
+ [Test]
+ public override void TestInvalidSelector(
+ [Values(SELECTOR_TEST_QUEUE)]
+ string testDestRef)
+ {
+ base.TestInvalidSelector(testDestRef);
+ }
+
+ [Test]
+ public void TestSelectByMessageId(
+ [Values(SELECTOR_TEST_QUEUE)]
+ string testDestRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ ITextMessage message = null;
+
+ int COUNT = 5;
+ for(int i = 1; i <= COUNT; i++)
+ {
+ message = session.CreateTextMessage("MessageSelectorTest - TestSelectByMessageId: " + i.ToString());
+ producer.Send(message);
+ }
+
+ using(IQueueBrowser browser = session.CreateBrowser((IQueue)destination))
+ {
+ int i = 0;
+ foreach(IMessage message0 in browser)
+ {
+ if(++i == COUNT / 2)
+ {
+ message = message0 as ITextMessage;
+ break;
+ }
+ }
+ }
+
+ string selector = "NMSMessageId = '" + message.NMSMessageId + "'";
+
+ using(IMessageConsumer consumer = session.CreateConsumer(destination, selector))
+ {
+ ITextMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000)) as ITextMessage;
+ Assert.IsNotNull(msg);
+ Assert.AreEqual(msg.Text, message.Text);
+ Assert.AreEqual(msg.NMSMessageId, message.NMSMessageId);
+
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(2000)) as ITextMessage;
+ Assert.IsNull(msg);
+ }
+ }
+ }
+ }
+ }
+
+ [Test]
+ public void TestSelectByLookupId(
+ [Values(SELECTOR_TEST_QUEUE)]
+ string testDestRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ ITextMessage message = null;
+
+ int COUNT = 5;
+ for(int i = 1; i <= COUNT; i++)
+ {
+ message = session.CreateTextMessage("MessageSelectorTest - TestSelectByLookupId: " + i.ToString());
+ producer.Send(message);
+ }
+
+ using(IQueueBrowser browser = session.CreateBrowser((IQueue)destination))
+ {
+ int i = 0;
+ foreach(IMessage message0 in browser)
+ {
+ if(++i == COUNT / 2)
+ {
+ message = message0 as ITextMessage;
+ break;
+ }
+ }
+ }
+
+ long lookupId = (long)(message.Properties["LookupId"]);
+ string selector = "LookupId = " + lookupId.ToString(CultureInfo.InvariantCulture);
+
+ using(IMessageConsumer consumer = session.CreateConsumer(destination, selector))
+ {
+ ITextMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000)) as ITextMessage;
+ Assert.IsNotNull(msg);
+ Assert.AreEqual(msg.Text, message.Text);
+ Assert.AreEqual(msg.Properties["LookupId"], lookupId);
+
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(2000)) as ITextMessage;
+ Assert.IsNull(msg);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQMessageTest.cs b/src/test/csharp/MSMQMessageTest.cs
new file mode 100644
index 0000000..1cfcd70
--- /dev/null
+++ b/src/test/csharp/MSMQMessageTest.cs
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQMessageTest : MessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public MSMQMessageTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveMessageProperties(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveMessageProperties(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
+
diff --git a/src/test/csharp/MSMQMessageTransformerTest.cs b/src/test/csharp/MSMQMessageTransformerTest.cs
new file mode 100644
index 0000000..2249db5
--- /dev/null
+++ b/src/test/csharp/MSMQMessageTransformerTest.cs
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQMessageTransformerTest : MessageTransformerTest
+ {
+ public MSMQMessageTransformerTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public override void TestProducerTransformer(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestProducerTransformer(deliveryMode);
+ }
+
+ [Test]
+ public override void TestConsumerTransformer(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestConsumerTransformer(deliveryMode);
+ }
+ }
+}
+
diff --git a/src/test/csharp/MSMQNMSPropertyTest.cs b/src/test/csharp/MSMQNMSPropertyTest.cs
new file mode 100644
index 0000000..3968aea
--- /dev/null
+++ b/src/test/csharp/MSMQNMSPropertyTest.cs
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQNMSPropertyTest : NMSPropertyTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public MSMQNMSPropertyTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveNMSProperties(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveNMSProperties(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQProducerTest.cs b/src/test/csharp/MSMQProducerTest.cs
new file mode 100644
index 0000000..bbe86fd
--- /dev/null
+++ b/src/test/csharp/MSMQProducerTest.cs
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQProducerTest : ProducerTest
+ {
+ protected const string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+ protected const string DEFAULT_TEST_TOPIC = "defaultTestTopic";
+ protected const string DEFAULT_TEST_TEMP_QUEUE = "defaultTestTempQueue";
+ protected const string DEFAULT_TEST_TEMP_TOPIC = "defaultTestTempTopic";
+
+ protected const string DEFAULT_TEST_QUEUE2 = "defaultTestQueue2";
+ protected const string DEFAULT_TEST_TOPIC2 = "defaultTestTopic2";
+ protected const string DEFAULT_TEST_TEMP_QUEUE2 = "defaultTestTempQueue2";
+ protected const string DEFAULT_TEST_TEMP_TOPIC2 = "defaultTestTempTopic2";
+
+ public MSMQProducerTest()
+ : base(new NMSTestSupport())
+ {
+ }
+
+ [Test]
+ public override void TestProducerSendToNullDestinationWithoutDefault()
+ {
+ base.TestProducerSendToNullDestinationWithoutDefault();
+ }
+
+ [Test]
+ public override void TestProducerSendToNullDestinationWithDefault(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC, DEFAULT_TEST_TEMP_QUEUE, DEFAULT_TEST_TEMP_TOPIC*/)]
+ string testDestRef)
+ {
+ base.TestProducerSendToNullDestinationWithDefault(testDestRef);
+ }
+
+ [Test]
+ public override void TestProducerSendToNonDefaultDestination(
+ [Values(DEFAULT_TEST_QUEUE /*, DEFAULT_TEST_TOPIC, DEFAULT_TEST_TEMP_QUEUE, DEFAULT_TEST_TEMP_TOPIC*/)]
+ string unusedTestDestRef,
+ [Values(DEFAULT_TEST_QUEUE2 /*, DEFAULT_TEST_TOPIC2, DEFAULT_TEST_TEMP_QUEUE2, DEFAULT_TEST_TEMP_TOPIC2*/)]
+ string usedTestDestRef)
+ {
+ base.TestProducerSendToNonDefaultDestination(unusedTestDestRef, usedTestDestRef);
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQRequestResponseTest.cs b/src/test/csharp/MSMQRequestResponseTest.cs
new file mode 100644
index 0000000..1261ab1
--- /dev/null
+++ b/src/test/csharp/MSMQRequestResponseTest.cs
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQRequestResponseTest : RequestResponseTest
+ {
+ protected const string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+ protected const string DEFAULT_TEST_QUEUE2 = "defaultTestQueue2";
+
+ public MSMQRequestResponseTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ [Category("RequestResponse")]
+ public void TestRequestResponseMessaging()
+ {
+ base.TestRequestResponseMessaging(DEFAULT_TEST_QUEUE, DEFAULT_TEST_QUEUE2);
+ }
+ }
+}
+
diff --git a/src/test/csharp/MSMQStreamMessageTest.cs b/src/test/csharp/MSMQStreamMessageTest.cs
new file mode 100644
index 0000000..75d8c99
--- /dev/null
+++ b/src/test/csharp/MSMQStreamMessageTest.cs
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQStreamMessageTest : StreamMessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public MSMQStreamMessageTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveStreamMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveStreamMessage(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQTempDestinationDeletionTest.cs b/src/test/csharp/MSMQTempDestinationDeletionTest.cs
new file mode 100644
index 0000000..b2d8a41
--- /dev/null
+++ b/src/test/csharp/MSMQTempDestinationDeletionTest.cs
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ [Ignore("Temporary queues are not supported")]
+ public class MSMQTempDestinationDeletionTest : TempDestinationDeletionTest
+ {
+ protected const string DELETION_TEST_QUEUE = "deletionTestQueue";
+ protected const string DELETION_TEST_TOPIC = "deletionTestTopic";
+ protected const string DELETION_TEST_TEMP_QUEUE = "deletionTestTempQueue";
+ protected const string DELETION_TEST_TEMP_TOPIC = "deletionTestTempTopic";
+
+ public MSMQTempDestinationDeletionTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public override void TestTempDestinationDeletion(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode,
+ [Values(DELETION_TEST_QUEUE, DELETION_TEST_TOPIC, DELETION_TEST_TEMP_QUEUE, DELETION_TEST_TEMP_TOPIC)]
+ string testDestRef)
+ {
+ base.TestTempDestinationDeletion(deliveryMode, testDestRef);
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQTempDestinationTest.cs b/src/test/csharp/MSMQTempDestinationTest.cs
new file mode 100644
index 0000000..de62683
--- /dev/null
+++ b/src/test/csharp/MSMQTempDestinationTest.cs
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ [Ignore("Temporary queues are not supported")]
+ public class MSMQTempDestinationTest : TempDestinationTest
+ {
+ public MSMQTempDestinationTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [TearDown]
+ public override void TearDown()
+ {
+ base.TearDown();
+ }
+
+ [Test]
+ public override void TestTempDestOnlyConsumedByLocalConn()
+ {
+ base.TestTempDestOnlyConsumedByLocalConn();
+ }
+
+ [Test]
+ public override void TestTempQueueHoldsMessagesWithConsumers()
+ {
+ base.TestTempQueueHoldsMessagesWithConsumers();
+ }
+
+ [Test]
+ public override void TestTempQueueHoldsMessagesWithoutConsumers()
+ {
+ base.TestTempQueueHoldsMessagesWithoutConsumers();
+ }
+
+ [Test]
+ public override void TestTmpQueueWorksUnderLoad()
+ {
+ base.TestTmpQueueWorksUnderLoad();
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQTestSupport.cs b/src/test/csharp/MSMQTestSupport.cs
new file mode 100644
index 0000000..13725a8
--- /dev/null
+++ b/src/test/csharp/MSMQTestSupport.cs
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+using System;
+using System.Xml;
+using Apache.NMS.Test;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+using Apache.NMS.MSMQ;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ /// <summary>
+ /// Useful class for test cases support.
+ /// </summary>
+ public class MSMQTestSupport : NMSTestSupport
+ {
+ /// <summary>
+ /// Gets the environment variable name for the configuration file path.
+ /// </summary>
+ /// <returns>Environment variable name</returns>
+ public override string GetConfigEnvVarName()
+ {
+ return "MSMQTESTCONFIGPATH";
+ }
+
+ /// <summary>
+ /// Gets the default name for the configuration filename.
+ /// </summary>
+ /// <returns>Default name of the configuration filename</returns>
+ public override string GetDefaultConfigFileName()
+ {
+ return "msmqprovider-test.config";
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQTextMessageTest.cs b/src/test/csharp/MSMQTextMessageTest.cs
new file mode 100644
index 0000000..dfbd061
--- /dev/null
+++ b/src/test/csharp/MSMQTextMessageTest.cs
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQTextMessageTest : TextMessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public MSMQTextMessageTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendReceiveTextMessage(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendReceiveTextMessage(deliveryMode, DEFAULT_TEST_QUEUE);
+ }
+ }
+}
diff --git a/src/test/csharp/MSMQTransactionTest.cs b/src/test/csharp/MSMQTransactionTest.cs
new file mode 100644
index 0000000..c269d0c
--- /dev/null
+++ b/src/test/csharp/MSMQTransactionTest.cs
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQTransactionTest : TransactionTest
+ {
+ protected static string TRANSACTION_TEST_QUEUE = "transactionTestQueue";
+
+ public MSMQTransactionTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+ [Test]
+ public void TestSendRollback(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendRollback(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestSendSessionClose(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendSessionClose(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestReceiveRollback(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestReceiveRollback(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+
+ [Test]
+ public void TestReceiveTwoThenRollback(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestReceiveTwoThenRollback(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestSendCommitNonTransaction(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestSendCommitNonTransaction(ackMode, deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestReceiveCommitNonTransaction(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestReceiveCommitNonTransaction(ackMode, deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestReceiveRollbackNonTransaction(
+ [Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestReceiveRollbackNonTransaction(ackMode, deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestRedispatchOfRolledbackTx(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestRedispatchOfRolledbackTx(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+
+ [Test]
+ public void TestRedispatchOfUncommittedTx(
+ [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ base.TestRedispatchOfUncommittedTx(deliveryMode, TRANSACTION_TEST_QUEUE);
+ }
+ }
+}
+
+
diff --git a/src/test/csharp/MSMQXmlMessageTest.cs b/src/test/csharp/MSMQXmlMessageTest.cs
new file mode 100644
index 0000000..757e1f9
--- /dev/null
+++ b/src/test/csharp/MSMQXmlMessageTest.cs
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Test;
+using NUnit.Framework;
+
+namespace Apache.NMS.MSMQ.Test
+{
+ [TestFixture]
+ public class MSMQXmlMessageTest : XmlMessageTest
+ {
+ protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";
+
+ public MSMQXmlMessageTest()
+ : base(new MSMQTestSupport())
+ {
+ }
+
+#if NET_3_5 || MONO
+
+ [Test]
+ public void TestSendReceiveXmlMessage_Net35()
+ {
+ base.TestSendReceiveXmlMessage_Net35(DEFAULT_TEST_QUEUE);
+ }
+
+#else
+
+ // Test the obsolete API versions until they are completely removed.
+ [Test]
+ public void SendReceiveXmlMessage()
+ {
+ base.TestSendReceiveXmlMessage(DEFAULT_TEST_QUEUE);
+ }
+
+#endif
+ }
+}
diff --git a/src/test/csharp/MapMessageTest.cs b/src/test/csharp/MapMessageTest.cs
new file mode 100644
index 0000000..f904c97
--- /dev/null
+++ b/src/test/csharp/MapMessageTest.cs
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class MapMessageTest : NMSTest
+ {
+ protected bool a = true;
+ protected byte b = 123;
+ protected char c = 'c';
+ protected short d = 0x1234;
+ protected int e = 0x12345678;
+ protected long f = 0x1234567812345678;
+ protected string g = "Hello World!";
+ protected bool h = false;
+ protected byte i = 0xFF;
+ protected short j = -0x1234;
+ protected int k = -0x12345678;
+ protected long l = -0x1234567812345678;
+ protected float m = 2.1F;
+ protected double n = 2.3;
+ protected byte[] o = {1, 2, 3, 4, 5};
+
+ protected MapMessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveMapMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMapMessage request = session.CreateMapMessage();
+ request.Body["a"] = a;
+ request.Body["b"] = b;
+ request.Body["c"] = c;
+ request.Body["d"] = d;
+ request.Body["e"] = e;
+ request.Body["f"] = f;
+ request.Body["g"] = g;
+ request.Body["h"] = h;
+ request.Body["i"] = i;
+ request.Body["j"] = j;
+ request.Body["k"] = k;
+ request.Body["l"] = l;
+ request.Body["m"] = m;
+ request.Body["n"] = n;
+ request.Body["o"] = o;
+ producer.Send(request);
+
+ IMapMessage message = consumer.Receive(receiveTimeout) as IMapMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Body.Count, message.Body.Count, "Invalid number of message maps.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ Assert.AreEqual(ToHex(f), ToHex(message.Body.GetLong("f")), "map entry: f as hex");
+
+ // use generic API to access entries
+ Assert.AreEqual(a, message.Body["a"], "generic map entry: a");
+ Assert.AreEqual(b, message.Body["b"], "generic map entry: b");
+ Assert.AreEqual(c, message.Body["c"], "generic map entry: c");
+ Assert.AreEqual(d, message.Body["d"], "generic map entry: d");
+ Assert.AreEqual(e, message.Body["e"], "generic map entry: e");
+ Assert.AreEqual(f, message.Body["f"], "generic map entry: f");
+ Assert.AreEqual(g, message.Body["g"], "generic map entry: g");
+ Assert.AreEqual(h, message.Body["h"], "generic map entry: h");
+ Assert.AreEqual(i, message.Body["i"], "generic map entry: i");
+ Assert.AreEqual(j, message.Body["j"], "generic map entry: j");
+ Assert.AreEqual(k, message.Body["k"], "generic map entry: k");
+ Assert.AreEqual(l, message.Body["l"], "generic map entry: l");
+ Assert.AreEqual(m, message.Body["m"], "generic map entry: m");
+ Assert.AreEqual(n, message.Body["n"], "generic map entry: n");
+ Assert.AreEqual(o, message.Body["o"], "generic map entry: o");
+
+ // use type safe APIs
+ Assert.AreEqual(a, message.Body.GetBool("a"), "map entry: a");
+ Assert.AreEqual(b, message.Body.GetByte("b"), "map entry: b");
+ Assert.AreEqual(c, message.Body.GetChar("c"), "map entry: c");
+ Assert.AreEqual(d, message.Body.GetShort("d"), "map entry: d");
+ Assert.AreEqual(e, message.Body.GetInt("e"), "map entry: e");
+ Assert.AreEqual(f, message.Body.GetLong("f"), "map entry: f");
+ Assert.AreEqual(g, message.Body.GetString("g"), "map entry: g");
+ Assert.AreEqual(h, message.Body.GetBool("h"), "map entry: h");
+ Assert.AreEqual(i, message.Body.GetByte("i"), "map entry: i");
+ Assert.AreEqual(j, message.Body.GetShort("j"), "map entry: j");
+ Assert.AreEqual(k, message.Body.GetInt("k"), "map entry: k");
+ Assert.AreEqual(l, message.Body.GetLong("l"), "map entry: l");
+ Assert.AreEqual(m, message.Body.GetFloat("m"), "map entry: m");
+ Assert.AreEqual(n, message.Body.GetDouble("n"), "map entry: n");
+ Assert.AreEqual(o, message.Body.GetBytes("o"), "map entry: o");
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveNestedMapMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ try
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMapMessage request = session.CreateMapMessage();
+ const string textFieldValue = "Nested Map Messages Rule!";
+
+ request.Body.SetString("textField", textFieldValue);
+
+ IDictionary grandChildMap = new Hashtable();
+ grandChildMap["x"] = "abc";
+ grandChildMap["y"] = new ArrayList(new object[] { "a", "b", "c" });
+
+ IDictionary nestedMap = new Hashtable();
+ nestedMap["a"] = "foo";
+ nestedMap["b"] = (int) 23;
+ nestedMap["c"] = (long) 45;
+ nestedMap["d"] = grandChildMap;
+
+ request.Body.SetDictionary("mapField", nestedMap);
+ request.Body.SetList("listField", new ArrayList(new Object[] { "a", "b", "c" }));
+
+ producer.Send(request);
+
+ IMapMessage message = consumer.Receive(receiveTimeout) as IMapMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Body.Count, message.Body.Count, "Invalid number of message maps.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ string textFieldResponse = message.Body.GetString("textField");
+ Assert.AreEqual(textFieldValue, textFieldResponse, "textField does not match.");
+
+ IDictionary nestedMapResponse = message.Body.GetDictionary("mapField");
+ Assert.IsNotNull(nestedMapResponse, "Nested map not returned.");
+ Assert.AreEqual(nestedMap.Count, nestedMapResponse.Count, "nestedMap: Wrong number of elements");
+ Assert.AreEqual("foo", nestedMapResponse["a"], "nestedMap: a");
+ Assert.AreEqual(23, nestedMapResponse["b"], "nestedMap: b");
+ Assert.AreEqual(45, nestedMapResponse["c"], "nestedMap: c");
+
+ IDictionary grandChildMapResponse = nestedMapResponse["d"] as IDictionary;
+ Assert.IsNotNull(grandChildMapResponse, "Grand child map not returned.");
+ Assert.AreEqual(grandChildMap.Count, grandChildMapResponse.Count, "grandChildMap: Wrong number of elements");
+ Assert.AreEqual(grandChildMapResponse["x"], "abc", "grandChildMap: x");
+
+ IList grandChildList = grandChildMapResponse["y"] as IList;
+ Assert.IsNotNull(grandChildList, "Grand child list not returned.");
+ Assert.AreEqual(3, grandChildList.Count, "grandChildList: Wrong number of list elements.");
+ Assert.AreEqual("a", grandChildList[0], "grandChildList: a");
+ Assert.AreEqual("b", grandChildList[1], "grandChildList: b");
+ Assert.AreEqual("c", grandChildList[2], "grandChildList: c");
+
+ IList listFieldResponse = message.Body.GetList("listField");
+ Assert.IsNotNull(listFieldResponse, "Nested list not returned.");
+ Assert.AreEqual(3, listFieldResponse.Count, "listFieldResponse: Wrong number of list elements.");
+ Assert.AreEqual("a", listFieldResponse[0], "listFieldResponse: a");
+ Assert.AreEqual("b", listFieldResponse[1], "listFieldResponse: b");
+ Assert.AreEqual("c", listFieldResponse[2], "listFieldResponse: c");
+ }
+ catch(NotSupportedException)
+ {
+ }
+ catch(NMSException e)
+ {
+ Assert.IsTrue(e.InnerException.GetType() == typeof(NotSupportedException));
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/MessageSelectorTest.cs b/src/test/csharp/MessageSelectorTest.cs
new file mode 100644
index 0000000..413a965
--- /dev/null
+++ b/src/test/csharp/MessageSelectorTest.cs
@@ -0,0 +1,221 @@
+/*
+ * 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.
+ */
+using System;
+using System.Threading;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ //[Category("LongRunning")]
+ public class MessageSelectorTest : NMSTest
+ {
+ private int receivedNonIgnoredMsgCount = 0;
+ private int receivedIgnoredMsgCount = 0;
+ private bool simulateSlowConsumer = false;
+
+ protected MessageSelectorTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestFilterIgnoredMessages(
+ //[Values(SELECTOR_TEST_QUEUE, SELECTOR_TEST_TOPIC)]
+ string testDestRef)
+ {
+ simulateSlowConsumer = false;
+ RunFilterIgnoredMessagesTest(testDestRef);
+ }
+
+ /// <summary>
+ /// A slow consumer will trigger the producer flow control on the broker when the destination is
+ /// a queue. It will also trigger the consumer flow control by slowing down the feed to all of the
+ /// consumers on the queue to only send messages as fast as the slowest consumer can run.
+ /// When sending to a topic, the producer will not be slowed down, and consumers will be allowed
+ /// to run as fast as they can go.
+ /// Since this test can take a long time to run, it is marked as explicit.
+ /// </summary>
+ /// <param name="testDestRef"></param>
+ //[Test]
+ public virtual void TestFilterIgnoredMessagesSlowConsumer(
+ //[Values(SELECTOR_TEST_QUEUE, SELECTOR_TEST_TOPIC)]
+ string testDestRef)
+ {
+ simulateSlowConsumer = true;
+ RunFilterIgnoredMessagesTest(testDestRef);
+ }
+
+ public void RunFilterIgnoredMessagesTest(string testDestRef)
+ {
+ TimeSpan ttl = TimeSpan.FromMinutes(30);
+ const int MaxNumRequests = 100000;
+
+ using(IConnection connection1 = CreateConnection(GetTestClientId()))
+ using(IConnection connection2 = CreateConnection(GetTestClientId()))
+ using(IConnection connection3 = CreateConnection(GetTestClientId()))
+ {
+ connection1.Start();
+ connection2.Start();
+ connection3.Start();
+ using(ISession session1 = connection1.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession session2 = connection2.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ using(ISession session3 = connection3.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination1 = GetClearDestinationByNodeReference(session1, testDestRef);
+ IDestination destination2 = GetClearDestinationByNodeReference(session2, testDestRef);
+ IDestination destination3 = GetClearDestinationByNodeReference(session3, testDestRef);
+
+ using(IMessageProducer producer = session1.CreateProducer(destination1))
+ using(IMessageConsumer consumer1 = session2.CreateConsumer(destination2, "JMSType NOT LIKE '%IGNORE'"))
+ {
+ int numNonIgnoredMsgsSent = 0;
+ int numIgnoredMsgsSent = 0;
+
+ producer.DeliveryMode = MsgDeliveryMode.NonPersistent;
+
+ receivedNonIgnoredMsgCount = 0;
+ receivedIgnoredMsgCount = 0;
+ consumer1.Listener += new MessageListener(OnNonIgnoredMessage);
+ IMessageConsumer consumer2 = null;
+
+ for(int index = 1; index <= MaxNumRequests; index++)
+ {
+ IMessage request = session1.CreateTextMessage(String.Format("Hello World! [{0} of {1}]", index, MaxNumRequests));
+
+ request.NMSTimeToLive = ttl;
+ if(0 == (index % 2))
+ {
+ request.NMSType = "ACTIVE";
+ numNonIgnoredMsgsSent++;
+ }
+ else
+ {
+ request.NMSType = "ACTIVE.IGNORE";
+ numIgnoredMsgsSent++;
+ }
+
+if(index % 200 == 0) Console.WriteLine("{0} Sending message {1}/{2}", DateTime.Now, index, MaxNumRequests);
+ producer.Send(request);
+
+ if(2000 == index)
+ {
+ // Start the second consumer
+ if(destination3.IsTopic)
+ {
+ // Reset the ignored message sent count, since all previous messages
+ // will not have been consumed on a topic.
+ numIgnoredMsgsSent = 0;
+ }
+
+ consumer2 = session3.CreateConsumer(destination3, "JMSType LIKE '%IGNORE'");
+ consumer2.Listener += new MessageListener(OnIgnoredMessage);
+ }
+ }
+
+ // Create a waiting loop that will coordinate the end of the test. It checks
+ // to see that all intended messages were received. It will continue to wait as
+ // long as new messages are being received. If it stops receiving messages before
+ // it receives everything it expects, it will eventually timeout and the test will fail.
+ int waitCount = 0;
+ int lastReceivedINongnoredMsgCount = receivedNonIgnoredMsgCount;
+ int lastReceivedIgnoredMsgCount = receivedIgnoredMsgCount;
+
+ while(receivedNonIgnoredMsgCount < numNonIgnoredMsgsSent
+ || receivedIgnoredMsgCount < numIgnoredMsgsSent)
+ {
+ if(lastReceivedINongnoredMsgCount != receivedNonIgnoredMsgCount
+ || lastReceivedIgnoredMsgCount != receivedIgnoredMsgCount)
+ {
+ // Reset the wait count.
+ waitCount = 0;
+ }
+ else
+ {
+ waitCount++;
+ }
+
+ lastReceivedINongnoredMsgCount = receivedNonIgnoredMsgCount;
+ lastReceivedIgnoredMsgCount = receivedIgnoredMsgCount;
+
+ Assert.IsTrue(waitCount <= 30, String.Format("Timeout waiting for all messages to be delivered. Only {0} of {1} non-ignored messages delivered. Only {2} of {3} ignored messages delivered.",
+ receivedNonIgnoredMsgCount, numNonIgnoredMsgsSent, receivedIgnoredMsgCount, numIgnoredMsgsSent));
+ Thread.Sleep(1000);
+ }
+
+ consumer2.Dispose();
+ }
+ }
+ }
+ }
+
+ protected void OnNonIgnoredMessage(IMessage message)
+ {
+ receivedNonIgnoredMsgCount++;
+ Assert.AreEqual(message.NMSType, "ACTIVE");
+if(receivedNonIgnoredMsgCount % 200 == 0) Console.WriteLine("{0} Received non ignored message {1}", DateTime.Now, receivedNonIgnoredMsgCount);
+ }
+
+ protected void OnIgnoredMessage(IMessage message)
+ {
+ receivedIgnoredMsgCount++;
+ Assert.AreEqual(message.NMSType, "ACTIVE.IGNORE");
+ if(simulateSlowConsumer)
+ {
+ // Simulate a slow consumer It doesn't have to be too slow in a high speed environment
+ // in order to trigger producer flow control.
+ Thread.Sleep(10);
+ }
+if(receivedIgnoredMsgCount % 200 == 0) Console.WriteLine("{0} Received ignored message {1}", DateTime.Now, receivedIgnoredMsgCount);
+ }
+
+ //[Test]
+ public virtual void TestInvalidSelector(
+ //[Values(SELECTOR_TEST_QUEUE)]
+ string testDestRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+
+ string selector = "THIS IS NOT A VALID SELECTOR";
+
+ try
+ {
+ using(IMessageConsumer consumer = session.CreateConsumer(destination, selector))
+ {
+ Assert.Fail("Consumer should have thrown an NotSupportedException");
+ }
+ }
+ catch(InvalidSelectorException ex)
+ {
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail("Wrong Exception Type Thrown: " + ex.GetType().Name);
+ }
+ }
+ }
+ }
+
+
+ }
+}
diff --git a/src/test/csharp/MessageTest.cs b/src/test/csharp/MessageTest.cs
new file mode 100644
index 0000000..6cfe45c
--- /dev/null
+++ b/src/test/csharp/MessageTest.cs
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class MessageTest : NMSTest
+ {
+ protected bool a = true;
+ protected byte b = 123;
+ protected char c = 'c';
+ protected short d = 0x1234;
+ protected int e = 0x12345678;
+ protected long f = 0x1234567812345678;
+ protected string g = "Hello World!";
+ protected bool h = false;
+ protected byte i = 0xFF;
+ protected short j = -0x1234;
+ protected int k = -0x12345678;
+ protected long l = -0x1234567812345678;
+ protected float m = 2.1F;
+ protected double n = 2.3;
+ protected byte[] o = {1, 2, 3, 4, 5};
+
+ protected MessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveMessageProperties(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMessage request = session.CreateMessage();
+ request.Properties["a"] = a;
+ request.Properties["b"] = b;
+ request.Properties["c"] = c;
+ request.Properties["d"] = d;
+ request.Properties["e"] = e;
+ request.Properties["f"] = f;
+ request.Properties["g"] = g;
+ request.Properties["h"] = h;
+ request.Properties["i"] = i;
+ request.Properties["j"] = j;
+ request.Properties["k"] = k;
+ request.Properties["l"] = l;
+ request.Properties["m"] = m;
+ request.Properties["n"] = n;
+
+ try
+ {
+ request.Properties["o"] = o;
+ Assert.Fail("Should not be able to add a Byte[] to the Properties of a Message.");
+ }
+ catch
+ {
+ // Expected
+ }
+
+ try
+ {
+ request.Properties.SetBytes("o", o);
+ Assert.Fail("Should not be able to add a Byte[] to the Properties of a Message.");
+ }
+ catch
+ {
+ // Expected
+ }
+
+ producer.Send(request);
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ Assert.AreEqual(ToHex(f), ToHex(message.Properties.GetLong("f")), "map entry: f as hex");
+
+ // use generic API to access entries
+ // Perform a string only comparison here since some NMS providers are type limited and
+ // may return only a string instance from the generic [] accessor. Each provider should
+ // further test this functionality to determine that the correct type is returned if
+ // it is capable of doing so.
+ Assert.AreEqual(a.ToString(), message.Properties["a"].ToString(), "generic map entry: a");
+ Assert.AreEqual(b.ToString(), message.Properties["b"].ToString(), "generic map entry: b");
+ Assert.AreEqual(c.ToString(), message.Properties["c"].ToString(), "generic map entry: c");
+ Assert.AreEqual(d.ToString(), message.Properties["d"].ToString(), "generic map entry: d");
+ Assert.AreEqual(e.ToString(), message.Properties["e"].ToString(), "generic map entry: e");
+ Assert.AreEqual(f.ToString(), message.Properties["f"].ToString(), "generic map entry: f");
+ Assert.AreEqual(g.ToString(), message.Properties["g"].ToString(), "generic map entry: g");
+ Assert.AreEqual(h.ToString(), message.Properties["h"].ToString(), "generic map entry: h");
+ Assert.AreEqual(i.ToString(), message.Properties["i"].ToString(), "generic map entry: i");
+ Assert.AreEqual(j.ToString(), message.Properties["j"].ToString(), "generic map entry: j");
+ Assert.AreEqual(k.ToString(), message.Properties["k"].ToString(), "generic map entry: k");
+ Assert.AreEqual(l.ToString(), message.Properties["l"].ToString(), "generic map entry: l");
+ Assert.AreEqual(m.ToString(), message.Properties["m"].ToString(), "generic map entry: m");
+ Assert.AreEqual(n.ToString(), message.Properties["n"].ToString(), "generic map entry: n");
+
+ // use type safe APIs
+ Assert.AreEqual(a, message.Properties.GetBool("a"), "map entry: a");
+ Assert.AreEqual(b, message.Properties.GetByte("b"), "map entry: b");
+ Assert.AreEqual(c, message.Properties.GetChar("c"), "map entry: c");
+ Assert.AreEqual(d, message.Properties.GetShort("d"), "map entry: d");
+ Assert.AreEqual(e, message.Properties.GetInt("e"), "map entry: e");
+ Assert.AreEqual(f, message.Properties.GetLong("f"), "map entry: f");
+ Assert.AreEqual(g, message.Properties.GetString("g"), "map entry: g");
+ Assert.AreEqual(h, message.Properties.GetBool("h"), "map entry: h");
+ Assert.AreEqual(i, message.Properties.GetByte("i"), "map entry: i");
+ Assert.AreEqual(j, message.Properties.GetShort("j"), "map entry: j");
+ Assert.AreEqual(k, message.Properties.GetInt("k"), "map entry: k");
+ Assert.AreEqual(l, message.Properties.GetLong("l"), "map entry: l");
+ Assert.AreEqual(m, message.Properties.GetFloat("m"), "map entry: m");
+ Assert.AreEqual(n, message.Properties.GetDouble("n"), "map entry: n");
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/test/csharp/MessageTransformerTest.cs b/src/test/csharp/MessageTransformerTest.cs
new file mode 100644
index 0000000..d954fe7
--- /dev/null
+++ b/src/test/csharp/MessageTransformerTest.cs
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class MessageTransformerTest : NMSTest
+ {
+ private string propertyName = "ADDITIONAL-PROPERTY";
+ private string propertyValue = "ADDITIONAL-PROPERTY-VALUE";
+
+ protected MessageTransformerTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestProducerTransformer(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = session.CreateTemporaryTopic();
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ producer.ProducerTransformer = DoProducerTransform;
+
+ IMessage message = session.CreateMessage();
+
+ message.Properties["Test"] = "Value";
+
+ producer.Send(message);
+
+ message = consumer.Receive(TimeSpan.FromMilliseconds(5000));
+
+ Assert.IsNotNull(message);
+ Assert.IsTrue(message.Properties.Count == 2);
+
+ Assert.AreEqual("Value", message.Properties["Test"]);
+ Assert.AreEqual(propertyValue, message.Properties[propertyName]);
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestConsumerTransformer(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = session.CreateTemporaryTopic();
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+
+ consumer.ConsumerTransformer = DoConsumerTransform;
+
+ IMessage message = session.CreateMessage();
+
+ message.Properties["Test"] = "Value";
+
+ producer.Send(message);
+
+ message = consumer.Receive(TimeSpan.FromMilliseconds(5000));
+
+ Assert.IsNotNull(message);
+ Assert.IsTrue(message.Properties.Count == 2, "Property Count should be 2");
+
+ Assert.AreEqual("Value", message.Properties["Test"], "Property 'Value' was incorrect");
+ Assert.AreEqual(propertyValue, message.Properties[propertyName], "Property not inserted");
+ }
+ }
+ }
+ }
+
+ private IMessage DoProducerTransform(ISession session, IMessageProducer producer, IMessage message)
+ {
+ message.Properties[propertyName] = propertyValue;
+
+ return message;
+ }
+
+ private IMessage DoConsumerTransform(ISession session, IMessageConsumer consumer, IMessage message)
+ {
+ IMessage newMessage = session.CreateMessage();
+
+ MessageTransformation.CopyNMSMessageProperties(message, newMessage);
+
+ newMessage.Properties[propertyName] = propertyValue;
+
+ return newMessage;
+ }
+ }
+}
+
diff --git a/src/test/csharp/NMSPropertyTest.cs b/src/test/csharp/NMSPropertyTest.cs
new file mode 100644
index 0000000..460faa8
--- /dev/null
+++ b/src/test/csharp/NMSPropertyTest.cs
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class NMSPropertyTest : NMSTest
+ {
+ // standard NMS properties
+ protected string expectedText = "Hey this works!";
+ protected string correlationID = "FooBar";
+ protected MsgPriority priority = MsgPriority.Normal;
+ protected String type = "FooType";
+ protected String groupID = "BarGroup";
+ protected int groupSeq = 1;
+
+ protected NMSPropertyTest(NMSTestSupport testSupport)
+ : base (testSupport)
+ {
+ }
+
+ //[Test]
+ public void TestSendReceiveNMSProperties(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.Priority = priority;
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage request = session.CreateTextMessage(expectedText);
+
+ // Set the headers
+ request.NMSCorrelationID = correlationID;
+ request.NMSType = type;
+ request.Properties["NMSXGroupID"] = groupID;
+ request.Properties["NMSXGroupSeq"] = groupSeq;
+
+ producer.Send(request);
+
+ ITextMessage message = consumer.Receive(receiveTimeout) as ITextMessage;
+
+ Assert.IsNotNull(message, "Did not receive an ITextMessage!");
+ Assert.AreEqual(expectedText, message.Text, "Message text does not match.");
+
+ // compare standard NMS headers
+ Assert.AreEqual(correlationID, message.NMSCorrelationID, "NMSCorrelationID does not match");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ Assert.AreEqual(priority, message.NMSPriority, "NMSPriority does not match");
+ Assert.AreEqual(type, message.NMSType, "NMSType does not match");
+ Assert.AreEqual(groupID, message.Properties["NMSXGroupID"], "NMSXGroupID does not match");
+ Assert.AreEqual(groupSeq, message.Properties["NMSXGroupSeq"], "NMSXGroupSeq does not match");
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/NMSTest.cs b/src/test/csharp/NMSTest.cs
new file mode 100644
index 0000000..3fe3fac
--- /dev/null
+++ b/src/test/csharp/NMSTest.cs
@@ -0,0 +1,505 @@
+/*
+ * 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.
+ */
+using System;
+using System.Xml;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ /// <summary>
+ /// Base class for test cases
+ /// </summary>
+ public abstract class NMSTest
+ {
+ protected TimeSpan receiveTimeout = TimeSpan.FromMilliseconds(15000);
+
+ public static string ToHex(long value)
+ {
+ return String.Format("{0:x}", value);
+ }
+
+ #region Constructors and test support
+
+ private NMSTestSupport testSupport;
+
+ static NMSTest()
+ {
+ Apache.NMS.Tracer.Trace = new NMSTracer();
+ }
+
+ protected NMSTest(NMSTestSupport testSupport)
+ {
+ this.testSupport = testSupport;
+ this.testSupport.TestClassType = this.GetType();
+ }
+
+ #endregion
+
+ #region Set up and tear down
+
+ [SetUp]
+ public virtual void SetUp()
+ {
+ this.testSupport.SetUp();
+ }
+
+ [TearDown]
+ public virtual void TearDown()
+ {
+ this.testSupport.TearDown();
+ }
+
+ #endregion
+
+ #region Configuration file
+
+ /// <summary>
+ /// The configuration document.
+ /// </summary>
+ public XmlDocument ConfigurationDocument
+ {
+ get { return this.testSupport.ConfigurationDocument; }
+ }
+
+ /// <summary>
+ /// Loads the configuration file.
+ /// </summary>
+ /// <returns>XmlDocument of the configuration file</returns>
+ protected virtual XmlDocument LoadConfigFile()
+ {
+ return this.testSupport.LoadConfigFile();
+ }
+
+ /// <summary>
+ /// Loads the configuration file.
+ /// </summary>
+ /// <param name="configFilePath">Configuration file path</param>
+ /// <returns>XmlDocument of the configuration file</returns>
+ protected virtual XmlDocument LoadConfigFile(string configFilePath)
+ {
+ return this.testSupport.LoadConfigFile(configFilePath);
+ }
+
+ /// <summary>
+ /// Gets the path of the configuration filename.
+ /// </summary>
+ /// <returns>Path of the configuration filename</returns>
+ protected virtual string GetConfigFilePath()
+ {
+ return this.testSupport.GetConfigFilePath();
+ }
+
+ /// <summary>
+ /// Gets the environment variable name for the configuration file path.
+ /// </summary>
+ /// <returns>Environment variable name</returns>
+ protected virtual string GetConfigEnvVarName()
+ {
+ return this.testSupport.GetConfigEnvVarName();
+ }
+
+ /// <summary>
+ /// Gets the default name for the configuration filename.
+ /// </summary>
+ /// <returns>Default name of the configuration filename</returns>
+ protected virtual string GetDefaultConfigFileName()
+ {
+ return this.testSupport.GetDefaultConfigFileName();
+ }
+
+ /// <summary>
+ /// Gets the value of the "value" attribute of the specified node.
+ /// </summary>
+ /// <param name="parentNode">Parent node</param>
+ /// <param name="nodeName">Node name</param>
+ /// <param name="defaultVaue">Default value</param>
+ /// <returns></returns>
+ protected virtual string GetNodeValueAttribute(XmlElement parentNode,
+ string nodeName, string defaultVaue)
+ {
+ return this.testSupport.GetNodeValueAttribute(parentNode,
+ nodeName, defaultVaue);
+ }
+
+ #endregion
+
+ #region URI node
+
+ /// <summary>
+ /// Gets the URI node for the default configuration.
+ /// </summary>
+ /// <returns>URI node for the default configuration name</returns>
+ public virtual XmlElement GetURINode()
+ {
+ return this.testSupport.GetURINode();
+ }
+
+ /// <summary>
+ /// Gets the URI node for the default configuration.
+ /// </summary>
+ /// <param name="nameTestURI">Name of the default configuration node
+ /// </param>
+ /// <returns>URI node for the default configuration name</returns>
+ public virtual XmlElement GetURINode(string nameTestURI)
+ {
+ return this.testSupport.GetURINode(nameTestURI);
+ }
+
+ /// <summary>
+ /// Gets the name of the default connection configuration to be loaded.
+ /// </summary>
+ /// <returns>Default configuration name</returns>
+ protected virtual string GetNameTestURI()
+ {
+ return this.testSupport.GetNameTestURI();
+ }
+
+ #endregion
+
+ #region Factory
+
+ private NMSConnectionFactory nmsFactory;
+ /// <summary>
+ /// The connection factory interface property.
+ /// </summary>
+ public IConnectionFactory Factory
+ {
+ get { return this.testSupport.Factory; }
+ }
+
+ /// <summary>
+ /// Create the NMS Factory that can create NMS Connections.
+ /// </summary>
+ /// <returns>Connection factory</returns>
+ protected NMSConnectionFactory CreateNMSFactory()
+ {
+ return this.testSupport.CreateNMSFactory();
+ }
+
+ /// <summary>
+ /// Create the NMS Factory that can create NMS Connections. This
+ /// function loads the connection settings from the configuration file.
+ /// </summary>
+ /// <param name="nameTestURI">The named connection configuration.
+ /// </param>
+ /// <returns>Connection factory</returns>
+ protected NMSConnectionFactory CreateNMSFactory(string nameTestURI)
+ {
+ return this.testSupport.CreateNMSFactory(nameTestURI);
+ }
+
+ /// <summary>
+ /// Get the parameters for the ConnectionFactory from the configuration
+ /// file.
+ /// </summary>
+ /// <param name="uriNode">Parent node of the factoryParams node.</param>
+ /// <returns>Object array of parameter objects to be passsed to provider
+ /// factory object. Null if no parameters are specified in
+ /// configuration file.</returns>
+ protected object[] GetFactoryParams(XmlElement uriNode)
+ {
+ return this.testSupport.GetFactoryParams(uriNode);
+ }
+
+ #endregion
+
+ #region Client id and connection
+
+ /// <summary>
+ /// Client id.
+ /// </summary>
+ public string ClientId
+ {
+ get { return this.testSupport.ClientId; }
+ }
+
+ /// <summary>
+ /// Gets a new client id.
+ /// </summary>
+ /// <returns>Client id</returns>
+ public virtual string GetTestClientId()
+ {
+ return this.testSupport.GetTestClientId();
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker.
+ /// </summary>
+ /// <returns>New connection</returns>
+ public virtual IConnection CreateConnection()
+ {
+ return this.testSupport.CreateConnection();
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker.
+ /// </summary>
+ /// <param name="newClientId">Client ID of the new connection.</param>
+ /// <returns>New connection</returns>
+ public virtual IConnection CreateConnection(string newClientId)
+ {
+ return this.testSupport.CreateConnection(newClientId);
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker, and start it.
+ /// </summary>
+ /// <returns>Started connection</returns>
+ public virtual IConnection CreateConnectionAndStart()
+ {
+ return this.testSupport.CreateConnectionAndStart();
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker, and start it.
+ /// </summary>
+ /// <param name="newClientId">Client ID of the new connection.</param>
+ /// <returns>Started connection</returns>
+ public virtual IConnection CreateConnectionAndStart(string newClientId)
+ {
+ return this.testSupport.CreateConnectionAndStart(newClientId);
+ }
+
+ #endregion
+
+ #region Destination
+
+ /// <summary>
+ /// Gets a clear destination by its configuration node reference.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationNodeReference">Configuration node name for
+ /// the destination URI</param>
+ /// <returns>Destination</returns>
+ public virtual IDestination GetClearDestinationByNodeReference(
+ ISession session, string destinationNodeReference)
+ {
+ return this.testSupport.GetClearDestinationByNodeReference(session, destinationNodeReference);
+ }
+
+ /// <summary>
+ /// Gets a clear destination. This will try to delete an existing
+ /// destination and re-create it.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationURI">Destination URI</param>
+ /// <returns>Clear destination</returns>
+ public virtual IDestination GetClearDestination(ISession session,
+ string destinationURI)
+ {
+ return this.testSupport.GetClearDestination(session, destinationURI);
+ }
+
+ /// <summary>
+ /// Gets an existing destination. Don't clear its contents.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationNodeReference">Configuration node name for
+ /// the destination URI</param>
+ /// <returns>Destination</returns>
+ public virtual IDestination GetDestinationByNodeReference(ISession session,
+ string destinationNodeReference)
+ {
+ return this.testSupport.GetDestinationByNodeReference(session, destinationNodeReference);
+ }
+
+ /// <summary>
+ /// Gets a destination URI.
+ /// </summary>
+ /// <param name="destinationNodeReference">Configuration node name for the
+ /// destination URI</param>
+ /// <returns>Destination URI</returns>
+ public virtual string GetDestinationURI(string destinationNodeReference)
+ {
+ return this.testSupport.GetDestinationURI(destinationNodeReference);
+ }
+
+ #endregion
+
+ #region Durable consumer
+
+ /// <summary>
+ /// Register a durable consumer
+ /// </summary>
+ /// <param name="connectionID">Connection ID of the consumer.</param>
+ /// <param name="destination">Destination name to register. Supports
+ /// embedded prefix names.</param>
+ /// <param name="consumerID">Name of the durable consumer.</param>
+ /// <param name="selector">Selector parameters for consumer.</param>
+ /// <param name="noLocal"></param>
+ protected void RegisterDurableConsumer(string connectionID,
+ string destination, string consumerID, string selector, bool noLocal)
+ {
+ using(IConnection connection = CreateConnection(connectionID))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(
+ AcknowledgementMode.DupsOkAcknowledge))
+ {
+ ITopic destinationTopic = (ITopic)SessionUtil.GetDestination(session, destination);
+ Assert.IsNotNull(destinationTopic, "Could not get destination topic.");
+
+ using(IMessageConsumer consumer = session.CreateDurableConsumer(destinationTopic, consumerID, selector, noLocal))
+ {
+ Assert.IsNotNull(consumer, "Could not create durable consumer.");
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Unregister a durable consumer for the given connection ID.
+ /// </summary>
+ /// <param name="connectionID">Connection ID of the consumer.</param>
+ /// <param name="consumerID">Name of the durable consumer.</param>
+ protected void UnregisterDurableConsumer(string connectionID, string consumerID)
+ {
+ using(IConnection connection = CreateConnection(connectionID))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.DupsOkAcknowledge))
+ {
+ session.DeleteDurableConsumer(consumerID);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Send messages
+
+ /// <summary>
+ /// Sends a specified number of text messages to the designated
+ /// destination.
+ /// </summary>
+ /// <param name="destination">Destination.</param>
+ /// <param name="deliveryMode">Delivery mode.</param>
+ /// <param name="count">Number of messages to be sent.</param>
+ public void SendMessages(IDestination destination,
+ MsgDeliveryMode deliveryMode, int count)
+ {
+ IConnection connection = CreateConnection();
+ connection.Start();
+ SendMessages(connection, destination, deliveryMode, count);
+ connection.Close();
+ }
+
+ /// <summary>
+ /// Sends a specified number of text messages to the designated
+ /// destination.
+ /// </summary>
+ /// <param name="connection">Connection.</param>
+ /// <param name="destination">Destination.</param>
+ /// <param name="deliveryMode">Delivery mode.</param>
+ /// <param name="count">Number of messages to be sent.</param>
+ public void SendMessages(IConnection connection,
+ IDestination destination, MsgDeliveryMode deliveryMode, int count)
+ {
+ ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ SendMessages(session, destination, deliveryMode, count);
+ session.Close();
+ }
+
+ /// <summary>
+ /// Sends a specified number of text messages to the designated
+ /// destination.
+ /// </summary>
+ /// <param name="session">Session.</param>
+ /// <param name="destination">Destination.</param>
+ /// <param name="deliveryMode">Delivery mode.</param>
+ /// <param name="count">Number of messages to be sent.</param>
+ public void SendMessages(ISession session, IDestination destination,
+ MsgDeliveryMode deliveryMode, int count)
+ {
+ IMessageProducer producer = session.CreateProducer(destination);
+ producer.DeliveryMode = deliveryMode;
+ for(int i = 0; i < count; i++)
+ {
+ producer.Send(session.CreateTextMessage("" + i));
+ }
+ producer.Close();
+ }
+
+ #endregion
+
+ #region Check messages
+
+ protected void AssertTextMessagesEqual(IMessage[] firstSet, IMessage[] secondSet)
+ {
+ AssertTextMessagesEqual(firstSet, secondSet, "");
+ }
+
+ protected void AssertTextMessagesEqual(IMessage[] firstSet, IMessage[] secondSet, string messsage)
+ {
+ Assert.AreEqual(firstSet.Length, secondSet.Length, "Message count does not match: " + messsage);
+
+ for(int i = 0; i < secondSet.Length; i++)
+ {
+ ITextMessage m1 = firstSet[i] as ITextMessage;
+ ITextMessage m2 = secondSet[i] as ITextMessage;
+
+ AssertTextMessageEqual(m1, m2, "Message " + (i + 1) + " did not match : ");
+ }
+ }
+
+ protected void AssertEquals(ITextMessage m1, ITextMessage m2)
+ {
+ AssertEquals(m1, m2, "");
+ }
+
+ protected void AssertTextMessageEqual(ITextMessage m1, ITextMessage m2, string message)
+ {
+ Assert.IsFalse(m1 == null ^ m2 == null, message + ": expected {" + m1 + "}, but was {" + m2 + "}");
+
+ if(m1 == null)
+ {
+ return;
+ }
+
+ Assert.AreEqual(m1.Text, m2.Text, message);
+ }
+
+ protected void AssertEquals(IMessage m1, IMessage m2)
+ {
+ AssertEquals(m1, m2, "");
+ }
+
+ protected void AssertEquals(IMessage m1, IMessage m2, string message)
+ {
+ Assert.IsFalse(m1 == null ^ m2 == null, message + ": expected {" + m1 + "}, but was {" + m2 + "}");
+
+ if(m1 == null)
+ {
+ return;
+ }
+
+ Assert.IsTrue(m1.GetType() == m2.GetType(), message + ": expected {" + m1 + "}, but was {" + m2 + "}");
+
+ if(m1 is ITextMessage)
+ {
+ AssertTextMessageEqual((ITextMessage) m1, (ITextMessage) m2, message);
+ }
+ else
+ {
+ Assert.AreEqual(m1, m2, message);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/test/csharp/NMSTestSupport.cs b/src/test/csharp/NMSTestSupport.cs
new file mode 100644
index 0000000..31f2e11
--- /dev/null
+++ b/src/test/csharp/NMSTestSupport.cs
@@ -0,0 +1,637 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using System.IO;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Xml;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+using Apache.NMS.MSMQ;
+
+namespace Apache.NMS.Test
+{
+ /// <summary>
+ /// Useful class for test cases support.
+ /// </summary>
+ public class NMSTestSupport
+ {
+ protected TimeSpan receiveTimeout = TimeSpan.FromMilliseconds(15000);
+ protected int testRun;
+ protected int idCounter;
+
+ protected Type testClassType;
+ public Type TestClassType
+ {
+ get { return this.testClassType; }
+ set { this.testClassType = value; }
+ }
+
+ #region Constructors
+
+ public NMSTestSupport()
+ {
+ }
+
+ #endregion
+
+ #region Set up and tear down
+
+ public virtual void SetUp()
+ {
+ this.testRun++;
+ }
+
+ public virtual void TearDown()
+ {
+ }
+
+ #endregion
+
+ #region Configuration file
+
+ private XmlDocument configurationDocument = null;
+ /// <summary>
+ /// The configuration document.
+ /// </summary>
+ public XmlDocument ConfigurationDocument
+ {
+ get
+ {
+ if(this.configurationDocument == null)
+ {
+ this.configurationDocument = LoadConfigFile();
+ Assert.IsTrue(this.configurationDocument != null,
+ "Error loading configuration.");
+ }
+
+ return this.configurationDocument;
+ }
+ }
+
+ /// <summary>
+ /// Loads the configuration file.
+ /// </summary>
+ /// <returns>XmlDocument of the configuration file</returns>
+ public virtual XmlDocument LoadConfigFile()
+ {
+ return LoadConfigFile(GetConfigFilePath());
+ }
+
+ /// <summary>
+ /// Loads the configuration file.
+ /// </summary>
+ /// <param name="configFilePath">Configuration file path</param>
+ /// <returns>XmlDocument of the configuration file</returns>
+ public virtual XmlDocument LoadConfigFile(string configFilePath)
+ {
+ XmlDocument configDoc = new XmlDocument();
+
+ configDoc.Load(configFilePath);
+
+ return configDoc;
+ }
+
+ /// <summary>
+ /// Gets the path of the configuration filename.
+ /// </summary>
+ /// <returns>Path of the configuration filename</returns>
+ public virtual string GetConfigFilePath()
+ {
+ // The full path may be specified by an environment variable
+ string configFilePath = GetEnvVar(GetConfigEnvVarName(), "");
+ bool configFound = (!string.IsNullOrEmpty(configFilePath)
+ && File.Exists(configFilePath));
+
+ // Else it may be found in well known locations
+ if(!configFound)
+ {
+ string[] paths = GetConfigSearchPaths();
+ string configFileName = GetDefaultConfigFileName();
+
+ foreach(string path in paths)
+ {
+ string fullpath = Path.Combine(path, configFileName);
+ Tracer.Debug("\tScanning folder: " + path);
+
+ if(File.Exists(fullpath))
+ {
+ Tracer.Debug("\tAssembly found!");
+ configFilePath = fullpath;
+ configFound = true;
+ break;
+ }
+ }
+ }
+
+ Tracer.Debug("\tConfig file: " + configFilePath);
+ Assert.IsTrue(configFound, "Connection configuration file does not exist.");
+ return configFilePath;
+ }
+
+ /// <summary>
+ /// Gets the environment variable name for the configuration file path.
+ /// </summary>
+ /// <returns>Environment variable name</returns>
+ public virtual string GetConfigEnvVarName()
+ {
+ return "NMSTESTCONFIGPATH";
+ }
+
+ /// <summary>
+ /// Gets the default name for the configuration filename.
+ /// </summary>
+ /// <returns>Default name of the configuration filename</returns>
+ public virtual string GetDefaultConfigFileName()
+ {
+ return "nmsprovider-test.config";
+ }
+
+ /// <summary>
+ /// Gets an array of paths where the configuration file sould be found.
+ /// </summary>
+ /// <returns>Array of paths</returns>
+ private static string[] GetConfigSearchPaths()
+ {
+ ArrayList pathList = new ArrayList();
+
+ // Check the current folder first.
+ pathList.Add("");
+#if !NETCF
+ AppDomain currentDomain = AppDomain.CurrentDomain;
+
+ // Check the folder the assembly is located in.
+ pathList.Add(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
+ if(null != currentDomain.BaseDirectory)
+ {
+ pathList.Add(currentDomain.BaseDirectory);
+ }
+
+ if(null != currentDomain.RelativeSearchPath)
+ {
+ pathList.Add(currentDomain.RelativeSearchPath);
+ }
+#endif
+
+ return (string[]) pathList.ToArray(typeof(string));
+ }
+
+ /// <summary>
+ /// Gets the value of the "value" attribute of the specified node.
+ /// </summary>
+ /// <param name="parentNode">Parent node</param>
+ /// <param name="nodeName">Node name</param>
+ /// <param name="defaultVaue">Default value</param>
+ /// <returns></returns>
+ public string GetNodeValueAttribute(XmlElement parentNode,
+ string nodeName, string defaultVaue)
+ {
+ XmlElement node = (XmlElement)parentNode.SelectSingleNode(nodeName);
+
+ return (node == null ? defaultVaue : node.GetAttribute("value"));
+ }
+
+ #endregion
+
+ #region URI node
+
+ /// <summary>
+ /// Gets the URI node for the default configuration.
+ /// </summary>
+ /// <returns>URI node for the default configuration name</returns>
+ public virtual XmlElement GetURINode()
+ {
+ return GetURINode(GetNameTestURI());
+ }
+
+ /// <summary>
+ /// Gets the URI node for the default configuration.
+ /// </summary>
+ /// <param name="nameTestURI">Name of the default configuration node
+ /// </param>
+ /// <returns>URI node for the default configuration name</returns>
+ public virtual XmlElement GetURINode(string nameTestURI)
+ {
+ return (XmlElement)ConfigurationDocument.SelectSingleNode(
+ String.Format("/configuration/{0}", nameTestURI));
+ }
+
+ /// <summary>
+ /// Gets the name of the default connection configuration to be loaded.
+ /// </summary>
+ /// <returns>Default configuration name</returns>
+ public virtual string GetNameTestURI()
+ {
+ return "testURI";
+ }
+
+ #endregion
+
+ #region Factory
+
+ private NMSConnectionFactory nmsFactory;
+ /// <summary>
+ /// The connection factory interface property.
+ /// </summary>
+ public IConnectionFactory Factory
+ {
+ get
+ {
+ if(this.nmsFactory == null)
+ {
+ this.nmsFactory = CreateNMSFactory();
+
+ Assert.IsNotNull(this.nmsFactory, "Error creating factory.");
+ }
+
+ return this.nmsFactory.ConnectionFactory;
+ }
+ }
+
+ /// <summary>
+ /// Create the NMS Factory that can create NMS Connections.
+ /// </summary>
+ /// <returns>Connection factory</returns>
+ public NMSConnectionFactory CreateNMSFactory()
+ {
+ return CreateNMSFactory(GetNameTestURI());
+ }
+
+ /// <summary>
+ /// Create the NMS Factory that can create NMS Connections. This
+ /// function loads the connection settings from the configuration file.
+ /// </summary>
+ /// <param name="nameTestURI">The named connection configuration.
+ /// </param>
+ /// <returns>Connection factory</returns>
+ public NMSConnectionFactory CreateNMSFactory(string nameTestURI)
+ {
+ XmlElement uriNode = GetURINode(nameTestURI);
+
+ Uri brokerUri = null;
+ object[] factoryParams = null;
+ if(uriNode != null)
+ {
+ // Replace any environment variables embedded inside the string.
+ brokerUri = new Uri(uriNode.GetAttribute("value"));
+ factoryParams = GetFactoryParams(uriNode);
+ cnxClientId = GetNodeValueAttribute(uriNode, "cnxClientId", "NMSTestClientId");
+ cnxUserName = GetNodeValueAttribute(uriNode, "cnxUserName", null);
+ cnxPassWord = GetNodeValueAttribute(uriNode, "cnxPassWord", null);
+ }
+
+ if(factoryParams == null)
+ {
+ this.nmsFactory = new Apache.NMS.NMSConnectionFactory(brokerUri);
+ }
+ else
+ {
+ this.nmsFactory = new Apache.NMS.NMSConnectionFactory(brokerUri, factoryParams);
+ }
+
+ return this.nmsFactory;
+ }
+
+ /// <summary>
+ /// Get the parameters for the ConnectionFactory from the configuration
+ /// file.
+ /// </summary>
+ /// <param name="uriNode">Parent node of the factoryParams node.</param>
+ /// <returns>Object array of parameter objects to be passsed to provider
+ /// factory object. Null if no parameters are specified in
+ /// configuration file.</returns>
+ public object[] GetFactoryParams(XmlElement uriNode)
+ {
+ ArrayList factoryParams = new ArrayList();
+ XmlElement factoryParamsNode = (XmlElement)uriNode.SelectSingleNode("factoryParams");
+
+ if(factoryParamsNode != null)
+ {
+ XmlNodeList nodeList = factoryParamsNode.SelectNodes("param");
+
+ if(nodeList != null)
+ {
+ foreach(XmlElement paramNode in nodeList)
+ {
+ string paramType = paramNode.GetAttribute("type");
+ string paramValue = paramNode.GetAttribute("value");
+
+ switch(paramType)
+ {
+ case "string":
+ factoryParams.Add(paramValue);
+ break;
+
+ case "int":
+ factoryParams.Add(int.Parse(paramValue));
+ break;
+
+ // TODO: Add more parameter types
+ }
+ }
+ }
+ }
+
+ if(factoryParams.Count > 0)
+ {
+ return factoryParams.ToArray();
+ }
+
+ return null;
+ }
+
+ #endregion
+
+ #region Environment variables
+
+ /// <summary>
+ /// Get environment variable value.
+ /// </summary>
+ /// <param name="varName"></param>
+ /// <param name="defaultValue"></param>
+ /// <returns></returns>
+ public static string GetEnvVar(string varName, string defaultValue)
+ {
+#if (PocketPC||NETCF||NETCF_2_0)
+ string varValue = null;
+#else
+ string varValue = Environment.GetEnvironmentVariable(varName);
+#endif
+ if(null == varValue)
+ {
+ varValue = defaultValue;
+ }
+
+ return varValue;
+ }
+
+ #endregion
+
+ #region Client id and connection
+
+ protected string cnxClientId;
+ /// <summary>
+ /// Client id.
+ /// </summary>
+ public string ClientId
+ {
+ get { return this.cnxClientId; }
+ }
+
+ /// <summary>
+ /// Gets a new client id.
+ /// </summary>
+ /// <returns>Client id</returns>
+ public virtual string GetTestClientId()
+ {
+ System.Text.StringBuilder id = new System.Text.StringBuilder();
+
+ id.Append("ID:");
+ id.Append(this.GetType().Name);
+ id.Append(":");
+ id.Append(this.testRun);
+ id.Append(":");
+ id.Append(++idCounter);
+
+ return id.ToString();
+ }
+
+ protected string cnxUserName;
+ /// <summary>
+ /// User name.
+ /// </summary>
+ public string UserName
+ {
+ get { return this.cnxUserName; }
+ }
+
+ protected string cnxPassWord;
+ /// <summary>
+ /// User pass word.
+ /// </summary>
+ public string PassWord
+ {
+ get { return this.cnxPassWord; }
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker.
+ /// </summary>
+ /// <returns>New connection</returns>
+ public virtual IConnection CreateConnection()
+ {
+ return CreateConnection(null);
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker.
+ /// </summary>
+ /// <param name="newClientId">Client ID of the new connection.</param>
+ /// <returns>New connection</returns>
+ public virtual IConnection CreateConnection(string newClientId)
+ {
+ IConnection newConnection;
+
+ if(this.cnxUserName == null)
+ {
+ newConnection = Factory.CreateConnection();
+ }
+ else
+ {
+ newConnection = Factory.CreateConnection(cnxUserName, cnxPassWord);
+ }
+
+ Assert.IsNotNull(newConnection, "Connection not created");
+
+ if(newClientId != null)
+ {
+ newConnection.ClientId = newClientId;
+ }
+
+ return newConnection;
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker, and start it.
+ /// </summary>
+ /// <returns>Started connection</returns>
+ public virtual IConnection CreateConnectionAndStart()
+ {
+ return CreateConnectionAndStart(null);
+ }
+
+ /// <summary>
+ /// Create a new connection to the broker, and start it.
+ /// </summary>
+ /// <param name="newClientId">Client ID of the new connection.</param>
+ /// <returns>Started connection</returns>
+ public virtual IConnection CreateConnectionAndStart(string newClientId)
+ {
+ IConnection newConnection = CreateConnection(newClientId);
+ newConnection.Start();
+ return newConnection;
+ }
+
+ #endregion
+
+ #region Destination
+
+ /// <summary>
+ /// Gets a clear destination by its configuration node reference.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationNodeReference">Configuration node name for
+ /// the destination URI</param>
+ /// <returns>Destination</returns>
+ public virtual IDestination GetClearDestinationByNodeReference(
+ ISession session, string destinationNodeReference)
+ {
+ string uri = GetDestinationURI(destinationNodeReference);
+ return GetClearDestination(session, uri);
+ }
+
+ /// <summary>
+ /// Gets a clear destination. This will try to delete an existing
+ /// destination and re-create it.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationURI">Destination URI</param>
+ /// <returns>Clear destination</returns>
+ public virtual IDestination GetClearDestination(ISession session,
+ string destinationURI)
+ {
+ IDestination destination;
+
+ try
+ {
+ DeleteDestination(session, destinationURI);
+ destination = CreateDestination(session, destinationURI);
+ }
+ catch(Exception)
+ {
+ // Can't delete it, so lets try and purge it.
+ destination = SessionUtil.GetDestination(session, destinationURI);
+
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ while(consumer.Receive(TimeSpan.FromMilliseconds(750)) != null)
+ {
+ }
+ }
+ }
+
+ return destination;
+ }
+
+ /// <summary>
+ /// Deletes a destination.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationURI">Destination URI</param>
+ protected virtual void DeleteDestination(ISession session,
+ string destinationURI)
+ {
+ // Only delete the destination if it can be recreated
+ // SessionUtil.DeleteDestination(session, destinationURI, DestinationType.Queue)
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Creates a destination.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationURI">Destination URI</param>
+ protected virtual IDestination CreateDestination(ISession session,
+ string destinationURI)
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Gets an existing destination. Don't clear its contents.
+ /// </summary>
+ /// <param name="session">Session</param>
+ /// <param name="destinationNodeReference">Configuration node name for
+ /// the destination URI</param>
+ /// <returns>Destination</returns>
+ public virtual IDestination GetDestinationByNodeReference(
+ ISession session, string destinationNodeReference)
+ {
+ string uri = GetDestinationURI(destinationNodeReference);
+
+ IDestination destination = SessionUtil.GetDestination(session, uri);
+
+ return destination;
+ }
+
+ /// <summary>
+ /// Gets a destination URI.
+ /// </summary>
+ /// <param name="destinationNodeReference">Configuration node name for
+ /// the destination URI</param>
+ /// <returns>Destination URI</returns>
+ public virtual string GetDestinationURI(
+ string destinationNodeReference)
+ {
+ string uri = null;
+
+ if(!string.IsNullOrEmpty(destinationNodeReference))
+ {
+ XmlElement uriNode = GetURINode();
+
+ if(uriNode != null)
+ {
+ uri = GetNodeValueAttribute(uriNode, destinationNodeReference, null);
+ }
+ }
+
+ if(string.IsNullOrEmpty(uri))
+ {
+ uri = NewDestinationURI(destinationNodeReference);
+ }
+
+ return uri;
+ }
+
+ /// <summary>
+ /// Gets a new destination URI for the specified URI scheme (valid
+ /// values are "queue://", "topic://", "temp-queue://" and
+ /// "temp-topic://").
+ /// </summary>
+ /// <param name="destinationTypeScheme">Destination type</param>
+ /// <returns>Destination URI</returns>
+ public virtual string NewDestinationURI(string destinationTypeScheme)
+ {
+ if(destinationTypeScheme != "queue://" &&
+ destinationTypeScheme != "topic://" &&
+ destinationTypeScheme != "temp-queue://" &&
+ destinationTypeScheme != "temp-topic://")
+ {
+ throw new ArgumentException(
+ string.Format("Invalid destination type scheme \"{0}\".",
+ destinationTypeScheme));
+ }
+
+ return destinationTypeScheme + "TEST." + this.TestClassType.Name
+ + "." + Guid.NewGuid().ToString();
+ }
+
+ #endregion
+ }
+}
diff --git a/src/test/csharp/NMSTracer.cs b/src/test/csharp/NMSTracer.cs
new file mode 100644
index 0000000..448e232
--- /dev/null
+++ b/src/test/csharp/NMSTracer.cs
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#define TRACE // Force tracing to be enabled for this class
+
+namespace Apache.NMS.Test
+{
+ public class NMSTracer : Apache.NMS.ITrace
+ {
+ #region ITrace Members
+ public void Debug(string message)
+ {
+#if !NETCF
+ System.Diagnostics.Trace.WriteLine(string.Format("DEBUG: {0}", message));
+#endif
+ }
+
+ public void Error(string message)
+ {
+#if !NETCF
+ System.Diagnostics.Trace.WriteLine(string.Format("ERROR: {0}", message));
+#endif
+ }
+
+ public void Fatal(string message)
+ {
+#if !NETCF
+ System.Diagnostics.Trace.WriteLine(string.Format("FATAL: {0}", message));
+#endif
+ }
+
+ public void Info(string message)
+ {
+#if !NETCF
+ System.Diagnostics.Trace.WriteLine(string.Format("INFO: {0}", message));
+#endif
+ }
+
+ public void Warn(string message)
+ {
+#if !NETCF
+ System.Diagnostics.Trace.WriteLine(string.Format("WARN: {0}", message));
+#endif
+ }
+
+ public bool IsDebugEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsErrorEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsFatalEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsInfoEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsWarnEnabled
+ {
+ get { return true; }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/test/csharp/PrimitiveMapTest.cs b/src/test/csharp/PrimitiveMapTest.cs
new file mode 100644
index 0000000..3e20892
--- /dev/null
+++ b/src/test/csharp/PrimitiveMapTest.cs
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ [TestFixture]
+ public class PrimitiveMapTest
+ {
+
+ bool a = true;
+ byte b = 123;
+ char c = 'c';
+ short d = 0x1234;
+ int e = 0x12345678;
+ long f = 0x1234567812345678;
+ string g = "Hello World!";
+ bool h = false;
+ byte i = 0xFF;
+ short j = -0x1234;
+ int k = -0x12345678;
+ long l = -0x1234567812345678;
+ IList m = CreateList();
+ IDictionary n = CreateDictionary();
+
+ [Test]
+ public void TestNotMarshalled()
+ {
+ PrimitiveMap map = CreatePrimitiveMap();
+ AssertPrimitiveMap(map);
+ }
+
+ [Test]
+ public void TestMarshalled()
+ {
+ PrimitiveMap map = CreatePrimitiveMap();
+ byte[] data = map.Marshal();
+ map = PrimitiveMap.Unmarshal(data);
+ AssertPrimitiveMap(map);
+ }
+
+ [Test]
+ public void TestMarshalledWithBigString()
+ {
+ PrimitiveMap map = CreatePrimitiveMap();
+ String test = new String('a', 65538);
+ map.SetString("BIG_STRING", test);
+ byte[] data = map.Marshal();
+ map = PrimitiveMap.Unmarshal(data);
+ AssertPrimitiveMap(map);
+ Assert.AreEqual(test, map.GetString("BIG_STRING"));
+ }
+
+ protected PrimitiveMap CreatePrimitiveMap()
+ {
+ PrimitiveMap map = new PrimitiveMap();
+
+ map["a"] = a;
+ map["b"] = b;
+ map["c"] = c;
+ map["d"] = d;
+ map["e"] = e;
+ map["f"] = f;
+ map["g"] = g;
+ map["h"] = h;
+ map["i"] = i;
+ map["j"] = j;
+ map["k"] = k;
+ map["l"] = l;
+ map["m"] = m;
+ map["n"] = n;
+
+ return map;
+ }
+
+ protected void AssertPrimitiveMap(PrimitiveMap map)
+ {
+ // use generic API to access entries
+ Assert.AreEqual(a, map["a"], "generic map entry: a");
+ Assert.AreEqual(b, map["b"], "generic map entry: b");
+ Assert.AreEqual(c, map["c"], "generic map entry: c");
+ Assert.AreEqual(d, map["d"], "generic map entry: d");
+ Assert.AreEqual(e, map["e"], "generic map entry: e");
+ Assert.AreEqual(f, map["f"], "generic map entry: f");
+ Assert.AreEqual(g, map["g"], "generic map entry: g");
+ Assert.AreEqual(h, map["h"], "generic map entry: h");
+ Assert.AreEqual(i, map["i"], "generic map entry: i");
+ Assert.AreEqual(j, map["j"], "generic map entry: j");
+ Assert.AreEqual(k, map["k"], "generic map entry: k");
+ Assert.AreEqual(l, map["l"], "generic map entry: l");
+ //Assert.AreEqual(m, map["m"], "generic map entry: m");
+ //Assert.AreEqual(n, map["n"], "generic map entry: n");
+
+ // use type safe APIs
+ Assert.AreEqual(a, map.GetBool("a"), "map entry: a");
+ Assert.AreEqual(b, map.GetByte("b"), "map entry: b");
+ Assert.AreEqual(c, map.GetChar("c"), "map entry: c");
+ Assert.AreEqual(d, map.GetShort("d"), "map entry: d");
+ Assert.AreEqual(e, map.GetInt("e"), "map entry: e");
+ Assert.AreEqual(f, map.GetLong("f"), "map entry: f");
+ Assert.AreEqual(g, map.GetString("g"), "map entry: g");
+ Assert.AreEqual(h, map.GetBool("h"), "map entry: h");
+ Assert.AreEqual(i, map.GetByte("i"), "map entry: i");
+ Assert.AreEqual(j, map.GetShort("j"), "map entry: j");
+ Assert.AreEqual(k, map.GetInt("k"), "map entry: k");
+ Assert.AreEqual(l, map.GetLong("l"), "map entry: l");
+ //Assert.AreEqual(m, map.GetList("m"), "map entry: m");
+ //Assert.AreEqual(n, map.GetDictionary("n"), "map entry: n");
+
+ IList list = map.GetList("m");
+ Assert.AreEqual(2, list.Count, "list size");
+ Assert.IsTrue(list.Contains("Item1"));
+ Assert.IsTrue(list.Contains("Item2"));
+
+ IDictionary dictionary = map.GetDictionary("n");
+ Assert.AreEqual(5, dictionary.Count, "dictionary size");
+
+ IDictionary childMap = (IDictionary) dictionary["childMap"];
+ Assert.IsNotNull(childMap);
+ Assert.AreEqual("childMap", childMap["name"], "childMap[name]");
+
+ IList childList = (IList) dictionary["childList"];
+ Assert.IsNotNull(childList);
+ Assert.IsTrue(childList.Contains("childListElement1"));
+ }
+
+ protected static IList CreateList()
+ {
+ ArrayList answer = new ArrayList();
+ answer.Add("Item1");
+ answer.Add("Item2");
+ return answer;
+ }
+
+ protected static IDictionary CreateDictionary()
+ {
+ Hashtable answer = new Hashtable();
+ answer.Add("Name", "James");
+ answer.Add("Location", "London");
+ answer.Add("Company", "LogicBlaze");
+
+ Hashtable childMap = new Hashtable();
+ childMap.Add("name", "childMap");
+ answer.Add("childMap", childMap);
+
+ ArrayList childList = new ArrayList();
+ childList.Add("childListElement1");
+ answer.Add("childList", childList);
+ return answer;
+ }
+ }
+}
diff --git a/src/test/csharp/ProducerTest.cs b/src/test/csharp/ProducerTest.cs
new file mode 100644
index 0000000..ffe058e
--- /dev/null
+++ b/src/test/csharp/ProducerTest.cs
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+using System;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class ProducerTest : NMSTest
+ {
+ protected ProducerTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestProducerSendToNullDestinationWithoutDefault()
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ IMessageProducer producer = session.CreateProducer(null);
+
+ try
+ {
+ producer.Send(null, session.CreateTextMessage("Message"));
+ Assert.Fail("Producer should have thrown an NotSupportedException");
+ }
+ catch(NotSupportedException)
+ {
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail("Wrong Exception Type Thrown: " + ex.GetType().Name);
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestProducerSendToNullDestinationWithDefault(string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination unusedDest = GetClearDestinationByNodeReference(session, testDestRef);
+
+ IMessageProducer producer = session.CreateProducer(unusedDest);
+
+ try
+ {
+ producer.Send(null, session.CreateTextMessage("Message"));
+ Assert.Fail("Producer should have thrown an InvalidDestinationException");
+ }
+ catch(InvalidDestinationException)
+ {
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail("Wrong Exception Type Thrown: " + ex.GetType().Name);
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestProducerSendToNonDefaultDestination(string unusedTestDestRef, string usedTestDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession())
+ {
+ IDestination unusedDest = GetClearDestinationByNodeReference(session, unusedTestDestRef);
+ IDestination usedDest = GetClearDestinationByNodeReference(session, usedTestDestRef);
+
+ IMessageProducer producer = session.CreateProducer(unusedDest);
+
+ try
+ {
+ producer.Send(usedDest, session.CreateTextMessage("Message"));
+ Assert.Fail("Producer should have thrown an NotSupportedException");
+ }
+ catch(NotSupportedException)
+ {
+ }
+ catch(Exception ex)
+ {
+ Assert.Fail("Wrong Exception Type Thrown: " + ex.GetType().Name);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/RedeliveryPolicyTest.cs b/src/test/csharp/RedeliveryPolicyTest.cs
new file mode 100644
index 0000000..0ee9f54
--- /dev/null
+++ b/src/test/csharp/RedeliveryPolicyTest.cs
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+using Apache.NMS.Policies;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ [TestFixture]
+ public class RedeliveryPolicyTest
+ {
+ [Test]
+ public void Executes_redelivery_policy_with_backoff_enabled_correctly()
+ {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+
+ policy.BackOffMultiplier = 2;
+ policy.InitialRedeliveryDelay = 5;
+ policy.UseExponentialBackOff = true;
+
+ // simulate a retry of 10 times
+ Assert.IsTrue(policy.RedeliveryDelay(0) == 0, "redelivery delay not 5 is " + policy.RedeliveryDelay(0));
+ Assert.IsTrue(policy.RedeliveryDelay(1) == 5, "redelivery delay not 10 is " + policy.RedeliveryDelay(1));
+ Assert.IsTrue(policy.RedeliveryDelay(2) == 10, "redelivery delay not 20 is " + policy.RedeliveryDelay(2));
+ Assert.IsTrue(policy.RedeliveryDelay(3) == 20, "redelivery delay not 40 is " + policy.RedeliveryDelay(3));
+ Assert.IsTrue(policy.RedeliveryDelay(4) == 40, "redelivery delay not 80 is " + policy.RedeliveryDelay(4));
+ Assert.IsTrue(policy.RedeliveryDelay(5) == 80, "redelivery delay not 160 is " + policy.RedeliveryDelay(5));
+ Assert.IsTrue(policy.RedeliveryDelay(6) == 160, "redelivery delay not 320 is " + policy.RedeliveryDelay(6));
+ Assert.IsTrue(policy.RedeliveryDelay(7) == 320, "redelivery delay not 640 is " + policy.RedeliveryDelay(7));
+ Assert.IsTrue(policy.RedeliveryDelay(8) == 640, "redelivery delay not 1280 is " + policy.RedeliveryDelay(8));
+ Assert.IsTrue(policy.RedeliveryDelay(9) == 1280, "redelivery delay not 2560 is " + policy.RedeliveryDelay(9));
+ }
+
+ [Test]
+ public void Executes_redelivery_policy_with_backoff_of_3_enabled_correctly()
+ {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+
+ policy.BackOffMultiplier = 3;
+ policy.InitialRedeliveryDelay = 3;
+ policy.UseExponentialBackOff = true;
+
+ // simulate a retry of 10 times
+ Assert.IsTrue(policy.RedeliveryDelay(0) == 0, "redelivery delay not 5 is " + policy.RedeliveryDelay(0));
+ Assert.IsTrue(policy.RedeliveryDelay(1) == 3, "redelivery delay not 10 is " + policy.RedeliveryDelay(1));
+ Assert.IsTrue(policy.RedeliveryDelay(2) == 9, "redelivery delay not 20 is " + policy.RedeliveryDelay(2));
+ Assert.IsTrue(policy.RedeliveryDelay(3) == 27, "redelivery delay not 40 is " + policy.RedeliveryDelay(3));
+ Assert.IsTrue(policy.RedeliveryDelay(4) == 81, "redelivery delay not 80 is " + policy.RedeliveryDelay(4));
+ Assert.IsTrue(policy.RedeliveryDelay(5) == 243, "redelivery delay not 160 is " + policy.RedeliveryDelay(5));
+ Assert.IsTrue(policy.RedeliveryDelay(6) == 729, "redelivery delay not 320 is " + policy.RedeliveryDelay(6));
+ Assert.IsTrue(policy.RedeliveryDelay(7) == 2187, "redelivery delay not 640 is " + policy.RedeliveryDelay(7));
+ Assert.IsTrue(policy.RedeliveryDelay(8) == 6561, "redelivery delay not 1280 is " + policy.RedeliveryDelay(8));
+ Assert.IsTrue(policy.RedeliveryDelay(9) == 19683, "redelivery delay not 2560 is " + policy.RedeliveryDelay(9));
+ }
+
+ [Test]
+ public void Executes_redelivery_policy_without_backoff_enabled_correctly()
+ {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+
+ policy.InitialRedeliveryDelay = 5;
+
+ // simulate a retry of 10 times
+ Assert.IsTrue(policy.RedeliveryDelay(0) == 0, "redelivery delay not 0 is " + policy.RedeliveryDelay(0));
+ Assert.IsTrue(policy.RedeliveryDelay(1) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(1));
+ Assert.IsTrue(policy.RedeliveryDelay(2) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(2));
+ Assert.IsTrue(policy.RedeliveryDelay(3) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(3));
+ Assert.IsTrue(policy.RedeliveryDelay(4) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(4));
+ Assert.IsTrue(policy.RedeliveryDelay(5) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(5));
+ Assert.IsTrue(policy.RedeliveryDelay(6) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(6));
+ Assert.IsTrue(policy.RedeliveryDelay(7) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(7));
+ Assert.IsTrue(policy.RedeliveryDelay(8) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(8));
+ Assert.IsTrue(policy.RedeliveryDelay(9) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(9));
+ }
+
+ [Test]
+ public void Should_get_collision_percent_correctly()
+ {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+
+ policy.CollisionAvoidancePercent = 45;
+
+ Assert.IsTrue(policy.CollisionAvoidancePercent == 45);
+ }
+
+ [Test]
+ public void Executes_redelivery_policy_with_collision_enabled_correctly()
+ {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+
+ policy.BackOffMultiplier = 2;
+ policy.InitialRedeliveryDelay = 5;
+ policy.UseExponentialBackOff = true;
+ policy.UseCollisionAvoidance = true;
+ policy.CollisionAvoidancePercent = 10;
+
+ // simulate a retry of 10 times
+ int delay = policy.RedeliveryDelay(0);
+ Assert.IsTrue(delay == 0, "not zero is " + policy.RedeliveryDelay(0));
+ delay = policy.RedeliveryDelay(1);
+ Assert.IsTrue(delay >= 4.5 && delay <= 5.5, "not delay >= 4.5 && delay <= 5.5 is " + policy.RedeliveryDelay(1));
+ delay = policy.RedeliveryDelay(2);
+ Assert.IsTrue(delay >= 9 && delay <= 11, "not delay >= 9 && delay <= 11 is " + policy.RedeliveryDelay(2));
+ delay = policy.RedeliveryDelay(3);
+ Assert.IsTrue(delay >= 18 && delay <= 22, "not delay >= 18 && delay <= 22 is " + policy.RedeliveryDelay(3));
+ delay = policy.RedeliveryDelay(4);
+ Assert.IsTrue(delay >= 36 && delay <= 44, "not delay >= 36 && delay <= 44 is " + policy.RedeliveryDelay(4));
+ delay = policy.RedeliveryDelay(5);
+ Assert.IsTrue(delay >= 72 && delay <= 88, "not delay >= 72 && delay <= 88 is " + policy.RedeliveryDelay(5));
+ delay = policy.RedeliveryDelay(6);
+ Assert.IsTrue(delay >= 144 && delay <= 176, "not delay >= 144 && delay <= 176 is " + policy.RedeliveryDelay(6));
+ delay = policy.RedeliveryDelay(7);
+ Assert.IsTrue(delay >= 288 && delay <= 352, "not delay >= 288 && delay <= 352 is " + policy.RedeliveryDelay(7));
+ delay = policy.RedeliveryDelay(8);
+ Assert.IsTrue(delay >= 576 && delay <= 704, "not delay >= 576 && delay <= 704 is " + policy.RedeliveryDelay(8));
+ delay = policy.RedeliveryDelay(9);
+ Assert.IsTrue(delay >= 1152 && delay <= 1408, "not delay >= 1152 && delay <= 1408 is " + policy.RedeliveryDelay(9));
+ delay = policy.RedeliveryDelay(10);
+ Assert.IsTrue(delay >= 2304 && delay <= 2816, "not delay >= 2304 && delay <= 2816 is " + policy.RedeliveryDelay(10));
+ }
+ }
+}
diff --git a/src/test/csharp/RequestResponseTest.cs b/src/test/csharp/RequestResponseTest.cs
new file mode 100644
index 0000000..d6f0489
--- /dev/null
+++ b/src/test/csharp/RequestResponseTest.cs
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class RequestResponseTest : NMSTest
+ {
+ protected RequestResponseTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ //[Category("RequestResponse")]
+ public virtual void TestRequestResponseMessaging(string testDestRef, string testRespDestRef)
+ {
+ using(IConnection connection = CreateConnection())
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ IDestination replyTo = GetClearDestinationByNodeReference(session, testRespDestRef);
+
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ IMessage request = session.CreateMessage();
+
+ request.NMSReplyTo = replyTo;
+
+ producer.Send(request);
+
+ request = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+ Assert.IsNotNull(request);
+ Assert.IsNotNull(request.NMSReplyTo);
+
+ using(IMessageProducer responder = session.CreateProducer(request.NMSReplyTo))
+ {
+ IMessage response = session.CreateTextMessage("RESPONSE");
+ responder.Send(response);
+ }
+ }
+
+ using(IMessageConsumer consumer = session.CreateConsumer(replyTo))
+ {
+ ITextMessage response = consumer.Receive(TimeSpan.FromMilliseconds(3000)) as ITextMessage;
+ Assert.IsNotNull(response);
+ Assert.AreEqual("RESPONSE", response.Text);
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/test/csharp/StreamMessageTest.cs b/src/test/csharp/StreamMessageTest.cs
new file mode 100644
index 0000000..be690a4
--- /dev/null
+++ b/src/test/csharp/StreamMessageTest.cs
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class StreamMessageTest : NMSTest
+ {
+ protected bool a = true;
+ protected byte b = 123;
+ protected char c = 'c';
+ protected short d = 0x1234;
+ protected int e = 0x12345678;
+ protected long f = 0x1234567812345678;
+ protected string g = "Hello World!";
+ protected bool h = false;
+ protected byte i = 0xFF;
+ protected short j = -0x1234;
+ protected int k = -0x12345678;
+ protected long l = -0x1234567812345678;
+ protected float m = 2.1F;
+ protected double n = 2.3;
+
+ protected StreamMessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveStreamMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IStreamMessage request;
+
+ try
+ {
+ request = session.CreateStreamMessage();
+ }
+ catch(System.NotSupportedException)
+ {
+ return;
+ }
+
+ request.WriteBoolean(a);
+ request.WriteByte(b);
+ request.WriteChar(c);
+ request.WriteInt16(d);
+ request.WriteInt32(e);
+ request.WriteInt64(f);
+ request.WriteString(g);
+ request.WriteBoolean(h);
+ request.WriteByte(i);
+ request.WriteInt16(j);
+ request.WriteInt32(k);
+ request.WriteInt64(l);
+ request.WriteSingle(m);
+ request.WriteDouble(n);
+ producer.Send(request);
+
+ IStreamMessage message = consumer.Receive(receiveTimeout) as IStreamMessage;
+ Assert.IsNotNull(message, "No message returned!");
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+
+ // use generic API to access entries
+ Assert.AreEqual(a, message.ReadBoolean(), "Stream Boolean Value: a");
+ Assert.AreEqual(b, message.ReadByte(), "Stream Byte Value: b");
+ Assert.AreEqual(c, message.ReadChar(), "Stream Char Value: c");
+ Assert.AreEqual(d, message.ReadInt16(), "Stream Int16 Value: d");
+ Assert.AreEqual(e, message.ReadInt32(), "Stream Int32 Value: e");
+ Assert.AreEqual(f, message.ReadInt64(), "Stream Int64 Value: f");
+ Assert.AreEqual(g, message.ReadString(), "Stream String Value: g");
+ Assert.AreEqual(h, message.ReadBoolean(), "Stream Boolean Value: h");
+ Assert.AreEqual(i, message.ReadByte(), "Stream Byte Value: i");
+ Assert.AreEqual(j, message.ReadInt16(), "Stream Int16 Value: j");
+ Assert.AreEqual(k, message.ReadInt32(), "Stream Int32 Value: k");
+ Assert.AreEqual(l, message.ReadInt64(), "Stream Int64 Value: l");
+ Assert.AreEqual(m, message.ReadSingle(), "Stream Single Value: m");
+ Assert.AreEqual(n, message.ReadDouble(), "Stream Double Value: n");
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/TempDestinationDeletionTest.cs b/src/test/csharp/TempDestinationDeletionTest.cs
new file mode 100644
index 0000000..834193e
--- /dev/null
+++ b/src/test/csharp/TempDestinationDeletionTest.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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class TempDestinationDeletionTest : NMSTest
+ {
+ protected TempDestinationDeletionTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestTempDestinationDeletion(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode,
+ //[Values(DELETION_TEST_QUEUE, DELETION_TEST_TOPIC, DELETION_TEST_TEMP_QUEUE, DELETION_TEST_TEMP_TOPIC)]
+ string testDestRef)
+ {
+ using(IConnection connection1 = CreateConnection(GetTestClientId()))
+ {
+ connection1.Start();
+ using(ISession session = connection1.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ const int MaxNumDestinations = 100;
+
+ for(int index = 1; index <= MaxNumDestinations; index++)
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+
+ IMessage request = session.CreateTextMessage("Hello World, Just Passing Through!");
+
+ request.NMSType = "TEMP_MSG";
+ producer.Send(request);
+ IMessage receivedMsg = consumer.Receive(TimeSpan.FromMilliseconds(5000));
+ Assert.IsNotNull(receivedMsg);
+ Assert.AreEqual(receivedMsg.NMSType, "TEMP_MSG");
+
+ // Ensures that Consumer closes out its subscription
+ consumer.Close();
+ }
+
+ try
+ {
+ session.DeleteDestination(destination);
+ }
+ catch(NotSupportedException)
+ {
+ // Might as well not try this again.
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/TempDestinationTest.cs b/src/test/csharp/TempDestinationTest.cs
new file mode 100644
index 0000000..b9a75e4
--- /dev/null
+++ b/src/test/csharp/TempDestinationTest.cs
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+using System;
+using System.Collections;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class TempDestinationTest : NMSTest
+ {
+ private IConnection connection;
+ private IList connections = ArrayList.Synchronized(new ArrayList());
+
+ protected TempDestinationTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+
+ this.connection = CreateConnection();
+ this.connections.Add(connection);
+ }
+
+ //[TearDown]
+ public override void TearDown()
+ {
+ foreach(IConnection conn in this.connections)
+ {
+ try
+ {
+ conn.Close();
+ }
+ catch
+ {
+ }
+ }
+
+ connections.Clear();
+
+ base.TearDown();
+ }
+
+ //[Test]
+ public virtual void TestTempDestOnlyConsumedByLocalConn()
+ {
+ connection.Start();
+
+ ISession tempSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ITemporaryQueue queue = tempSession.CreateTemporaryQueue();
+ IMessageProducer producer = tempSession.CreateProducer(queue);
+ producer.DeliveryMode = (MsgDeliveryMode.NonPersistent);
+ ITextMessage message = tempSession.CreateTextMessage("First");
+ producer.Send(message);
+
+ // temp destination should not be consume when using another connection
+ IConnection otherConnection = CreateConnection();
+ connections.Add(otherConnection);
+ ISession otherSession = otherConnection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ITemporaryQueue otherQueue = otherSession.CreateTemporaryQueue();
+ IMessageConsumer consumer = otherSession.CreateConsumer(otherQueue);
+ IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+ Assert.IsNull(msg);
+
+ // should be able to consume temp destination from the same connection
+ consumer = tempSession.CreateConsumer(queue);
+ msg = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+ Assert.IsNotNull(msg);
+ }
+
+ //[Test]
+ public virtual void TestTempQueueHoldsMessagesWithConsumers()
+ {
+ ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ITemporaryQueue queue = session.CreateTemporaryQueue();
+ IMessageConsumer consumer = session.CreateConsumer(queue);
+ connection.Start();
+
+ IMessageProducer producer = session.CreateProducer(queue);
+ producer.DeliveryMode = (MsgDeliveryMode.NonPersistent);
+ ITextMessage message = session.CreateTextMessage("Hello");
+ producer.Send(message);
+
+ IMessage message2 = consumer.Receive(TimeSpan.FromMilliseconds(1000));
+ Assert.IsNotNull(message2);
+ Assert.IsTrue(message2 is ITextMessage, "Expected message to be a ITextMessage");
+ Assert.IsTrue(((ITextMessage)message2).Text == message.Text, "Expected message to be a '" + message.Text + "'");
+ }
+
+ //[Test]
+ public virtual void TestTempQueueHoldsMessagesWithoutConsumers()
+ {
+ ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ITemporaryQueue queue = session.CreateTemporaryQueue();
+ IMessageProducer producer = session.CreateProducer(queue);
+ producer.DeliveryMode = MsgDeliveryMode.NonPersistent;
+ ITextMessage message = session.CreateTextMessage("Hello");
+ producer.Send(message);
+
+ connection.Start();
+ IMessageConsumer consumer = session.CreateConsumer(queue);
+ IMessage message2 = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+ Assert.IsNotNull(message2);
+ Assert.IsTrue(message2 is ITextMessage, "Expected message to be a ITextMessage");
+ Assert.IsTrue(((ITextMessage)message2).Text == message.Text, "Expected message to be a '" + message.Text + "'");
+ }
+
+ //[Test]
+ public virtual void TestTmpQueueWorksUnderLoad()
+ {
+ int count = 500;
+ int dataSize = 1024;
+
+ ArrayList list = new ArrayList(count);
+ ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ ITemporaryQueue queue = session.CreateTemporaryQueue();
+ IBytesMessage message;
+ IBytesMessage message2;
+ IMessageProducer producer = session.CreateProducer(queue);
+ producer.DeliveryMode = MsgDeliveryMode.NonPersistent;
+
+ byte[] srcdata = new byte[dataSize];
+ srcdata[0] = (byte) 'B';
+ srcdata[1] = (byte) 'A';
+ srcdata[2] = (byte) 'D';
+ srcdata[3] = (byte) 'W';
+ srcdata[4] = (byte) 'O';
+ srcdata[5] = (byte) 'L';
+ srcdata[6] = (byte) 'F';
+ for(int i = 0; i < count; i++)
+ {
+ message = session.CreateBytesMessage();
+ message.WriteBytes(srcdata);
+ message.Properties.SetInt("c", i);
+ producer.Send(message);
+ list.Add(message);
+ }
+
+ connection.Start();
+ byte[] data = new byte[dataSize];
+ byte[] data2 = new byte[dataSize];
+ IMessageConsumer consumer = session.CreateConsumer(queue);
+ for(int i = 0; i < count; i++)
+ {
+ message2 = consumer.Receive(TimeSpan.FromMilliseconds(2000)) as IBytesMessage;
+ Assert.IsNotNull(message2);
+ Assert.AreEqual(i, message2.Properties.GetInt("c"));
+ message = list[i] as IBytesMessage;
+ Assert.IsNotNull(message);
+ message.Reset();
+ message.ReadBytes(data);
+ message2.ReadBytes(data2);
+ Assert.AreEqual(data, data2);
+ }
+ }
+ }
+}
diff --git a/src/test/csharp/TextMessageTest.cs b/src/test/csharp/TextMessageTest.cs
new file mode 100644
index 0000000..a5f23fd
--- /dev/null
+++ b/src/test/csharp/TextMessageTest.cs
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class TextMessageTest : NMSTest
+ {
+ protected TextMessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendReceiveTextMessage(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ IMessage request = session.CreateTextMessage("Hello World!");
+ producer.Send(request);
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(request, message);
+ Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Assert that two messages are ITextMessages and their text bodies are equal.
+ /// </summary>
+ /// <param name="expected"></param>
+ /// <param name="actual"></param>
+ protected void AssertTextMessageEqual(IMessage expected, IMessage actual)
+ {
+ ITextMessage expectedTextMsg = expected as ITextMessage;
+ Assert.IsNotNull(expectedTextMsg, "'expected' message not a text message");
+ ITextMessage actualTextMsg = actual as ITextMessage;
+ Assert.IsNotNull(actualTextMsg, "'actual' message not a text message");
+ Assert.AreEqual(expectedTextMsg.Text, actualTextMsg.Text, "Text message does not match.");
+ }
+ }
+}
diff --git a/src/test/csharp/TransactionTest.cs b/src/test/csharp/TransactionTest.cs
new file mode 100644
index 0000000..8fd7f93
--- /dev/null
+++ b/src/test/csharp/TransactionTest.cs
@@ -0,0 +1,439 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ //[TestFixture]
+ public class TransactionTest : NMSTest
+ {
+ protected TransactionTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+ //[Test]
+ public virtual void TestSendRollback(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage firstMsgSend = session.CreateTextMessage("First Message");
+ producer.Send(firstMsgSend);
+ session.Commit();
+
+ ITextMessage rollbackMsg = session.CreateTextMessage("I'm going to get rolled back.");
+ producer.Send(rollbackMsg);
+ session.Rollback();
+
+ ITextMessage secondMsgSend = session.CreateTextMessage("Second Message");
+ producer.Send(secondMsgSend);
+ session.Commit();
+
+ // Receive the messages
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+
+ message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");
+
+ // validates that the rollback was not consumed
+ session.Commit();
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendSessionClose(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ ITextMessage firstMsgSend;
+ ITextMessage secondMsgSend;
+
+ using(IConnection connection1 = CreateConnection(GetTestClientId()))
+ {
+ connection1.Start();
+ using(ISession session1 = connection1.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination1 = GetClearDestinationByNodeReference(session1, testDestRef);
+ using(IMessageConsumer consumer = session1.CreateConsumer(destination1))
+ {
+ // First connection session that sends one message, and the
+ // second message is implicitly rolled back as the session is
+ // disposed before Commit() can be called.
+ using(IConnection connection2 = CreateConnection(GetTestClientId()))
+ {
+ connection2.Start();
+ using(ISession session2 = connection2.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination2 = GetClearDestinationByNodeReference(session2, testDestRef);
+ using(IMessageProducer producer = session2.CreateProducer(destination2))
+ {
+ producer.DeliveryMode = deliveryMode;
+ firstMsgSend = session2.CreateTextMessage("First Message");
+ producer.Send(firstMsgSend);
+ session2.Commit();
+
+ ITextMessage rollbackMsg = session2.CreateTextMessage("I'm going to get rolled back.");
+ producer.Send(rollbackMsg);
+ }
+ }
+ }
+
+ // Second connection session that will send one message.
+ using(IConnection connection2 = CreateConnection(GetTestClientId()))
+ {
+ connection2.Start();
+ using(ISession session2 = connection2.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination2 = GetClearDestinationByNodeReference(session2, testDestRef);
+ using(IMessageProducer producer = session2.CreateProducer(destination2))
+ {
+ producer.DeliveryMode = deliveryMode;
+ secondMsgSend = session2.CreateTextMessage("Second Message");
+ producer.Send(secondMsgSend);
+ session2.Commit();
+ }
+ }
+ }
+
+ // Check the consumer to verify which messages were actually received.
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+
+ message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");
+
+ // validates that the rollback was not consumed
+ session1.Commit();
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestReceiveRollback(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ // Send both messages
+ ITextMessage firstMsgSend = session.CreateTextMessage("First Message");
+ producer.Send(firstMsgSend);
+ ITextMessage secondMsgSend = session.CreateTextMessage("Second Message");
+ producer.Send(secondMsgSend);
+ session.Commit();
+
+ // Receive the messages
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+ session.Commit();
+
+ message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");
+
+ // Rollback so we can get that last message again.
+ session.Rollback();
+ IMessage rollbackMsg = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, rollbackMsg, "Rollback message does not match.");
+ session.Commit();
+ }
+ }
+ }
+ }
+
+
+ //[Test]
+ public virtual void TestReceiveTwoThenRollback(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.Transactional))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ // Send both messages
+ ITextMessage firstMsgSend = session.CreateTextMessage("First Message");
+ producer.Send(firstMsgSend);
+ ITextMessage secondMsgSend = session.CreateTextMessage("Second Message");
+ producer.Send(secondMsgSend);
+ session.Commit();
+
+ // Receive the messages
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+ message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");
+
+ // Rollback so we can get that last two messages again.
+ session.Rollback();
+ IMessage rollbackMsg = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, rollbackMsg, "First rollback message does not match.");
+ rollbackMsg = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(secondMsgSend, rollbackMsg, "Second rollback message does not match.");
+
+ Assert.IsNull(consumer.ReceiveNoWait());
+ session.Commit();
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestSendCommitNonTransaction(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage firstMsgSend = session.CreateTextMessage("SendCommitNonTransaction Message");
+ producer.Send(firstMsgSend);
+ try
+ {
+ session.Commit();
+ Assert.Fail("Should have thrown an InvalidOperationException.");
+ }
+ catch(InvalidOperationException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestReceiveCommitNonTransaction(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage firstMsgSend = session.CreateTextMessage("ReceiveCommitNonTransaction Message");
+ producer.Send(firstMsgSend);
+
+ // Receive the messages
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+ if(AcknowledgementMode.ClientAcknowledge == ackMode)
+ {
+ message.Acknowledge();
+ }
+
+ try
+ {
+ session.Commit();
+ Assert.Fail("Should have thrown an InvalidOperationException.");
+ }
+ catch(InvalidOperationException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ //[Test]
+ public virtual void TestReceiveRollbackNonTransaction(
+ //[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]
+ AcknowledgementMode ackMode,
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(ackMode))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ producer.DeliveryMode = deliveryMode;
+ ITextMessage firstMsgSend = session.CreateTextMessage("ReceiveCommitNonTransaction Message");
+ producer.Send(firstMsgSend);
+
+ // Receive the messages
+
+ IMessage message = consumer.Receive(receiveTimeout);
+ AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");
+ if(AcknowledgementMode.ClientAcknowledge == ackMode)
+ {
+ message.Acknowledge();
+ }
+
+ try
+ {
+ session.Rollback();
+ Assert.Fail("Should have thrown an InvalidOperationException.");
+ }
+ catch(InvalidOperationException)
+ {
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Assert that two messages are ITextMessages and their text bodies are equal.
+ /// </summary>
+ /// <param name="expected"></param>
+ /// <param name="actual"></param>
+ /// <param name="message"></param>
+ protected void AssertTextMessageEqual(IMessage expected, IMessage actual, String message)
+ {
+ ITextMessage expectedTextMsg = expected as ITextMessage;
+ Assert.IsNotNull(expectedTextMsg, "'expected' message not a text message");
+ ITextMessage actualTextMsg = actual as ITextMessage;
+ Assert.IsNotNull(actualTextMsg, "'actual' message not a text message");
+ Assert.AreEqual(expectedTextMsg.Text, actualTextMsg.Text, message);
+ }
+
+ //[Test]
+ public virtual void TestRedispatchOfRolledbackTx(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.Transactional);
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+
+ SendMessages(connection, destination, deliveryMode, 2);
+
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(1500)));
+ Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(1500)));
+
+ // install another consumer while message dispatch is unacked/uncommitted
+ ISession redispatchSession = connection.CreateSession(AcknowledgementMode.Transactional);
+ IMessageConsumer redispatchConsumer = redispatchSession.CreateConsumer(destination);
+
+ session.Rollback();
+ session.Close();
+
+ IMessage msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(1500));
+ Assert.IsNotNull(msg);
+ Assert.IsTrue(msg.NMSRedelivered);
+ Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));
+ msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(1500));
+ Assert.IsNotNull(msg);
+ Assert.IsTrue(msg.NMSRedelivered);
+ Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));
+ redispatchSession.Commit();
+
+ Assert.IsNull(redispatchConsumer.Receive(TimeSpan.FromMilliseconds(500)));
+ redispatchSession.Close();
+ }
+ }
+
+ //[Test]
+ public virtual void TestRedispatchOfUncommittedTx(
+ //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
+ MsgDeliveryMode deliveryMode, string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ ISession session = connection.CreateSession(AcknowledgementMode.Transactional);
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+
+ SendMessages(connection, destination, deliveryMode, 2);
+
+ IMessageConsumer consumer = session.CreateConsumer(destination);
+ Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(2000)));
+ Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(2000)));
+
+ // install another consumer while message dispatch is unacked/uncommitted
+ ISession redispatchSession = connection.CreateSession(AcknowledgementMode.Transactional);
+ IMessageConsumer redispatchConsumer = redispatchSession.CreateConsumer(destination);
+
+ // no commit so will auto rollback and get re-dispatched to redisptachConsumer
+ session.Close();
+
+ IMessage msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(2000));
+ Assert.IsNotNull(msg);
+ Assert.IsTrue(msg.NMSRedelivered);
+ Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));
+
+ msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(2000));
+ Assert.IsNotNull(msg);
+ Assert.IsTrue(msg.NMSRedelivered);
+ Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));
+ redispatchSession.Commit();
+
+ Assert.IsNull(redispatchConsumer.Receive(TimeSpan.FromMilliseconds(500)));
+ redispatchSession.Close();
+ }
+ }
+ }
+}
+
+
diff --git a/src/test/csharp/XmlMessageTest.cs b/src/test/csharp/XmlMessageTest.cs
new file mode 100644
index 0000000..9c9fc88
--- /dev/null
+++ b/src/test/csharp/XmlMessageTest.cs
@@ -0,0 +1,186 @@
+/*
+ * 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.
+ */
+using System;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.Test
+{
+ // For ease of cross-platform exchange of information, you might generate objects from
+ // an XSD file using XSDObjectGen. However, C# has built-in support for serializing.
+ // All of the XML attributes that are commented out are optional, but give you fine-grained
+ // control over the serialized format if you need it.
+
+ // [Serializable]
+ public enum CheckType
+ {
+ // [XmlEnum(Name = "message")]
+ message,
+ // [XmlEnum(Name = "command")]
+ command,
+ // [XmlEnum(Name = "response")]
+ response
+ }
+
+ // [XmlRoot(ElementName = "NMSTestXmlType1", IsNullable = false), Serializable]
+ public class NMSTestXmlType1
+ {
+ // [XmlElement(ElementName = "crcCheck", IsNullable = false, DataType = "int")]
+ public int crcCheck;
+
+ // [XmlElement(Type = typeof(CheckType), ElementName = "checkType", IsNullable = false)]
+ public CheckType checkType;
+
+ public NMSTestXmlType1()
+ {
+ crcCheck = 0;
+ checkType = CheckType.message;
+ }
+ }
+
+ // [XmlRoot(ElementName = "NMSTestXmlType2", IsNullable = false), Serializable]
+ public class NMSTestXmlType2
+ {
+ // [XmlElement(ElementName = "stringCheck", IsNullable = false, DataType = "string")]
+ public string stringCheck;
+
+ public NMSTestXmlType2()
+ {
+ stringCheck = String.Empty;
+ }
+ }
+
+ //[TestFixture]
+ public class XmlMessageTest : NMSTest
+ {
+ public XmlMessageTest(NMSTestSupport testSupport)
+ : base(testSupport)
+ {
+ }
+
+#if NET_3_5 || MONO
+
+ //[Test]
+ public virtual void TestSendReceiveXmlMessage_Net35(string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ NMSTestXmlType1 srcIntObject = new NMSTestXmlType1();
+ srcIntObject.crcCheck = 0xbadf00d;
+ srcIntObject.checkType = CheckType.command;
+ producer.Send(srcIntObject);
+
+ NMSTestXmlType2 srcStringObject = new NMSTestXmlType2();
+ srcStringObject.stringCheck = "BadFood";
+ producer.Send(srcStringObject);
+
+ // Demonstrate the ability to generically handle multiple object types
+ // sent to the same consumer. If only one object type is ever sent to
+ // the destination, then a simple inline cast is all that is necessary
+ // when calling the NMSConvert.FromXmlMessage() function.
+
+ for(int index = 0; index < 2; index++)
+ {
+ object receivedObject = consumer.Receive(receiveTimeout).ToObject();
+ Assert.IsNotNull(receivedObject, "Failed to retrieve XML message object.");
+
+ if(receivedObject is NMSTestXmlType1)
+ {
+ NMSTestXmlType1 destObject = (NMSTestXmlType1) receivedObject;
+ Assert.AreEqual(srcIntObject.crcCheck, destObject.crcCheck, "CRC integer mis-match.");
+ Assert.AreEqual(srcIntObject.checkType, destObject.checkType, "Check type mis-match.");
+ }
+ else if(receivedObject is NMSTestXmlType2)
+ {
+ NMSTestXmlType2 destObject = (NMSTestXmlType2) receivedObject;
+ Assert.AreEqual(srcStringObject.stringCheck, destObject.stringCheck, "CRC string mis-match.");
+ }
+ else
+ {
+ Assert.Fail("Invalid object type.");
+ }
+ }
+ }
+ }
+ }
+ }
+
+#else
+
+ // Test the obsolete API versions until they are completely removed.
+ //[Test]
+ public virtual void TestSendReceiveXmlMessage(string testDestRef)
+ {
+ using(IConnection connection = CreateConnection(GetTestClientId()))
+ {
+ connection.Start();
+ using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+ {
+ IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
+ using(IMessageConsumer consumer = session.CreateConsumer(destination))
+ using(IMessageProducer producer = session.CreateProducer(destination))
+ {
+ NMSTestXmlType1 srcIntObject = new NMSTestXmlType1();
+ srcIntObject.crcCheck = 0xbadf00d;
+ srcIntObject.checkType = CheckType.command;
+ producer.Send(NMSConvert.ToXmlMessage(session, srcIntObject));
+
+ NMSTestXmlType2 srcStringObject = new NMSTestXmlType2();
+ srcStringObject.stringCheck = "BadFood";
+ producer.Send(NMSConvert.ToXmlMessage(session, srcStringObject));
+
+ // Demonstrate the ability to generically handle multiple object types
+ // sent to the same consumer. If only one object type is ever sent to
+ // the destination, then a simple inline cast is all that is necessary
+ // when calling the NMSConvert.FromXmlMessage() function.
+
+ for(int index = 0; index < 2; index++)
+ {
+ object receivedObject = NMSConvert.FromXmlMessage(consumer.Receive(receiveTimeout));
+ Assert.IsNotNull(receivedObject, "Failed to retrieve XML message object.");
+
+ if(receivedObject is NMSTestXmlType1)
+ {
+ NMSTestXmlType1 destObject = (NMSTestXmlType1) receivedObject;
+ Assert.AreEqual(srcIntObject.crcCheck, destObject.crcCheck, "CRC integer mis-match.");
+ Assert.AreEqual(srcIntObject.checkType, destObject.checkType, "Check type mis-match.");
+ }
+ else if(receivedObject is NMSTestXmlType2)
+ {
+ NMSTestXmlType2 destObject = (NMSTestXmlType2) receivedObject;
+ Assert.AreEqual(srcStringObject.stringCheck, destObject.stringCheck, "CRC string mis-match.");
+ }
+ else
+ {
+ Assert.Fail("Invalid object type.");
+ }
+ }
+ }
+ }
+ }
+ }
+
+#endif
+ }
+}
diff --git a/vs2008-msmq-test.csproj b/vs2008-msmq-test.csproj
index 685f1fc..e330436 100644
--- a/vs2008-msmq-test.csproj
+++ b/vs2008-msmq-test.csproj
@@ -1,9 +1,8 @@
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{2F31ED5C-44A2-464A-BD55-2B5B010654E8}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Apache.NMS.MSMQ.Test</RootNamespace>
@@ -79,6 +78,67 @@
<Compile Include="src\test\csharp\MSMQTest.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="src\test\csharp\AsyncConsumeTest.cs" />
+ <Compile Include="src\test\csharp\BadConsumeTest.cs" />
+ <Compile Include="src\test\csharp\BytesMessageTest.cs" />
+ <Compile Include="src\test\csharp\ConnectionTest.cs" />
+ <Compile Include="src\test\csharp\ConsumerTest.cs" />
+ <Compile Include="src\test\csharp\DurableTest.cs" />
+ <Compile Include="src\test\csharp\EndianBinaryReaderTest.cs" />
+ <Compile Include="src\test\csharp\EndianBinaryWriterTest.cs" />
+ <Compile Include="src\test\csharp\EndianTest.cs" />
+ <Compile Include="src\test\csharp\ForeignMessageTransformationTest.cs" />
+ <Compile Include="src\test\csharp\MapMessageTest.cs" />
+ <Compile Include="src\test\csharp\MessageSelectorTest.cs" />
+ <Compile Include="src\test\csharp\MessageTest.cs" />
+ <Compile Include="src\test\csharp\MessageTransformerTest.cs" />
+ <Compile Include="src\test\csharp\MSMQAsyncConsumeTest.cs" />
+ <Compile Include="src\test\csharp\MSMQBadConsumeTest.cs" />
+ <Compile Include="src\test\csharp\MSMQBytesMessageTest.cs" />
+ <Compile Include="src\test\csharp\MSMQConnectionTest.cs" />
+ <Compile Include="src\test\csharp\MSMQConsumerTest.cs" />
+ <Compile Include="src\test\csharp\MSMQDurableTest.cs" />
+ <Compile Include="src\test\csharp\MSMQForeignMessageTransformationTest.cs" />
+ <Compile Include="src\test\csharp\MSMQMapMessageTest.cs" />
+ <Compile Include="src\test\csharp\MSMQMessageSelectorTest.cs" />
+ <Compile Include="src\test\csharp\MSMQMessageTest.cs" />
+ <Compile Include="src\test\csharp\MSMQMessageTransformerTest.cs" />
+ <Compile Include="src\test\csharp\MSMQNMSPropertyTest.cs" />
+ <Compile Include="src\test\csharp\MSMQProducerTest.cs" />
+ <Compile Include="src\test\csharp\MSMQRequestResponseTest.cs" />
+ <Compile Include="src\test\csharp\MSMQStreamMessageTest.cs" />
+ <Compile Include="src\test\csharp\MSMQTempDestinationDeletionTest.cs" />
+ <Compile Include="src\test\csharp\MSMQTempDestinationTest.cs" />
+ <Compile Include="src\test\csharp\MSMQTestSupport.cs" />
+ <Compile Include="src\test\csharp\MSMQTextMessageTest.cs" />
+ <Compile Include="src\test\csharp\MSMQTransactionTest.cs" />
+ <Compile Include="src\test\csharp\MSMQXmlMessageTest.cs" />
+ <Compile Include="src\test\csharp\NMSPropertyTest.cs" />
+ <Compile Include="src\test\csharp\NMSTest.cs" />
+ <Compile Include="src\test\csharp\NMSTestSupport.cs" />
+ <Compile Include="src\test\csharp\NMSTracer.cs" />
+ <Compile Include="src\test\csharp\PrimitiveMapTest.cs" />
+ <Compile Include="src\test\csharp\ProducerTest.cs" />
+ <Compile Include="src\test\csharp\RedeliveryPolicyTest.cs" />
+ <Compile Include="src\test\csharp\RequestResponseTest.cs" />
+ <Compile Include="src\test\csharp\StreamMessageTest.cs" />
+ <Compile Include="src\test\csharp\TempDestinationDeletionTest.cs" />
+ <Compile Include="src\test\csharp\TempDestinationTest.cs" />
+ <Compile Include="src\test\csharp\TextMessageTest.cs" />
+ <Compile Include="src\test\csharp\TransactionTest.cs" />
+ <Compile Include="src\test\csharp\XmlMessageTest.cs" />
+ <Compile Include="src\test\csharp\Commands\BytesMessage.cs" />
+ <Compile Include="src\test\csharp\Commands\Destination.cs" />
+ <Compile Include="src\test\csharp\Commands\MapMessage.cs" />
+ <Compile Include="src\test\csharp\Commands\Message.cs" />
+ <Compile Include="src\test\csharp\Commands\ObjectMessage.cs" />
+ <Compile Include="src\test\csharp\Commands\Queue.cs" />
+ <Compile Include="src\test\csharp\Commands\StreamMessage.cs" />
+ <Compile Include="src\test\csharp\Commands\TempDestination.cs" />
+ <Compile Include="src\test\csharp\Commands\TempQueue.cs" />
+ <Compile Include="src\test\csharp\Commands\TempTopic.cs" />
+ <Compile Include="src\test\csharp\Commands\TextMessage.cs" />
+ <Compile Include="src\test\csharp\Commands\Topic.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="vs2008-msmq.csproj">
@@ -110,6 +170,7 @@
</ItemGroup>
<ItemGroup>
<None Include="keyfile\NMSKey.snk" />
+ <None Include="msmqprovider-test.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
<PropertyGroup>
diff --git a/vs2008-msmq.csproj b/vs2008-msmq.csproj
index 3023e88..76ab1dc 100644
--- a/vs2008-msmq.csproj
+++ b/vs2008-msmq.csproj
@@ -1,9 +1,8 @@
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A5FCA129-991B-4CB2-987A-B25E43B0F5EC}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Apache.NMS.MSMQ</RootNamespace>
diff --git a/vs2008-msmq.sln b/vs2008-msmq.sln
index a51006f..010ea3c 100644
--- a/vs2008-msmq.sln
+++ b/vs2008-msmq.sln
@@ -1,30 +1,30 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vs2008-msmq", "vs2008-msmq.csproj", "{A5FCA129-991B-4CB2-987A-B25E43B0F5EC}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vs2008-msmq-test", "vs2008-msmq-test.csproj", "{2F31ED5C-44A2-464A-BD55-2B5B010654E8}"
-EndProject
-Global
- GlobalSection(SubversionScc) = preSolution
- Svn-Managed = True
- Manager = AnkhSVN - Subversion Support for Visual Studio
- EndGlobalSection
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {A5FCA129-991B-4CB2-987A-B25E43B0F5EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A5FCA129-991B-4CB2-987A-B25E43B0F5EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A5FCA129-991B-4CB2-987A-B25E43B0F5EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A5FCA129-991B-4CB2-987A-B25E43B0F5EC}.Release|Any CPU.Build.0 = Release|Any CPU
- {2F31ED5C-44A2-464A-BD55-2B5B010654E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2F31ED5C-44A2-464A-BD55-2B5B010654E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2F31ED5C-44A2-464A-BD55-2B5B010654E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2F31ED5C-44A2-464A-BD55-2B5B010654E8}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vs2008-msmq", "vs2008-msmq.csproj", "{A5FCA129-991B-4CB2-987A-B25E43B0F5EC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vs2008-msmq-test", "vs2008-msmq-test.csproj", "{2F31ED5C-44A2-464A-BD55-2B5B010654E8}"
+EndProject
+Global
+ GlobalSection(SubversionScc) = preSolution
+ Svn-Managed = True
+ Manager = AnkhSVN - Subversion Support for Visual Studio
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A5FCA129-991B-4CB2-987A-B25E43B0F5EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A5FCA129-991B-4CB2-987A-B25E43B0F5EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A5FCA129-991B-4CB2-987A-B25E43B0F5EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A5FCA129-991B-4CB2-987A-B25E43B0F5EC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2F31ED5C-44A2-464A-BD55-2B5B010654E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2F31ED5C-44A2-464A-BD55-2B5B010654E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2F31ED5C-44A2-464A-BD55-2B5B010654E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2F31ED5C-44A2-464A-BD55-2B5B010654E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal