JMSHeaderAdapter.java
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 stringthrows 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((Stringstr);
067                 }
068             }
069             else
070             {
071                 b = Boolean.valueOf(null);
072             }
073         }
074 
075         return b;
076     }
077 
078     public boolean getBoolean(AMQShortString stringthrows 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((Stringstr);
096                 }
097             }
098             else
099             {
100                 b = Boolean.valueOf(null);
101             }
102         }
103 
104         return b;
105     }
106 
107     public char getCharacter(String stringthrows 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 (charc;
126         }
127     }
128 
129     public byte[] getBytes(String stringthrows JMSException
130     {
131         return getBytes(new AMQShortString(string));
132     }
133 
134     public byte[] getBytes(AMQShortString stringthrows 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 stringthrows 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((Stringstr);
167                 }
168             }
169             else
170             {
171                 b = Byte.valueOf(null);
172             }
173         }
174 
175         return b;
176     }
177 
178     public short getShort(String stringthrows 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 stringthrows 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 stringthrows 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 stringthrows 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((Stringstr);
235                 }
236             }
237             else
238             {
239                 f = Float.valueOf(null);
240             }
241 
242         }
243 
244         return f;
245     }
246 
247     public double getDouble(String stringthrows 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 stringthrows 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 (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 stringthrows JMSException
292     {
293         checkPropertyName(string);
294         return getHeaders().getObject(string);
295     }
296 
297     public void setBoolean(AMQShortString string, boolean bthrows JMSException
298     {
299         checkPropertyName(string);
300         getHeaders().setBoolean(string, b);
301     }
302 
303     public void setBoolean(String string, boolean bthrows JMSException
304     {
305         checkPropertyName(string);
306         getHeaders().setBoolean(string, b);
307     }
308 
309     public void setChar(String string, char cthrows 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 bthrows JMSException
334     {
335         checkPropertyName(string);
336         getHeaders().setByte(string, b);
337     }
338 
339     public void setByte(AMQShortString string, byte bthrows JMSException
340     {
341         checkPropertyName(string);
342         getHeaders().setByte(string, b);
343     }
344 
345 
346     public void setShort(String string, short ithrows JMSException
347     {
348         checkPropertyName(string);
349         getHeaders().setShort(string, i);
350     }
351 
352     public void setInteger(String string, int ithrows JMSException
353     {
354         checkPropertyName(string);
355         getHeaders().setInteger(string, i);
356     }
357 
358     public void setInteger(AMQShortString string, int ithrows JMSException
359     {
360         checkPropertyName(string);
361         getHeaders().setInteger(string, i);
362     }
363 
364     public void setLong(String string, long lthrows JMSException
365     {
366         checkPropertyName(string);
367         getHeaders().setLong(string, l);
368     }
369 
370     public void setFloat(String string, float vthrows JMSException
371     {
372         checkPropertyName(string);
373         getHeaders().setFloat(string, v);
374     }
375 
376     public void setDouble(String string, double vthrows JMSException
377     {
378         checkPropertyName(string);
379         getHeaders().setDouble(string, v);
380     }
381 
382     public void setString(String string, String string1throws JMSException
383     {
384         checkPropertyName(string);
385         getHeaders().setString(string, string1);
386     }
387 
388     public void setString(AMQShortString string, String string1throws JMSException
389     {
390         checkPropertyName(string);
391         getHeaders().setString(string, string1);
392     }
393 
394     public void setObject(String string, Object objectthrows 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 stringthrows 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 }