1 /*----------------------------------------------------------------------------
2 Name: PropTO.cs
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: A generic service approach
6 Author: "Marcel Ruff" <xmlBlaster@marcelruff.info>
7 Date: 04/2007
8 See: http://www.xmlblaster.org/
9 -----------------------------------------------------------------------------*/
10 using System;
11 using System.Collections.Generic;
12 using System.Text;
13 using System.Xml;
14 using System.Xml.Schema;
15 using System.Xml.Serialization;
16
17 namespace org.xmlBlaster.contrib.service {
18 [XmlRootAttribute("prop", IsNullable = false)]
19 public class PropTO : IXmlSerializable {
20
21 //private static NLog.Logger logger = NLog.LogManager.GetLogger("xmlBlaster");
22
23 public static readonly string ENCODING_BASE64 = "base64";
24
25 public static readonly string ENCODING_PLAIN = "";
26
27 public static readonly string KEY_SERVICENAME = "serviceName";
28
29 public static readonly string KEY_TASKTYPE = "taskType";
30
31 public static readonly string KEY_ENCODING = "encoding";
32
33 public static readonly string KEY_TASK = "task";
34
35 /** To send update data */
36 public static readonly string KEY_DATA = "data";
37
38 /** The encoding type of the data prop, "" or "base64" */
39 public static readonly string KEY_DATAENCODING = "dataEncoding";
40
41 public static readonly string VALUE_DATAENCODING_DEFAULT = ENCODING_PLAIN;
42
43
44 public static readonly string KEY_MIME = "mime";
45
46 public static readonly string KEY_RESULTMIME = "resultMime";
47
48 public static readonly string KEY_RESULTENCODING = "resultEncoding";
49
50 public static readonly string KEY_RESULT = "result";
51
52 /** Data from client will be bounced back, e.g. for requestId */
53 public static readonly string KEY_BOUNCE = "bounce";
54
55 public static readonly string VALUE_TASKTYPE_NAMED = "named";
56
57 public static readonly string VALUE_TASKTYPE_EXACT = "exact";
58
59 public static readonly string VALUE_TASKTYPE_XPATH = "xpath";
60
61 public static readonly string VALUE_TASKTYPE_UPDATE = "update";
62
63 // is specific for each service use case
64 //public static readonly string VALUE_SERVICE_BUDDY = "buddy";
65
66 // is specific for each service use case
67 //public static readonly string VALUE_SERVICE_TRACK = "track";
68
69 public static readonly string VALUE_RESULTENCODING_PLAIN = "";
70
71 public static readonly string VALUE_RESULTENCODING_DEFAULT = ENCODING_BASE64;
72
73 // is specific for each service use case
74 //public static readonly string VALUE_RESULTMIME_PREFIX = "application/xmlBlaster.service";
75
76 // is specific for each service use case
77 //public static readonly string VALUE_RESULTMIME_EXCEPTION = "application/xmlBlaster.service.exception";
78
79 public static readonly string PROP = "p"; // tag name
80
81 public static readonly string KEY = "k"; // attribute name
82
83 protected string key;
84
85 protected string value = "";
86
87 // transient: the encoding is tranfered in another PropTO instance
88 protected string encoding;
89
90 public PropTO() {
91 }
92
93 public PropTO(string key, string value) {
94 this.key = key;
95 this.value = value;
96 }
97
98 /// <summary>
99 /// The value will be send as BASE64 encoded.
100 /// IMPORTANT: You have to set an additional property
101 /// service.addProp(new PropTO(PropTO.KEY_DATAENCODING, PropTO.ENCODING_BASE64));
102 /// </summary>
103 /// <param name="key"></param>
104 /// <param name="value"></param>
105 public PropTO(string key, byte[] bytes) /*throws System.FormatException*/ {
106 this.key = key;
107 this.value = System.Convert.ToBase64String(bytes);
108 //logger.Info("Converted '" + bytes.Length + "' to " + this.value);
109 this.encoding = PropTO.ENCODING_BASE64; // transient setting
110 }
111
112 public string GetKey() {
113 return (this.key == null) ? "" : this.key;
114 }
115
116 public void SetKey(string key) {
117 this.key = key;
118 }
119
120 public string GetValueRaw() {
121 return this.value;
122 }
123
124 /// <summary>
125 /// If it was base64 encoded it is converted as UTF-8 string
126 /// </summary>
127 /// <returns>Never null</returns>
128 public string GetValue() {
129 if (this.value == null || this.value.Length < 1) return "";
130 if (!isBase64Encoding()) return this.value;
131
132 try {
133 byte[] dBytes = System.Convert.FromBase64String(this.value);
134 return System.Text.Encoding.UTF8.GetString(dBytes, 0, dBytes.Length);
135 }
136 catch (System.FormatException) {
137 System.Console.WriteLine("Base 64 string length is not " +
138 "4 or is not an even multiple of 4.");
139 return "";
140 }
141 }
142 /**
143 * Returns the raw byte[] of base64 encoding data. If data was of type
144 * String it is returned as UTF-8 bytes.
145 *
146 * @return never null
147 */
148 public byte[] getValueBytes() {
149 if (this.value == null || this.value.Length < 1) return new byte[0];
150 if (isBase64Encoding()) {
151 return System.Convert.FromBase64String(this.value);
152 }
153 return System.Text.Encoding.UTF8.GetBytes(this.value);
154 }
155
156 public void SetValue(string value) {
157 this.value = value;
158 }
159
160 public bool isBase64Encoding() {
161 if (this.encoding == null) return false;
162 return (ENCODING_BASE64.Equals(this.encoding));
163 }
164
165 public void SetEncoding(string encoding) {
166 this.encoding = encoding;
167 }
168
169 public bool getBoolValue() {
170 try {
171 return Boolean.Parse(this.value);
172 }
173 catch (System.FormatException e) {
174 System.Console.WriteLine("Is not a boolean '" + this.value + "' :" + e.ToString());
175 return false;
176 }
177 }
178
179 public static List<PropTO> ReadSiblings(XmlReader reader) {
180 List<PropTO> list = new List<PropTO>();
181 bool found = reader.ReadToDescendant(PROP);
182 if (found) {
183 string taskEncoding = null;
184 string resultEncoding = null;
185 string dataEncoding = null;
186 do {
187 PropTO prop = new PropTO();
188 reader.MoveToAttribute(KEY);
189 prop.SetKey(reader.ReadContentAsString());
190 reader.MoveToContent();
191 /*This method reads the start tag, the contents of the element, and moves the reader past
192 * the end element tag. It expands entities and ignores processing instructions and comments.
193 * The element can only contain simple content. That is, it cannot have child elements.
194 */
195
196 if (resultEncoding != null && PropTO.KEY_RESULT.Equals(prop.GetKey())) {
197 prop.SetEncoding(resultEncoding);
198 }
199 if (taskEncoding != null && PropTO.KEY_TASK.Equals(prop.GetKey())) {
200 prop.SetEncoding(taskEncoding);
201 }
202 if (dataEncoding != null && PropTO.KEY_DATA.Equals(prop.GetKey())) {
203 prop.SetEncoding(dataEncoding);
204 }
205
206 if (resultEncoding == null && PropTO.KEY_RESULT.Equals(prop.GetKey()) ||
207 taskEncoding == null && PropTO.KEY_TASK.Equals(prop.GetKey()) ||
208 dataEncoding == null && PropTO.KEY_DATA.Equals(prop.GetKey())) {
209 // Expect subtags like "<A><B>Hello</B></A>"
210 string tmp = reader.ReadInnerXml();
211 tmp = tmp.Trim();
212 if (tmp.StartsWith("<![CDATA["))
213 { // strip CDATA token
214 tmp = tmp.Substring("<![CDATA[".Length);
215 if (tmp.EndsWith("]]>"))
216 {
217 tmp = tmp.Substring(0, tmp.Length - "]]>".Length);
218 }
219 }
220 else
221 {
222 tmp = org.xmlBlaster.util.XmlBuffer.UnEscape(tmp);
223 }
224 //XmlReader nestedReader = reader.ReadSubtree();
225 //tmp = reader.ReadString(); is empty if contains tags
226 //tmp = reader.Value; is empty if contains tags
227 prop.SetValue(tmp);
228 }
229 else {
230 string val = reader.ReadElementContentAsString();
231 val = org.xmlBlaster.util.XmlBuffer.UnEscape(val);
232 prop.SetValue(val);
233 }
234
235 // Check if base64 encoded (this tag is a previous sibling before the content prop)
236 if (PropTO.KEY_ENCODING.Equals(prop.GetKey())) {
237 taskEncoding = prop.GetValueRaw();
238 }
239 if (PropTO.KEY_RESULTENCODING.Equals(prop.GetKey())) {
240 resultEncoding = prop.GetValueRaw();
241 }
242 if (PropTO.KEY_DATAENCODING.Equals(prop.GetKey())) {
243 dataEncoding = prop.GetValueRaw();
244 }
245
246 list.Add(prop);
247 } while (PROP.Equals(reader.LocalName));//reader.ReadToNextSibling(PROP));
248 }
249 return list;
250 }
251
252 /// <summary>
253 /// If was a string its UTF8 byte[] representation
254 /// If base64 the original byte[]
255 /// </summary>
256 /// <returns>never null</returns>
257 public byte[] GetBlobValue() {
258 if (this.value == null || this.value.Length < 1) return new byte[0];
259 if (!isBase64Encoding()) return System.Text.Encoding.UTF8.GetBytes(this.value);
260 try {
261 return System.Convert.FromBase64String(this.value);
262 }
263 catch (System.FormatException) {
264 System.Console.WriteLine("Base 64 string length is not " +
265 "4 or is not an even multiple of 4.");
266 return new byte[0];
267 }
268 }
269
270 public void ReadXml(XmlReader reader) {
271 reader.ReadToFollowing(PROP);
272 reader.MoveToAttribute(KEY);
273 this.key = reader.ReadContentAsString();
274 reader.MoveToContent();
275 this.value = reader.ReadElementContentAsString();
276 }
277
278 public void WriteXml(XmlWriter writer) {
279 writer.WriteStartElement(PROP);
280 writer.WriteStartAttribute(KEY);
281 writer.WriteValue(GetKey());
282 writer.WriteEndAttribute();
283 writer.WriteRaw(GetValueRaw());
284 writer.WriteEndElement();
285 }
286
287 public XmlSchema GetSchema() {
288 return null;
289 }
290 }
291 }
syntax highlighted by Code2HTML, v. 0.9.1