Add one more conversion and refactor others
[aquarium] / src / main / scala / gr / grnet / aquarium / converter / StdConverters.scala
1 /*
2  * Copyright 2011-2012 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above
13  *      copyright notice, this list of conditions and the following
14  *      disclaimer in the documentation and/or other materials
15  *      provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * The views and conclusions contained in the software and
31  * documentation are those of the authors and should not be
32  * interpreted as representing official policies, either expressed
33  * or implied, of GRNET S.A.
34  */
35
36 package gr.grnet.aquarium.converter
37
38 import net.liftweb.json.JsonAST.JValue
39 import com.ckkloverdos.convert._
40 import gr.grnet.aquarium.util.json.JsonSupport
41 import com.mongodb.util.JSON
42 import com.mongodb.DBObject
43 import xml.NodeSeq
44 import net.liftweb.json.Xml
45
46
47 /**
48  * Every data type conversion happening inside Aquarium is defined here.
49  *
50  * @author Christos KK Loverdos <loverdos@gmail.com>
51  */
52
53 object StdConverters {
54   private[this] final lazy val builder: ConvertersBuilder = {
55     val builder: ConvertersBuilder = new StdConvertersBuilder().registerDefaultConversions()
56
57     // Any ⇒ JValue
58     builder.registerConverter(AnyToJValueConverter)
59
60     // Any ⇒ PrettyJsonTextFormat
61     builder.registerConverter(AnyToPrettyJsonTextConverter)
62
63     // Any ⇒ CompactJsonTextFormat
64     builder.registerConverter(AnyToCompactJsonTextConverter)
65
66     // JsonTextFormat ⇒ AnyRef
67     builder.registerConverter(JsonTextToObjectConverter)
68
69     // JsonSupport ⇒ DBObject
70     builder.registerConverter(JsonSupportToDBObjectConverter)
71
72     // CharSequence ⇒ DBObject
73     builder.registerConverter(CharSequenceToDBObjectConverter)
74
75     // JValue ⇒ NodeSeq
76     builder.registerConverter(JValueToNodeSeqConverter)
77
78     // Array[Byte] ⇒ JsonTextFormat
79     builder.registerConverter(ByteArrayToJsonTextConverter)
80
81     builder
82   }
83
84   object ByteArrayToJsonTextConverter extends StrictSourceConverterSkeleton[Array[Byte], JsonTextFormat] {
85     @throws(classOf[ConverterException])
86     final protected def convertEx_(sourceValue: Array[Byte]) = {
87       JsonTextFormat(JsonConversions.jsonBytesToJson(sourceValue))
88     }
89   }
90
91   object AnyToJValueConverter extends NonStrictSourceConverterSkeleton[Any, JValue] {
92     @throws(classOf[ConverterException])
93     final protected def convertEx_(sourceValue: Any) = {
94       JsonConversions.anyToJValue(sourceValue)(JsonConversions.Formats)
95     }
96   }
97
98   object AnyToPrettyJsonTextConverter extends NonStrictSourceConverterSkeleton[Any, PrettyJsonTextFormat] {
99     @throws(classOf[ConverterException])
100     final protected def convertEx_(sourceValue: Any) = {
101       PrettyJsonTextFormat(JsonConversions.anyToJson(sourceValue, true)(JsonConversions.Formats))
102     }
103   }
104
105   object AnyToCompactJsonTextConverter extends NonStrictSourceConverterSkeleton[Any, CompactJsonTextFormat] {
106     @throws(classOf[ConverterException])
107     final protected def convertEx_(sourceValue: Any) = {
108       CompactJsonTextFormat(JsonConversions.anyToJson(sourceValue, false)(JsonConversions.Formats))
109     }
110   }
111
112   object JsonTextToObjectConverter extends Converter {
113     def isStrictSource = false
114
115     def canConvertType[S: Type, T: Type] = {
116       erasureOf[JsonTextFormat].isAssignableFrom(erasureOf[S])
117     }
118
119     @throws(classOf[ConverterException])
120     def convertEx[T: Type](sourceValue: Any) = {
121       // Generic deserializer from json string to a business logic model
122       JsonConversions.jsonToObject[T](sourceValue.asInstanceOf[JsonTextFormat].value)(manifest[T], JsonConversions.Formats)
123     }
124   }
125
126   object JsonSupportToDBObjectConverter extends NonStrictSourceConverterSkeleton[JsonSupport, DBObject] {
127     @throws(classOf[ConverterException])
128     final protected def convertEx_(sourceValue: JsonSupport) = {
129       JSON.parse(sourceValue.asInstanceOf[JsonSupport].toJsonString).asInstanceOf[DBObject]
130     }
131   }
132
133   object CharSequenceToDBObjectConverter extends NonStrictSourceConverterSkeleton[CharSequence, DBObject] {
134     @throws(classOf[ConverterException])
135     final protected def convertEx_(sourceValue: CharSequence) = {
136       JSON.parse(sourceValue.asInstanceOf[CharSequence].toString).asInstanceOf[DBObject]
137     }
138   }
139
140   object JValueToNodeSeqConverter extends NonStrictSourceConverterSkeleton[JValue, NodeSeq] {
141     @throws(classOf[ConverterException])
142     final protected def convertEx_(sourceValue: JValue) = {
143       Xml.toXml(sourceValue.asInstanceOf[JValue])
144     }
145   }
146
147   final val AllConverters: Converters = builder.build
148 }
149