Added: activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/StreamMessage.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/StreamMessage.cs?rev=1723221&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/StreamMessage.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/StreamMessage.cs Wed Jan 6 02:19:56 2016 @@ -0,0 +1,480 @@ +/* + * 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; +using Apache.NMS.Util; +using Apache.NMS.XMS.Util; +using IBM.XMS; + +namespace Apache.NMS.XMS +{ + /// <summary> + /// A StreamMessage object is used to send a stream of primitive types in the + /// .NET programming language. It is filled and read sequentially. It inherits + /// from the Message interface and adds a stream message body. + /// </summary> + class StreamMessage : Apache.NMS.XMS.Message, Apache.NMS.IStreamMessage + { + #region Constructors and access to internal stream message + + /// <summary> + /// Internal IBM XMS stream message. + /// </summary> + public IBM.XMS.IStreamMessage xmsStreamMessage + { + get { return (IBM.XMS.IStreamMessage)this.xmsMessage; } + set { this.xmsMessage = value; } + } + + /// <summary> + /// Constructs a <c>StreamMessage</c> object. + /// </summary> + /// <param name="message">XMS stream message.</param> + public StreamMessage(IBM.XMS.IStreamMessage message) + : base(message) + { + } + + #endregion + + #region IStreamMessage Members + + #region Reset method + + /// <summary> + /// Resets the contents of the stream message body. + /// </summary> + public void Reset() + { + try + { + this.xmsStreamMessage.Reset(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + #endregion + + #region Read methods + + /// <summary> + /// Reads a boolean from the stream message. + /// </summary> + /// <returns>A <see cref="System.Boolean"/></returns> + public bool ReadBoolean() + { + try + { + return this.xmsStreamMessage.ReadBoolean(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return false; + } + } + + /// <summary> + /// Reads a byte from the stream message. + /// </summary> + /// <returns>A <see cref="System.Byte"/></returns> + public byte ReadByte() + { + try + { + return this.xmsStreamMessage.ReadByte(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return 0; + } + } + + /// <summary> + /// Reads a byte array from the stream message. + /// </summary> + /// <param name="value">A <see cref="System.Byte"/> array</param> + /// <returns>The total number of bytes read into the buffer, or -1 if + /// there is no more data because the end of the byte field has been + /// reached</returns> + public int ReadBytes(byte[] value) + { + try + { + return this.xmsStreamMessage.ReadBytes(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return 0; + } + } + + /// <summary> + /// Reads a character from the stream message. + /// </summary> + /// <returns>A <see cref="System.Char"/></returns> + public char ReadChar() + { + try + { + return this.xmsStreamMessage.ReadChar(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return (char) 0; + } + } + + /// <summary> + /// Reads a 16 bits (short) integer number from the stream message. + /// </summary> + /// <returns>A <see cref="System.Int16"/></returns> + public short ReadInt16() + { + try + { + return this.xmsStreamMessage.ReadShort(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return 0; + } + } + + /// <summary> + /// Reads a 32 bits (int) integer number from the stream message. + /// </summary> + /// <returns>A <see cref="System.Int32"/></returns> + public int ReadInt32() + { + try + { + return this.xmsStreamMessage.ReadInt(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return 0; + } + } + + /// <summary> + /// Reads a 64 bits (long) integer number from the stream message. + /// </summary> + /// <returns>A <see cref="System.Int64"/></returns> + public long ReadInt64() + { + try + { + return this.xmsStreamMessage.ReadLong(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return 0; + } + } + + /// <summary> + /// Reads a single precision floating point number from the stream + /// message. + /// </summary> + /// <returns>A <see cref="System.Single"/></returns> + public float ReadSingle() + { + try + { + return this.xmsStreamMessage.ReadFloat(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return 0; + } + } + + /// <summary> + /// Reads a double precision floating point number from the stream + /// message. + /// </summary> + /// <returns>A <see cref="System.Double"/></returns> + public double ReadDouble() + { + try + { + return this.xmsStreamMessage.ReadDouble(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return 0; + } + } + + /// <summary> + /// Reads a character string from the stream message. + /// </summary> + /// <returns>A <see cref="System.String"/></returns> + public string ReadString() + { + try + { + return this.xmsStreamMessage.ReadString(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return null; + } + } + + /// <summary> + /// Reads an object from the stream message. + /// </summary> + /// <returns>A <see cref="System.Object"/></returns> + public object ReadObject() + { + try + { + return this.xmsStreamMessage.ReadObject(); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return 0; + } + } + + #endregion + + #region Write methods + + /// <summary> + /// Writes a boolean to the stream message. + /// </summary> + /// <param name="value">A <see cref="System.Boolean"/></param> + public void WriteBoolean(bool value) + { + try + { + this.xmsStreamMessage.WriteBoolean(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes a byte to the stream message. + /// </summary> + /// <param name="value">A <see cref="System.Byte"/></param> + public void WriteByte(byte value) + { + try + { + this.xmsStreamMessage.WriteByte(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes a byte array to the stream message. + /// </summary> + /// <param name="value">A <see cref="System.Byte"/> array</param> + public void WriteBytes(byte[] value) + { + try + { + this.xmsStreamMessage.WriteBytes(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes a portion of a byte array as a byte array field to the + /// stream message. + /// </summary> + /// <param name="value">A <see cref="System.Byte"/> array</param> + /// <param name="offset">A <see cref="System.Int32"/> value that + /// indicates the point in the buffer to begin writing to the stream + /// message.</param> + /// <param name="length">A <see cref="System.Int32"/> value that + /// indicates how many bytes in the buffer to write to the stream + /// message.</param> + public void WriteBytes(byte[] value, int offset, int length) + { + try + { + this.xmsStreamMessage.WriteBytes(value, offset, length); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes a character to the stream message. + /// </summary> + /// <param name="value">A <see cref="System.Char"/></param> + public void WriteChar(char value) + { + try + { + this.xmsStreamMessage.WriteChar(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes a 16 bts (short) integer to the stream message. + /// </summary> + /// <param name="value">A <see cref="System.Int16"/></param> + public void WriteInt16(short value) + { + try + { + this.xmsStreamMessage.WriteShort(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes a 32 bts (int) integer to the stream message. + /// </summary> + /// <param name="value">A <see cref="System.Int32"/></param> + public void WriteInt32(int value) + { + try + { + this.xmsStreamMessage.WriteInt(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes a 64 bts (long) integer to the stream message. + /// </summary> + /// <param name="value">A <see cref="System.Int64"/></param> + public void WriteInt64(long value) + { + try + { + this.xmsStreamMessage.WriteLong(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes a single precision floating point number to the stream + /// message. + /// </summary> + /// <param name="value">A <see cref="System.Single"/></param> + public void WriteSingle(float value) + { + try + { + this.xmsStreamMessage.WriteFloat(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes a double precision floating point number to the stream + /// message. + /// </summary> + /// <param name="value">A <see cref="System.Double"/></param> + public void WriteDouble(double value) + { + try + { + this.xmsStreamMessage.WriteDouble(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes a character string to the stream + /// message. + /// </summary> + /// <param name="value">A <see cref="System.String"/></param> + public void WriteString(string value) + { + try + { + this.xmsStreamMessage.WriteString(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + /// <summary> + /// Writes an object to the stream + /// message. + /// </summary> + /// <param name="value">A <see cref="System.Object"/></param> + public void WriteObject(object value) + { + try + { + this.xmsStreamMessage.WriteObject(value); + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + + #endregion + + #endregion + } +}
Added: activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TemporaryQueue.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TemporaryQueue.cs?rev=1723221&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TemporaryQueue.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TemporaryQueue.cs Wed Jan 6 02:19:56 2016 @@ -0,0 +1,62 @@ +/* + * 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.XMS +{ + class TemporaryQueue : Apache.NMS.XMS.Queue, Apache.NMS.ITemporaryQueue + { + #region Constructors and destructors + + /// <summary> + /// Constructs a <c>TemporaryQueue</c> object. + /// </summary> + /// <param name="temporaryQueue">IBM XMS queue</param> + public TemporaryQueue(IBM.XMS.IDestination temporaryQueue) + : base(temporaryQueue, true) + { + } + + #endregion + + #region ITemporaryQueue Members + + /// <summary> + /// Deletes the temporary queue. + /// </summary> + public void Delete() + { + // IBM.XMS does not provide a method for deleting a destination. + // Should we throw an exception or ignore the request ? + //this.xmsDestination.Delete(); + } + + #endregion + + #region ToString + + /// <summary> + /// Returns a string representation of this instance. + /// </summary> + /// <returns>String representation of this instance</returns> + public override System.String ToString() + { + return "temp-queue://" + QueueName; + } + + #endregion + } +} Added: activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TemporaryTopic.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TemporaryTopic.cs?rev=1723221&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TemporaryTopic.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TemporaryTopic.cs Wed Jan 6 02:19:56 2016 @@ -0,0 +1,62 @@ +/* + * 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.XMS +{ + class TemporaryTopic : Apache.NMS.XMS.Topic, Apache.NMS.ITemporaryTopic + { + #region Constructors and destructors + + /// <summary> + /// Constructs a <c>TemporaryTopic</c> object. + /// </summary> + /// <param name="temporaryTopic">IBM XMS queue</param> + public TemporaryTopic(IBM.XMS.IDestination temporaryTopic) + : base(temporaryTopic, true) + { + } + + #endregion + + #region ITemporaryTopic Members + + /// <summary> + /// Deletes the temporary topic. + /// </summary> + public void Delete() + { + // IBM.XMS does not provide a method for deleting a destination. + // Should we throw an exception or ignore the request ? + //this.xmsDestination.Delete(); + } + + #endregion + + #region ToString + + /// <summary> + /// Returns a string representation of this instance. + /// </summary> + /// <returns>string representation of this instance</returns> + public override System.String ToString() + { + return "temp-topic://" + TopicName; + } + + #endregion + } +} Added: activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TextMessage.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TextMessage.cs?rev=1723221&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TextMessage.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/TextMessage.cs Wed Jan 6 02:19:56 2016 @@ -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; +using Apache.NMS.Util; +using Apache.NMS.XMS.Util; +using IBM.XMS; + +namespace Apache.NMS.XMS +{ + /// <summary> + /// Represents a text based message. + /// </summary> + class TextMessage : Apache.NMS.XMS.Message, Apache.NMS.ITextMessage + { + #region Constructors and access to internal stream message + + /// <summary> + /// Internal IBM XMS text message. + /// </summary> + public IBM.XMS.ITextMessage xmsTextMessage + { + get { return (IBM.XMS.ITextMessage)this.xmsMessage; } + set { this.xmsMessage = value; } + } + + /// <summary> + /// Constructs a <c>TextMessage</c> object. + /// </summary> + /// <param name="message">XMS text message.</param> + public TextMessage(IBM.XMS.ITextMessage message) + : base(message) + { + } + + #endregion + + #region ITextMessage Members + + /// <summary> + /// The text contents of the message body. + /// </summary> + public string Text + { + get + { + try + { + return this.xmsTextMessage.Text; + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + return null; + } + } + set + { + try + { + this.xmsTextMessage.Text = value; + } + catch(Exception ex) + { + ExceptionUtil.WrapAndThrowNMSException(ex); + } + } + } + + #endregion + } +} Added: activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Topic.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Topic.cs?rev=1723221&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Topic.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Topic.cs Wed Jan 6 02:19:56 2016 @@ -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; +using Apache.NMS.Util; +using Apache.NMS.XMS.Util; +using IBM.XMS; + +namespace Apache.NMS.XMS +{ + public class Topic : Apache.NMS.XMS.Destination, Apache.NMS.ITopic + { + #region Constructors and destructors + + /// <summary> + /// Constructs a <c>Topic</c> object. + /// </summary> + /// <param name="topic">IBM XMS topic</param> + public Topic(IBM.XMS.IDestination topic) + : base(topic) + { + } + + /// <summary> + /// Constructs a <c>Topic</c> object. + /// </summary> + /// <param name="topic">IBM XMS topic</param> + /// <param name="isTemporary">Whether the topic is temporary</param> + public Topic(IBM.XMS.IDestination topic, bool isTemporary) + : base(topic, isTemporary) + { + } + + #endregion + + #region ITopic Members + + public string TopicName + { + get { return this.xmsDestination.Name; } + } + + #endregion + + #region ToString + + /// <summary> + /// Returns a String representation of this instance. + /// </summary> + /// <returns>String representation of this instance</returns> + public override System.String ToString() + { + return "topic://" + TopicName; + } + + #endregion + } +} \ No newline at end of file Added: activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/Dispatcher.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/Dispatcher.cs?rev=1723221&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/Dispatcher.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/Dispatcher.cs Wed Jan 6 02:19:56 2016 @@ -0,0 +1,173 @@ +/* + * 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.Threading; + +namespace Apache.NMS.XMS.Util +{ + /// <summary> + /// Handles the multi-threaded dispatching between the transport and the consumers + /// </summary> + public class Dispatcher + { + System.Collections.Queue queue = new System.Collections.Queue(); + readonly Object semaphore = new Object(); + readonly ArrayList messagesToRedeliver = new ArrayList(); + + // TODO can't use EventWaitHandle on MONO 1.0 + AutoResetEvent messageReceivedEventHandle = new AutoResetEvent(false); + bool m_bAsyncDelivery = false; + bool m_bClosed = false; + + public void SetAsyncDelivery(AutoResetEvent eventHandle) + { + lock (semaphore) + { + messageReceivedEventHandle = eventHandle; + m_bAsyncDelivery = true; + if (queue.Count > 0) + { + messageReceivedEventHandle.Set(); + } + } + } + + /// <summary> + /// Whem we start a transaction we must redeliver any rolled back messages + /// </summary> + public void RedeliverRolledBackMessages() + { + lock (semaphore) + { + System.Collections.Queue replacement = new System.Collections.Queue(queue.Count + messagesToRedeliver.Count); + foreach (Apache.NMS.IMessage element in messagesToRedeliver) + { + replacement.Enqueue(element); + } + messagesToRedeliver.Clear(); + + while (queue.Count > 0) + { + Apache.NMS.IMessage element = (Apache.NMS.IMessage) queue.Dequeue(); + replacement.Enqueue(element); + } + + queue = replacement; + if (queue.Count > 0) + { + messageReceivedEventHandle.Set(); + } + } + } + + /// <summary> + /// Redeliver the given message, putting it at the head of the queue + /// </summary> + public void Redeliver(Apache.NMS.IMessage message) + { + lock (semaphore) + { + messagesToRedeliver.Add(message); + } + } + + /// <summary> + /// Method Enqueue + /// </summary> + public void Enqueue(Apache.NMS.IMessage message) + { + lock (semaphore) + { + queue.Enqueue(message); + messageReceivedEventHandle.Set(); + } + } + + /// <summary> + /// Method DequeueNoWait + /// </summary> + public Apache.NMS.IMessage DequeueNoWait() + { + Apache.NMS.XMS.Message rc = null; + lock (semaphore) + { + if (!m_bClosed && queue.Count > 0) + { + rc = (Apache.NMS.XMS.Message) queue.Dequeue(); + if(null != rc) + { + rc.ReadOnlyBody = true; + rc.ReadOnlyProperties = true; + } + } + } + return rc; + } + + /// <summary> + /// Method Dequeue + /// </summary> + public Apache.NMS.IMessage Dequeue(TimeSpan timeout) + { + Apache.NMS.IMessage rc; + bool bClosed = false; + lock (semaphore) + { + bClosed = m_bClosed; + rc = DequeueNoWait(); + } + + while (!bClosed && rc == null) + { + if( !messageReceivedEventHandle.WaitOne(timeout, false)) + { + break; + } + + lock (semaphore) + { + rc = DequeueNoWait(); + bClosed = m_bClosed; + } + } + return rc; + } + + /// <summary> + /// Method Dequeue + /// </summary> + public Apache.NMS.IMessage Dequeue() + { + TimeSpan indefiniteWait = TimeSpan.FromMilliseconds(Timeout.Infinite); + return Dequeue(indefiniteWait); + } + + public void Close() + { + lock (semaphore) + { + m_bClosed = true; + queue.Clear(); + if(m_bAsyncDelivery) + { + messageReceivedEventHandle.Set(); + } + } + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/ExceptionUtil.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/ExceptionUtil.cs?rev=1723221&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/ExceptionUtil.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/ExceptionUtil.cs Wed Jan 6 02:19:56 2016 @@ -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 System.Text; +using System.Collections.Generic; +using IBM.XMS; + +namespace Apache.NMS.XMS.Util +{ + class ExceptionUtil + { + /// <summary> + /// Wrap the provider specific exception inside an NMS exception to + /// more tightly integrate the provider extensions into the NMS API. + /// </summary> + /// <param name="ex">Original exception.</param> + public static void WrapAndThrowNMSException(Exception ex) + { + if(ex is Apache.NMS.NMSException) + { + // Already derived from NMSException + throw ex; + } + + if(ex is IBM.XMS.IllegalStateException) + { + IBM.XMS.IllegalStateException xmsEx = + (IBM.XMS.IllegalStateException)ex; + throw new Apache.NMS.IllegalStateException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.InvalidClientIDException) + { + IBM.XMS.InvalidClientIDException xmsEx = + (IBM.XMS.InvalidClientIDException)ex; + throw new Apache.NMS.InvalidClientIDException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.InvalidDestinationException) + { + IBM.XMS.InvalidDestinationException xmsEx = + (IBM.XMS.InvalidDestinationException)ex; + throw new Apache.NMS.InvalidDestinationException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.InvalidSelectorException) + { + IBM.XMS.InvalidSelectorException xmsEx = + (IBM.XMS.InvalidSelectorException)ex; + throw new Apache.NMS.InvalidSelectorException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.MessageEOFException) + { + IBM.XMS.MessageEOFException xmsEx = + (IBM.XMS.MessageEOFException)ex; + throw new Apache.NMS.MessageEOFException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.MessageFormatException) + { + IBM.XMS.MessageFormatException xmsEx = + (IBM.XMS.MessageFormatException)ex; + throw new Apache.NMS.MessageFormatException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.MessageNotReadableException) + { + IBM.XMS.MessageNotReadableException xmsEx = + (IBM.XMS.MessageNotReadableException)ex; + throw new Apache.NMS.MessageNotReadableException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.MessageNotWriteableException) + { + IBM.XMS.MessageNotWriteableException xmsEx = + (IBM.XMS.MessageNotWriteableException)ex; + throw new Apache.NMS.MessageNotWriteableException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.ResourceAllocationException) + { + IBM.XMS.ResourceAllocationException xmsEx = + (IBM.XMS.ResourceAllocationException)ex; + throw new Apache.NMS.ResourceAllocationException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.SecurityException) + { + IBM.XMS.SecurityException xmsEx = + (IBM.XMS.SecurityException)ex; + throw new Apache.NMS.NMSSecurityException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.TransactionInProgressException) + { + IBM.XMS.TransactionInProgressException xmsEx = + (IBM.XMS.TransactionInProgressException)ex; + throw new Apache.NMS.TransactionInProgressException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.TransactionRolledBackException) + { + IBM.XMS.TransactionRolledBackException xmsEx = + (IBM.XMS.TransactionRolledBackException)ex; + throw new Apache.NMS.TransactionRolledBackException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + if(ex is IBM.XMS.XMSException) + { + IBM.XMS.XMSException xmsEx = + (IBM.XMS.XMSException)ex; + throw new Apache.NMS.NMSException( + xmsEx.Message, xmsEx.ErrorCode, xmsEx); + } + + // Not an EMS exception that should be wrapped. + throw ex; + } + } +} Added: activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/IntrospectionSupport.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/IntrospectionSupport.cs?rev=1723221&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/IntrospectionSupport.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/IntrospectionSupport.cs Wed Jan 6 02:19:56 2016 @@ -0,0 +1,434 @@ +/* + * 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; +using System.Globalization; +using System.Collections.Generic; +using System.Collections.Specialized; +using Apache.NMS; +using Apache.NMS.Util; + +namespace Apache.NMS.XMS.Util +{ + /// <summary> + /// Utility class used to provide convenience methods that apply named + /// property settings to objects. + /// </summary> + public class IntrospectionSupport + { + #region Manage maps of member names and URI aliases + + private static Dictionary<Type, StringDictionary> nameMaps = + new Dictionary<Type, StringDictionary>(); + private static readonly object nameMapsLock = new object(); + + /// <summary> + /// Gets the member names map for the specified type. + /// </summary> + /// <param name="type">Type whose names map is requested.</param> + /// <returns>Names map for the specified type.</returns> + /// <remarks> + /// The map is created and registered if it is not found in the + /// <c>nameMaps</c> registry. + /// </remarks> + public static StringDictionary GetNameMap(Type type) + { + StringDictionary nameMap; + lock(IntrospectionSupport.nameMapsLock) + { + if(!IntrospectionSupport.nameMaps.TryGetValue( + type, out nameMap)) + { + nameMap = CreateNameMap(type); + IntrospectionSupport.nameMaps.Add(type, nameMap); + } + } + return nameMap; + } + + /// <summary> + /// Creates a dictionary of public property and attribute names, + /// indexed by themselves plus all URI attribute keys associated + /// to them. + /// </summary> + /// <param name="type">Type whose names map is requested.</param> + /// <returns>Names map for the specified type.</returns> + /// <remarks> + /// Applied to this property: + /// <code> + /// [UriAttribute("My.Test", "MyTest")] + /// public string Test + /// { get { return(_test); } + /// set { _test = value; } + /// } + /// </code> + /// the method returns a dictionary containing + /// ("test" -> "Test"), ("my.test" -> "Test"), ("mytest" -> "Test"). + /// Note that <c>StringDictionary</c> converts keys to lowercase but + /// keeps values untouched. + /// </remarks> + public static StringDictionary CreateNameMap(Type type) + { + StringDictionary nameMap = new StringDictionary(); + BindingFlags flags = BindingFlags.FlattenHierarchy + | BindingFlags.Public + | BindingFlags.Instance; + + // Process public instance self or inherited property + foreach(PropertyInfo propertyInfo in type.GetProperties(flags)) + { + AddToNameMap(nameMap, propertyInfo); + } + + // Process public instance self or inherited fields + foreach(FieldInfo fieldInfo in type.GetFields(flags)) + { + AddToNameMap(nameMap, fieldInfo); + } + + return(nameMap); + } + + /// <summary> + /// Adds a property or field name and URI attribute keys to the + /// specified name map. + /// </summary> + /// <param name="nameMap">Name map.</param> + /// <param name="memberInfo">Member information for the property + /// or field.</param> + private static void AddToNameMap(StringDictionary nameMap, + MemberInfo memberInfo) + { + // Add member name mapped to itself + nameMap.Add(memberInfo.Name, memberInfo.Name); + + // For each UriAttribute custom attribute + foreach(Attribute attr in memberInfo.GetCustomAttributes( + typeof(UriAttributeAttribute), true)) + { + // For each URI attribute key + foreach(string key in + ((UriAttributeAttribute)attr).AttributeKeys) + { + // Index property name by URI attribute key + if(!nameMap.ContainsKey(key)) + { + nameMap.Add(key, memberInfo.Name); + } + } + } + + return; + } + + #endregion + + #region Set properties + + /// <summary> + /// Sets the public properties of a target object using a string map. + /// This method uses .Net reflection to identify public properties of + /// the target object matching the keys from the passed map. + /// </summary> + /// <param name="target">Object whose properties will be set.</param> + /// <param name="valueMap">Map of key/value pairs.</param> + public static void SetProperties(object target, + StringDictionary valueMap) + { + SetProperties(target, valueMap, GetNameMap(target.GetType())); + } + + /// <summary> + /// Sets the public properties of a target object using a string map. + /// This method uses .Net reflection to access public properties of + /// the target object matching the keys from the passed map. + /// </summary> + /// <param name="target">The object whose properties will be set.</param> + /// <param name="valueMap">Map of key/value pairs.</param> + /// <param name="nameMap">Map of key/property name pairs.</param> + public static void SetProperties(object target, + StringDictionary valueMap, + StringDictionary nameMap) + { + Tracer.DebugFormat("SetProperties called with target: {0}", + target.GetType().Name); + + // Application of specified values is recursive. If a key does not + // correspond to a member of the current target object, it is + // supposed to refer to a sub-member of such a member. Since member + // keys can contain dot characters, an attempt is made to find the + // "longest" key corresponding to a member of the current object + // (this identifies the "sub-target"), and extract the remaining + // key characters as a sub-key to sub-members. + // The following dictionary indexes keys to "sub-targets", and + // "sub-key"/value pairs to assign to "sub-targets". + Dictionary<string, StringDictionary> subTargetMap = null; + + foreach(string key in valueMap.Keys) + { + if(nameMap.ContainsKey(key)) + { + // Key refers to a member of the current target + string memberName = nameMap[key]; + MemberInfo member = FindMemberInfo(target, memberName); + if(member == null) + { + // Should not happen if the nameMap was indeed created + // for the current target object... + throw new NMSException(string.Format( + "No such property or field: {0} on class: {1}", + memberName, target.GetType().Name)); + } + + // Set value + try + { + if(member.MemberType == MemberTypes.Property) + { + PropertyInfo property = (PropertyInfo)member; + object value = ConvertValue(valueMap[key], + property.PropertyType); + property.SetValue(target, value, null); + } + else + { + FieldInfo field = (FieldInfo)member; + object value = ConvertValue(valueMap[key], + field.FieldType); + field.SetValue(target, value); + } + } + catch(Exception ex) + { + throw NMSExceptionSupport.Create( + "Error while attempting to apply option.", ex); + } + } + else + { + // Key does NOT refers to a member of the current target + // Extract maximal member key + subkeys + string memberKey = key; + int dotPos = memberKey.LastIndexOf('.'); + bool memberFound = false; + while(!memberFound && dotPos > 0) + { + memberKey = memberKey.Substring(0, dotPos); + if(nameMap.ContainsKey(memberKey)) + { + memberKey = nameMap[memberKey]; + memberFound = true; + } + else + { + dotPos = memberKey.LastIndexOf('.'); + } + } + + if(!memberFound) + { + throw new NMSException(string.Format( + "Unknown property or field: {0} on class: {1}", + key, target.GetType().Name)); + } + + // Register memberKey, subKey and value for further processing + string subKey = key.Substring(dotPos + 1); + StringDictionary subValueMap; + + if(subTargetMap == null) + { + subTargetMap = new Dictionary<string, StringDictionary>(); + } + + if(!subTargetMap.TryGetValue(memberKey, out subValueMap)) + { + subValueMap = new StringDictionary(); + subTargetMap.Add(memberKey, subValueMap); + } + + // In theory, we can't have the same subkey twice, since + // they were unique subkeys from another dictionary. + // Therefore, no need to check for subValueMap.ContainsKey. + subValueMap.Add(subKey, valueMap[key]); + } + } + + // Now process any compound assignments. + if(subTargetMap != null) + { + foreach(string subTargetKey in subTargetMap.Keys) + { + MemberInfo member = FindMemberInfo(target, subTargetKey); + object subTarget = GetUnderlyingObject(member, target); + SetProperties(subTarget, subTargetMap[subTargetKey]); + } + } + } + + /// <summary> + /// Converts the specified string value to the type of the target + /// member. + /// </summary> + private static object ConvertValue(string inputString, Type targetType) + { + // If the target member is an enumeration, get the enumeration + // value or combined (or-ed) values + object value; + if(targetType.IsEnum) + { + if(inputString.Contains("+")) + { + string[] inputValues = inputString.Split('+'); + + FieldInfo fieldInfo = targetType.GetField(inputValues[0], + BindingFlags.Public + | BindingFlags.Static + | BindingFlags.IgnoreCase); + if(fieldInfo == null) + { + throw new NMSException(string.Format( + "Invalid {0} value \"{1}\"", targetType.Name, + inputValues[0])); + } + dynamic val = fieldInfo.GetValue(null); + + for(int v = 1; v < inputValues.Length; v++) + { + fieldInfo = targetType.GetField(inputValues[v], + BindingFlags.Public + | BindingFlags.Static + | BindingFlags.IgnoreCase); + if(fieldInfo == null) + { + throw new NMSException(string.Format( + "Invalid {0} value \"{1}\"", targetType.Name, + inputValues[v])); + } + val = (dynamic)val | (dynamic)fieldInfo.GetValue(null); + } + + value = Convert.ChangeType(val, targetType); + } + else + { + FieldInfo fieldInfo = targetType.GetField(inputString, + BindingFlags.Public + | BindingFlags.Static + | BindingFlags.IgnoreCase); + if(fieldInfo == null) + { + throw new NMSException(string.Format( + "Invalid {0} value \"{1}\"", targetType.Name, + inputString)); + } + value = fieldInfo.GetValue(null); + } + } + else + { + // Not an enumeration + value = Convert.ChangeType(inputString, + targetType, CultureInfo.InvariantCulture); + } + return value; + } + + #endregion + + #region Get member information and objects + + /// <summary> + /// Gets member information for a property or field of the target + /// object. + /// </summary> + /// <param name="target">Target object.</param> + /// <param name="name">Property or field name.</param> + /// <returns>Retrieved member information.</returns> + private static MemberInfo FindMemberInfo(object target, string name) + { + BindingFlags flags = BindingFlags.FlattenHierarchy + | BindingFlags.Public + | BindingFlags.Instance + | BindingFlags.IgnoreCase; + + Type type = target.GetType(); + + MemberInfo member = type.GetProperty(name, flags); + + if(member == null) + { + member = type.GetField(name, flags); + } + + return member; + } + + /// <summary> + /// Gets object assigned to the specified property or field member of + /// the target object. + /// </summary> + /// <param name="member">Member information.</param> + /// <param name="target">Target object.</param> + /// <returns>Retrieved object.</returns> + private static object GetUnderlyingObject( + MemberInfo member, object target) + { + object result = null; + + if(member.MemberType == MemberTypes.Field) + { + FieldInfo field = member as FieldInfo; + + if(field.FieldType.IsPrimitive) + { + throw new NMSException(string.Format( + "The field given is a primitive type: {0}", + member.Name)); + } + + result = field.GetValue(target); + } + else + { + PropertyInfo property = member as PropertyInfo; + MethodInfo getter = property.GetGetMethod(); + + if(getter == null) + { + throw new NMSException(string.Format( + "Cannot access member: {0}", + member.Name)); + } + + result = getter.Invoke(target, null); + } + + if(result == null) + { + throw new NMSException(string.Format( + "Could not retrieve the value of member {0}.", + member.Name)); + } + + return result; + } + + #endregion + } +} Added: activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/UriAttributeAttribute.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/UriAttributeAttribute.cs?rev=1723221&view=auto ============================================================================== --- activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/UriAttributeAttribute.cs (added) +++ activemq/activemq-dotnet/Apache.NMS.XMS/trunk/src/main/csharp/Util/UriAttributeAttribute.cs Wed Jan 6 02:19:56 2016 @@ -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; + +namespace Apache.NMS.XMS.Util +{ + /// <summary> + /// Attribute for mapping a URI attribute key to an object's property. + /// </summary> + public class UriAttributeAttribute : System.Attribute + { + private readonly string[] attributeKeys; + + /// <summary> + /// Constructs an <c>UriAttributeAttribute</c> specifying a list + /// of attribute keys. + /// </summary> + /// <param name="keys">URI attribute keys.</param> + public UriAttributeAttribute(params string[] keys) + { + this.attributeKeys = new string[keys.Length]; + for(int k = 0; k < keys.Length; k++) + { + this.attributeKeys[k] = keys[k]; + } + } + + /// <summary> + /// URI attribute keys. + /// </summary> + public string[] AttributeKeys + { + get { return this.attributeKeys; } + } + } +}