root / src / main / scala / gr / grnet / aquarium / util / package.scala @ 16e25d79
History | View | Annotate | Download (6.8 kB)
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 |
37 |
|
38 |
import com.ckkloverdos.maybe.{Failed, MaybeOption, Just, NoVal, Maybe} |
39 |
import java.nio.charset.Charset |
40 |
import java.io.{PrintWriter, StringWriter} |
41 |
import annotation.tailrec |
42 |
|
43 |
|
44 |
/** |
45 |
* Utility functions. |
46 |
* |
47 |
* @author Christos KK Loverdos <loverdos@gmail.com>. |
48 |
*/ |
49 |
package object util { |
50 |
final val UTF_8_Charset = Charset.forName("UTF-8") |
51 |
|
52 |
def tryOption[A](f: => A): Option[A] = { |
53 |
try Some(f) |
54 |
catch { |
55 |
case _: Exception => None |
56 |
} |
57 |
} |
58 |
|
59 |
def withCloseable[C <: { def close(): Unit}, A](c: C)(f: C => A): A = { |
60 |
try { |
61 |
f(c) |
62 |
} finally { |
63 |
c.close() |
64 |
} |
65 |
} |
66 |
|
67 |
def afterLastIndexOf(separator: String, input: String) = { |
68 |
input.substring(input.lastIndexOf(separator) + 1) |
69 |
} |
70 |
/** |
71 |
* Compute the class name excluding any leading packages. |
72 |
* |
73 |
* This is basically the name after the last dot. |
74 |
*/ |
75 |
def shortNameOfClass(theClass: Class[_]): String = { |
76 |
afterLastIndexOf(".", theClass.getName) |
77 |
} |
78 |
|
79 |
/** |
80 |
* Compute the class name excluding any leading packages and any `$` prefixes. |
81 |
* |
82 |
* This is basically the name after the last dot and after any dollar sign. |
83 |
*/ |
84 |
def simpleNameOfClass(theClass: Class[_]): String = { |
85 |
afterLastIndexOf("$", simpleNameOfClass(theClass)) |
86 |
} |
87 |
|
88 |
/** |
89 |
* For the class of the provided object, compute the class name excluding any leading packages. |
90 |
* |
91 |
* This is basically the name after the last dot. |
92 |
* |
93 |
* The `null` value is mapped to string `"null"`. |
94 |
*/ |
95 |
def shortClassNameOf(anyRef: AnyRef): String = { |
96 |
anyRef match { |
97 |
case null => |
98 |
"<null>" |
99 |
case clz: Class[_] => |
100 |
shortNameOfClass(clz) |
101 |
case obj => |
102 |
shortNameOfClass(obj.getClass) |
103 |
} |
104 |
} |
105 |
|
106 |
/** |
107 |
* Compute the class name excluding any leading packages and any `$` prefixes. |
108 |
* |
109 |
* This is basically the name after the last dot and after any dollar sign. |
110 |
*/ |
111 |
def simpleClassNameOf(anyRef: AnyRef) = { |
112 |
afterLastIndexOf("$", shortClassNameOf(anyRef)) |
113 |
} |
114 |
|
115 |
def safeToStringOrNull(obj: AnyRef): String = obj match { |
116 |
case null => null |
117 |
case _ => obj.toString |
118 |
} |
119 |
|
120 |
def displayableObjectInfo(obj: AnyRef): String = { |
121 |
"[%s] %s".format(obj.getClass, obj) |
122 |
} |
123 |
|
124 |
/** |
125 |
* This basically turns an [[scala.Option]] into a [[com.ckkloverdos.maybe.Maybe]] when asking a |
126 |
* [[scala.collection.Map]] for a key. |
127 |
* |
128 |
* @param map The input map. |
129 |
* @param key The key we are interested in. |
130 |
* @tparam A The type of keys. |
131 |
* @tparam B The type of values. |
132 |
* |
133 |
* @return A [[com.ckkloverdos.maybe.Just]] if a value was found, a |
134 |
* [[com.ckkloverdos.maybe.NoVal]] if nothing was found and a |
135 |
* [[com.ckkloverdos.maybe.Failed]] if some error happened. |
136 |
*/ |
137 |
@inline |
138 |
def findFromMapAsMaybe[A, B <: AnyRef](map: scala.collection.Map[A, B], key: A): Maybe[B] = Maybe { |
139 |
map.get(key) match { |
140 |
case Some(value) ⇒ |
141 |
value |
142 |
case None ⇒ |
143 |
null.asInstanceOf[B] |
144 |
} |
145 |
} |
146 |
|
147 |
@inline |
148 |
def findAndRemoveFromMap[A, B <: AnyRef](map: scala.collection.mutable.Map[A, B], key: A): Maybe[B] = Maybe { |
149 |
map.get(key) match { |
150 |
case Some(value) ⇒ |
151 |
map -= key |
152 |
value |
153 |
case None ⇒ |
154 |
null.asInstanceOf[B] |
155 |
} |
156 |
} |
157 |
|
158 |
// Dear scalac. Optimize this. |
159 |
def nspaces(n: Int): String = { |
160 |
("" /: (1 to n)) ((string, _) => string + " ") |
161 |
} |
162 |
|
163 |
def rpad(s: String, size: Int) = { |
164 |
s + nspaces((size - s.length()) max 0) |
165 |
} |
166 |
|
167 |
def maxStringSize[A](trav: Traversable[A]): Int = { |
168 |
(0 /: trav)(_ max _.toString.length) |
169 |
} |
170 |
|
171 |
/** |
172 |
* Given a [[com.ckkloverdos.maybe.Maybe]] that is actually a [[com.ckkloverdos.maybe.Failed]], return the latter. |
173 |
* |
174 |
* Use this only when you are sure what the `maybe` contains, since the methods can break type safety. |
175 |
* |
176 |
* @param maybe |
177 |
* @tparam A |
178 |
* @return |
179 |
*/ |
180 |
def failedForSure[A](maybe: Maybe[A]): Failed = { |
181 |
maybe.asInstanceOf[Failed] |
182 |
} |
183 |
|
184 |
/** |
185 |
* Given a [[com.ckkloverdos.maybe.Maybe]] that is actually a [[com.ckkloverdos.maybe.Just]], return the latter. |
186 |
* |
187 |
* Use this only when you are sure what the `maybe` contains, since the methods can break type safety. |
188 |
* |
189 |
* @param maybe |
190 |
* @tparam A |
191 |
* @return |
192 |
*/ |
193 |
def justForSure[A](maybe: Maybe[A]): Just[A] = { |
194 |
maybe.asInstanceOf[Just[A]] |
195 |
} |
196 |
|
197 |
/** |
198 |
* Transform an array of bytes to a string, assuming UTF-8 encoding. |
199 |
*/ |
200 |
def makeString(bytes: Array[Byte]): String = { |
201 |
new String(bytes, UTF_8_Charset) |
202 |
} |
203 |
|
204 |
/** |
205 |
* Transform a string to an array of bytes, following a UTF-8 decoding scheme. |
206 |
*/ |
207 |
def makeBytes(string: String): Array[Byte] = { |
208 |
string.getBytes(UTF_8_Charset) |
209 |
} |
210 |
|
211 |
/** |
212 |
* Return the stack trace of the given [[java.lang.Throwable]] in the form of [[java.lang.String]]. |
213 |
* |
214 |
* @param t |
215 |
* @return |
216 |
*/ |
217 |
def stringOfStackTrace(t: Throwable): String = { |
218 |
val sw = new StringWriter() |
219 |
val pw = new PrintWriter(sw) |
220 |
|
221 |
t.printStackTrace(pw) |
222 |
pw.flush() |
223 |
pw.close() |
224 |
|
225 |
sw.toString |
226 |
} |
227 |
|
228 |
|
229 |
def chainOfCauses(t: Throwable): List[String] = { |
230 |
import scala.collection.mutable.ListBuffer |
231 |
@tailrec |
232 |
def loop(t: Throwable, buffer: ListBuffer[String]): List[String] = { |
233 |
t match { |
234 |
case null ⇒ |
235 |
buffer.toList |
236 |
|
237 |
case _ ⇒ |
238 |
buffer.append("%s(%s)".format(shortClassNameOf(t), t.getMessage)) |
239 |
loop(t.getCause, buffer) |
240 |
} |
241 |
} |
242 |
|
243 |
loop(t, new ListBuffer[String]) |
244 |
} |
245 |
} |