/
codecs.clj
111 lines (90 loc) · 3.58 KB
/
codecs.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
;; Copyright 2008-2012 Red Hat, Inc, and individual contributors.
;;
;; This is free software; you can redistribute it and/or modify it
;; under the terms of the GNU Lesser General Public License as
;; published by the Free Software Foundation; either version 2.1 of
;; the License, or (at your option) any later version.
;;
;; This software is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; Lesser General Public License for more details.
;;
;; You should have received a copy of the GNU Lesser General Public
;; License along with this software; if not, write to the Free
;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
;; 02110-1301 USA, or see the FSF site: http://www.fsf.org.
(ns immutant.messaging.codecs
(:require [immutant.codecs :as core])
(:use [immutant.messaging.core :only [get-properties]])
(:import [javax.jms BytesMessage TextMessage]))
(def encoding-header-name "__ContentEncoding__")
(defn ^{:private true} set-encoding [^javax.jms.Message msg enc]
(.setStringProperty msg encoding-header-name (name enc))
msg)
(defn get-encoding
"Retrieve the encoding from a JMS message."
[^javax.jms.Message msg]
(keyword (.getStringProperty msg encoding-header-name)))
(defprotocol AsText
"Function for extracting text from a message."
(message-text [message]))
(extend-type BytesMessage
AsText
(message-text [message]
(let [bytes (byte-array (.getBodyLength message))]
(.readBytes message bytes)
(String. bytes))))
(extend-type TextMessage
AsText
(message-text [message]
(.getText message)))
;; Encode
(defmulti encode (fn [_ _ {encoding :encoding}] (or encoding :clojure)))
(defmethod encode :clojure [^javax.jms.Session session message options]
"Stringify a clojure data structure"
(set-encoding
(.createTextMessage session (core/encode message))
:clojure))
(defmethod encode :edn [^javax.jms.Session session message options]
"Stringify an edn data structure"
(set-encoding
(.createTextMessage session (core/encode message :edn))
:edn))
(defmethod encode :json [^javax.jms.Session session message options]
"Stringify a json data structure"
(set-encoding
(.createTextMessage session (core/encode message :json))
:json))
(defmethod encode :text [^javax.jms.Session session message options]
"Treat the payload as a raw String. No encoding is done."
(set-encoding
(.createTextMessage session message)
:text))
;; Decode
(defmulti decode (fn [message] (or (get-encoding message) :text)))
(defmethod decode :clojure [message]
"Turn a string into a clojure data structure"
(core/decode (message-text message)))
(defmethod decode :edn [message]
"Turn a string into an edn data structure"
(core/decode (message-text message) :edn))
(defmethod decode :json [message]
"Turn a string into a json data structure"
(core/decode (message-text message) :json))
(defmethod decode :text [message]
"Treats the message payload as a raw string. No decoding is done."
(message-text message))
(defmethod decode :default [message]
(throw (RuntimeException. (str "Received unknown message encoding: " (get-encoding message)))))
(defn decode-if
"Decodes the given message if decode? is truthy. If the decoded
message is a clojure collection, the properties of the message will
be affixed as metadata"
[decode? msg]
(if decode?
(let [result (decode msg)]
(if (instance? clojure.lang.IObj result)
(with-meta result (get-properties msg))
result))
msg))