001 /*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements. See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership. The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied. See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 *
020 */
021 package org.apache.qpid.client.message;
022
023 import java.util.Enumeration;
024
025 import javax.jms.JMSException;
026 import javax.jms.MessageFormatException;
027
028 import org.apache.mina.common.ByteBuffer;
029 import org.apache.qpid.AMQPInvalidClassException;
030 import org.apache.qpid.framing.AMQShortString;
031 import org.apache.qpid.framing.FieldTable;
032
033
034 public final class JMSHeaderAdapter
035 {
036 private final FieldTable _headers;
037
038 public JMSHeaderAdapter(FieldTable headers)
039 {
040 _headers = headers;
041 }
042
043
044 public FieldTable getHeaders()
045 {
046 return _headers;
047 }
048
049 public boolean getBoolean(String string) throws JMSException
050 {
051 checkPropertyName(string);
052 Boolean b = getHeaders().getBoolean(string);
053
054 if (b == null)
055 {
056 if (getHeaders().containsKey(string))
057 {
058 Object str = getHeaders().getObject(string);
059
060 if (str == null || !(str instanceof String))
061 {
062 throw new MessageFormatException("getBoolean can't use " + string + " item.");
063 }
064 else
065 {
066 return Boolean.valueOf((String) str);
067 }
068 }
069 else
070 {
071 b = Boolean.valueOf(null);
072 }
073 }
074
075 return b;
076 }
077
078 public boolean getBoolean(AMQShortString string) throws JMSException
079 {
080 checkPropertyName(string);
081 Boolean b = getHeaders().getBoolean(string);
082
083 if (b == null)
084 {
085 if (getHeaders().containsKey(string))
086 {
087 Object str = getHeaders().getObject(string);
088
089 if (str == null || !(str instanceof String))
090 {
091 throw new MessageFormatException("getBoolean can't use " + string + " item.");
092 }
093 else
094 {
095 return Boolean.valueOf((String) str);
096 }
097 }
098 else
099 {
100 b = Boolean.valueOf(null);
101 }
102 }
103
104 return b;
105 }
106
107 public char getCharacter(String string) throws JMSException
108 {
109 checkPropertyName(string);
110 Character c = getHeaders().getCharacter(string);
111
112 if (c == null)
113 {
114 if (getHeaders().isNullStringValue(string))
115 {
116 throw new NullPointerException("Cannot convert null char");
117 }
118 else
119 {
120 throw new MessageFormatException("getChar can't use " + string + " item.");
121 }
122 }
123 else
124 {
125 return (char) c;
126 }
127 }
128
129 public byte[] getBytes(String string) throws JMSException
130 {
131 return getBytes(new AMQShortString(string));
132 }
133
134 public byte[] getBytes(AMQShortString string) throws JMSException
135 {
136 checkPropertyName(string);
137
138 byte[] bs = getHeaders().getBytes(string);
139
140 if (bs == null)
141 {
142 throw new MessageFormatException("getBytes can't use " + string + " item.");
143 }
144 else
145 {
146 return bs;
147 }
148 }
149
150 public byte getByte(String string) throws JMSException
151 {
152 checkPropertyName(string);
153 Byte b = getHeaders().getByte(string);
154 if (b == null)
155 {
156 if (getHeaders().containsKey(string))
157 {
158 Object str = getHeaders().getObject(string);
159
160 if (str == null || !(str instanceof String))
161 {
162 throw new MessageFormatException("getByte can't use " + string + " item.");
163 }
164 else
165 {
166 return Byte.valueOf((String) str);
167 }
168 }
169 else
170 {
171 b = Byte.valueOf(null);
172 }
173 }
174
175 return b;
176 }
177
178 public short getShort(String string) throws JMSException
179 {
180 checkPropertyName(string);
181 Short s = getHeaders().getShort(string);
182
183 if (s == null)
184 {
185 s = Short.valueOf(getByte(string));
186 }
187
188 return s;
189 }
190
191 public int getInteger(String string) throws JMSException
192 {
193 checkPropertyName(string);
194 Integer i = getHeaders().getInteger(string);
195
196 if (i == null)
197 {
198 i = Integer.valueOf(getShort(string));
199 }
200
201 return i;
202 }
203
204 public long getLong(String string) throws JMSException
205 {
206 checkPropertyName(string);
207 Long l = getHeaders().getLong(string);
208
209 if (l == null)
210 {
211 l = Long.valueOf(getInteger(string));
212 }
213
214 return l;
215 }
216
217 public float getFloat(String string) throws JMSException
218 {
219 checkPropertyName(string);
220 Float f = getHeaders().getFloat(string);
221
222 if (f == null)
223 {
224 if (getHeaders().containsKey(string))
225 {
226 Object str = getHeaders().getObject(string);
227
228 if (str == null || !(str instanceof String))
229 {
230 throw new MessageFormatException("getFloat can't use " + string + " item.");
231 }
232 else
233 {
234 return Float.valueOf((String) str);
235 }
236 }
237 else
238 {
239 f = Float.valueOf(null);
240 }
241
242 }
243
244 return f;
245 }
246
247 public double getDouble(String string) throws JMSException
248 {
249 checkPropertyName(string);
250 Double d = getHeaders().getDouble(string);
251
252 if (d == null)
253 {
254 d = Double.valueOf(getFloat(string));
255 }
256
257 return d;
258 }
259
260 public String getString(String string) throws JMSException
261 {
262 checkPropertyName(string);
263 String s = getHeaders().getString(string);
264
265 if (s == null)
266 {
267 if (getHeaders().containsKey(string))
268 {
269 Object o = getHeaders().getObject(string);
270 if (o instanceof byte[])
271 {
272 throw new MessageFormatException("getObject couldn't find " + string + " item.");
273 }
274 else
275 {
276 if (o == null)
277 {
278 return null;
279 }
280 else
281 {
282 s = String.valueOf(o);
283 }
284 }
285 }//else return s // null;
286 }
287
288 return s;
289 }
290
291 public Object getObject(String string) throws JMSException
292 {
293 checkPropertyName(string);
294 return getHeaders().getObject(string);
295 }
296
297 public void setBoolean(AMQShortString string, boolean b) throws JMSException
298 {
299 checkPropertyName(string);
300 getHeaders().setBoolean(string, b);
301 }
302
303 public void setBoolean(String string, boolean b) throws JMSException
304 {
305 checkPropertyName(string);
306 getHeaders().setBoolean(string, b);
307 }
308
309 public void setChar(String string, char c) throws JMSException
310 {
311 checkPropertyName(string);
312 getHeaders().setChar(string, c);
313 }
314
315 public Object setBytes(AMQShortString string, byte[] bytes)
316 {
317 checkPropertyName(string);
318 return getHeaders().setBytes(string, bytes);
319 }
320
321 public Object setBytes(String string, byte[] bytes)
322 {
323 checkPropertyName(string);
324 return getHeaders().setBytes(string, bytes);
325 }
326
327 public Object setBytes(String string, byte[] bytes, int start, int length)
328 {
329 checkPropertyName(string);
330 return getHeaders().setBytes(string, bytes, start, length);
331 }
332
333 public void setByte(String string, byte b) throws JMSException
334 {
335 checkPropertyName(string);
336 getHeaders().setByte(string, b);
337 }
338
339 public void setByte(AMQShortString string, byte b) throws JMSException
340 {
341 checkPropertyName(string);
342 getHeaders().setByte(string, b);
343 }
344
345
346 public void setShort(String string, short i) throws JMSException
347 {
348 checkPropertyName(string);
349 getHeaders().setShort(string, i);
350 }
351
352 public void setInteger(String string, int i) throws JMSException
353 {
354 checkPropertyName(string);
355 getHeaders().setInteger(string, i);
356 }
357
358 public void setInteger(AMQShortString string, int i) throws JMSException
359 {
360 checkPropertyName(string);
361 getHeaders().setInteger(string, i);
362 }
363
364 public void setLong(String string, long l) throws JMSException
365 {
366 checkPropertyName(string);
367 getHeaders().setLong(string, l);
368 }
369
370 public void setFloat(String string, float v) throws JMSException
371 {
372 checkPropertyName(string);
373 getHeaders().setFloat(string, v);
374 }
375
376 public void setDouble(String string, double v) throws JMSException
377 {
378 checkPropertyName(string);
379 getHeaders().setDouble(string, v);
380 }
381
382 public void setString(String string, String string1) throws JMSException
383 {
384 checkPropertyName(string);
385 getHeaders().setString(string, string1);
386 }
387
388 public void setString(AMQShortString string, String string1) throws JMSException
389 {
390 checkPropertyName(string);
391 getHeaders().setString(string, string1);
392 }
393
394 public void setObject(String string, Object object) throws JMSException
395 {
396 checkPropertyName(string);
397 try
398 {
399 getHeaders().setObject(string, object);
400 }
401 catch (AMQPInvalidClassException aice)
402 {
403 MessageFormatException mfe = new MessageFormatException("Only primatives are allowed object is:" + object.getClass());
404 mfe.setLinkedException(aice);
405 throw mfe;
406 }
407 }
408
409 public boolean itemExists(String string) throws JMSException
410 {
411 checkPropertyName(string);
412 return getHeaders().containsKey(string);
413 }
414
415 public Enumeration getPropertyNames()
416 {
417 return getHeaders().getPropertyNames();
418 }
419
420 public void clear()
421 {
422 getHeaders().clear();
423 }
424
425 public boolean propertyExists(AMQShortString propertyName)
426 {
427 checkPropertyName(propertyName);
428 return getHeaders().propertyExists(propertyName);
429 }
430
431 public boolean propertyExists(String propertyName)
432 {
433 checkPropertyName(propertyName);
434 return getHeaders().propertyExists(propertyName);
435 }
436
437 public Object put(Object key, Object value)
438 {
439 checkPropertyName(key.toString());
440 return getHeaders().setObject(key.toString(), value);
441 }
442
443 public Object remove(AMQShortString propertyName)
444 {
445 checkPropertyName(propertyName);
446 return getHeaders().remove(propertyName);
447 }
448
449 public Object remove(String propertyName)
450 {
451 checkPropertyName(propertyName);
452 return getHeaders().remove(propertyName);
453 }
454
455 public boolean isEmpty()
456 {
457 return getHeaders().isEmpty();
458 }
459
460 public void writeToBuffer(ByteBuffer data)
461 {
462 getHeaders().writeToBuffer(data);
463 }
464
465 public Enumeration getMapNames()
466 {
467 return getPropertyNames();
468 }
469
470 protected void checkPropertyName(CharSequence propertyName)
471 {
472 if (propertyName == null)
473 {
474 throw new IllegalArgumentException("Property name must not be null");
475 }
476 else if (propertyName.length() == 0)
477 {
478 throw new IllegalArgumentException("Property name must not be the empty string");
479 }
480
481 checkIdentiferFormat(propertyName);
482 }
483
484 protected void checkIdentiferFormat(CharSequence propertyName)
485 {
486 // JMS requirements 3.5.1 Property Names
487 // Identifiers:
488 // - An identifier is an unlimited-length character sequence that must begin
489 // with a Java identifier start character; all following characters must be Java
490 // identifier part characters. An identifier start character is any character for
491 // which the method Character.isJavaIdentifierStart returns true. This includes
492 // '_' and '$'. An identifier part character is any character for which the
493 // method Character.isJavaIdentifierPart returns true.
494 // - Identifiers cannot be the names NULL, TRUE, or FALSE.
495 // Identifiers cannot be NOT, AND, OR, BETWEEN, LIKE, IN, IS, or
496 // ESCAPE.
497 // Identifiers are either header field references or property references. The
498 // type of a property value in a message selector corresponds to the type
499 // used to set the property. If a property that does not exist in a message is
500 // referenced, its value is NULL. The semantics of evaluating NULL values
501 // in a selector are described in Section 3.8.1.2, Null Values.
502 // The conversions that apply to the get methods for properties do not
503 // apply when a property is used in a message selector expression. For
504 // example, suppose you set a property as a string value, as in the
505 // following:
506 // myMessage.setStringProperty("NumberOfOrders", "2");
507 // The following expression in a message selector would evaluate to false,
508 // because a string cannot be used in an arithmetic expression:
509 // "NumberOfOrders > 1"
510 // Identifiers are case sensitive.
511 // Message header field references are restricted to JMSDeliveryMode,
512 // JMSPriority, JMSMessageID, JMSTimestamp, JMSCorrelationID, and
513 // JMSType. JMSMessageID, JMSCorrelationID, and JMSType values may be
514 // null and if so are treated as a NULL value.
515
516 if (Boolean.getBoolean("strict-jms"))
517 {
518 // JMS start character
519 if (!(Character.isJavaIdentifierStart(propertyName.charAt(0))))
520 {
521 throw new IllegalArgumentException("Identifier '" + propertyName + "' does not start with a valid JMS identifier start character");
522 }
523
524 // JMS part character
525 int length = propertyName.length();
526 for (int c = 1; c < length; c++)
527 {
528 if (!(Character.isJavaIdentifierPart(propertyName.charAt(c))))
529 {
530 throw new IllegalArgumentException("Identifier '" + propertyName + "' contains an invalid JMS identifier character");
531 }
532 }
533
534 // JMS invalid names
535 if ((propertyName.equals("NULL")
536 || propertyName.equals("TRUE")
537 || propertyName.equals("FALSE")
538 || propertyName.equals("NOT")
539 || propertyName.equals("AND")
540 || propertyName.equals("OR")
541 || propertyName.equals("BETWEEN")
542 || propertyName.equals("LIKE")
543 || propertyName.equals("IN")
544 || propertyName.equals("IS")
545 || propertyName.equals("ESCAPE")))
546 {
547 throw new IllegalArgumentException("Identifier '" + propertyName + "' is not allowed in JMS");
548 }
549 }
550
551 }
552 }
|