| // /* |
| // * 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.IO; |
| using System.Xml; |
| using System.Collections; |
| using Apache.NMS.Util; |
| |
| namespace Apache.NMS.Stomp.Protocol |
| { |
| /// <summary> |
| /// Reads / Writes an IPrimitveMap as XML compatible with XStream. |
| /// </summary> |
| public class XmlPrimitiveMapMarshaler : IPrimitiveMapMarshaler |
| { |
| private Encoding encoder = new UTF8Encoding(); |
| |
| public XmlPrimitiveMapMarshaler() : base() |
| { |
| } |
| |
| public XmlPrimitiveMapMarshaler(Encoding encoder) : base() |
| { |
| this.encoder = encoder; |
| } |
| |
| public string Name |
| { |
| get{ return "jms-map-xml"; } |
| } |
| |
| public byte[] Marshal(IPrimitiveMap map) |
| { |
| if(map == null) |
| { |
| return null; |
| } |
| |
| StringBuilder builder = new StringBuilder(); |
| |
| XmlWriterSettings settings = new XmlWriterSettings(); |
| |
| settings.OmitXmlDeclaration = true; |
| settings.Encoding = this.encoder; |
| settings.NewLineHandling = NewLineHandling.None; |
| |
| XmlWriter writer = XmlWriter.Create(builder, settings); |
| |
| writer.WriteStartElement("map"); |
| |
| foreach(String entry in map.Keys) |
| { |
| writer.WriteStartElement("entry"); |
| |
| // Encode the Key <string>key</string> |
| writer.WriteElementString("string", entry); |
| |
| Object value = map[entry]; |
| |
| // Encode the Value <${type}>value</${type}> |
| MarshalPrimitive(writer, value); |
| |
| writer.WriteEndElement(); |
| } |
| |
| writer.WriteEndElement(); |
| writer.Close(); |
| |
| return this.encoder.GetBytes(builder.ToString()); |
| } |
| |
| public IPrimitiveMap Unmarshal(byte[] mapContent) |
| { |
| string xmlString = this.encoder.GetString(mapContent, 0, mapContent.Length); |
| |
| PrimitiveMap result = new PrimitiveMap(); |
| |
| if (xmlString == null || xmlString == "") |
| { |
| return result; |
| } |
| |
| XmlReaderSettings settings = new XmlReaderSettings(); |
| |
| settings.IgnoreComments = true; |
| settings.IgnoreWhitespace = true; |
| settings.IgnoreProcessingInstructions = true; |
| |
| XmlReader reader = XmlReader.Create(new StringReader(xmlString), settings); |
| |
| reader.MoveToContent(); |
| reader.ReadStartElement("map"); |
| |
| while(reader.Name == "entry") |
| { |
| reader.ReadStartElement(); |
| string key = reader.ReadElementContentAsString("string", ""); |
| |
| Object value = null; |
| |
| switch(reader.Name) |
| { |
| case "char": |
| value = Convert.ToChar(reader.ReadElementContentAsString()); |
| reader.ReadEndElement(); |
| break; |
| case "double": |
| value = Convert.ToDouble(reader.ReadElementContentAsString()); |
| reader.ReadEndElement(); |
| break; |
| case "float": |
| value = Convert.ToSingle(reader.ReadElementContentAsString()); |
| reader.ReadEndElement(); |
| break; |
| case "long": |
| value = Convert.ToInt64(reader.ReadElementContentAsString()); |
| reader.ReadEndElement(); |
| break; |
| case "int": |
| value = Convert.ToInt32(reader.ReadElementContentAsString()); |
| reader.ReadEndElement(); |
| break; |
| case "short": |
| value = Convert.ToInt16(reader.ReadElementContentAsString()); |
| reader.ReadEndElement(); |
| break; |
| case "byte": |
| value = (byte) Convert.ToInt16(reader.ReadElementContentAsString()); |
| reader.ReadEndElement(); |
| break; |
| case "boolean": |
| value = Convert.ToBoolean(reader.ReadElementContentAsString()); |
| reader.ReadEndElement(); |
| break; |
| case "byte-array": |
| value = Convert.FromBase64String(reader.ReadElementContentAsString()); |
| reader.ReadEndElement(); |
| break; |
| default: |
| value = reader.ReadElementContentAsString(); |
| reader.ReadEndElement(); |
| break; |
| }; |
| |
| // Now store the value into our new PrimitiveMap. |
| result[key] = value; |
| } |
| |
| reader.Close(); |
| |
| return result; |
| } |
| |
| private void MarshalPrimitive(XmlWriter writer, Object value) |
| { |
| if(value == null) |
| { |
| Console.WriteLine("Null Map Value"); |
| throw new NullReferenceException("PrimitiveMap values should not be Null"); |
| } |
| else if(value is char) |
| { |
| writer.WriteElementString("char", value.ToString()); |
| } |
| else if(value is bool) |
| { |
| writer.WriteElementString("boolean", value.ToString().ToLower()); |
| } |
| else if(value is byte) |
| { |
| writer.WriteElementString("byte", ((Byte) value).ToString()); |
| } |
| else if(value is short) |
| { |
| writer.WriteElementString("short", value.ToString()); |
| } |
| else if(value is int) |
| { |
| writer.WriteElementString("int", value.ToString()); |
| } |
| else if(value is long) |
| { |
| writer.WriteElementString("long", value.ToString()); |
| } |
| else if(value is float) |
| { |
| writer.WriteElementString("float", value.ToString()); |
| } |
| else if(value is double) |
| { |
| writer.WriteElementString("double", value.ToString()); |
| } |
| else if(value is byte[]) |
| { |
| writer.WriteElementString("byte-array", Convert.ToBase64String((byte[]) value)); |
| } |
| else if(value is string) |
| { |
| writer.WriteElementString("string", (string) value); |
| } |
| else if(value is IDictionary) |
| { |
| Console.WriteLine("Can't Marshal a Dictionary"); |
| |
| throw new NotSupportedException("Can't marshal nested Maps in Stomp"); |
| } |
| else if(value is IList) |
| { |
| Console.WriteLine("Can't Marshal a List"); |
| |
| throw new NotSupportedException("Can't marshal nested Maps in Stomp"); |
| } |
| else |
| { |
| Console.WriteLine("Can't Marshal a something other than a Primitive Value."); |
| |
| throw new Exception("Object is not a primitive: " + value); |
| } |
| } |
| } |
| } |