1 /***********************************************************************
2  * Copyright (c) 2013-2024 Commonwealth Computer Research, Inc.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Apache License, Version 2.0
5  * which accompanies this distribution and is available at
6  * http://www.opensource.org/licenses/apache2.0.php.
7  ***********************************************************************/
8 
9 package org.locationtech.geomesa.utils
10 
11 import com.typesafe.scalalogging.LazyLogging
12 
13 import scala.util.{Failure, Success}
14 
15 package object io {
16 
17   /**
18    * Closes and logs any exceptions
19    */
20   object CloseWithLogging extends SafeClose with LazyLogging {
21     override def apply[C : IsCloseable](c: C): Option[Throwable] = {
22       implicitly[IsCloseable[C]].close(c) match {
23         case _: Success[Unit] => None
24         case Failure(e) => logger.warn(s"Error calling close on '$c': ", e); Some(e)
25       }
26     }
27   }
28 
29   /**
30    * Closes and catches any exceptions
31    */
32   object CloseQuietly extends SafeClose {
33     override def apply[C : IsCloseable](c: C): Option[Throwable] =
34       implicitly[IsCloseable[C]].close(c).failed.toOption
35   }
36 
37   /**
38    * Flushes and logs any exceptions
39    */
40   object FlushWithLogging extends SafeFlush with LazyLogging {
41     override def apply[F : IsFlushable](f: F): Option[Throwable] = {
42       implicitly[IsFlushable[F]].flush(f) match {
43         case _: Success[Unit] => None
44         case Failure(e) => logger.warn(s"Error calling flush on '$f': ", e); Some(e)
45       }
46     }
47   }
48 
49   /**
50    * Flushes and catches any exceptions
51    */
52   object FlushQuietly extends SafeFlush {
53     override def apply[F : IsFlushable](f: F): Option[Throwable] =
54       implicitly[IsFlushable[F]].flush(f).failed.toOption
55   }
56 
57   /**
58    * Similar to java's try-with-resources, allows for using an object then closing in a finally block
59    */
60   object WithClose {
61 
62     def apply[C : IsCloseable, T](c: C)(fn: C => T): T = {
63       val ev = implicitly[IsCloseable[C]]
64       try { fn(c) } finally { if (c != null) { ev.close(c) }}
65     }
66 
67     def apply[C1 : IsCloseable, C2 : IsCloseable, T](c1: C1, c2: => C2)(fn: (C1, C2) => T): T =
68       apply(c1) { c1 => apply(c2) { c2 => fn(c1, c2) } }
69   }
70 }
Line Stmt Id Pos Tree Symbol Tests Code
22 9220 796 - 831 Apply org.locationtech.geomesa.utils.io.IsCloseable.close scala.Predef.implicitly[org.locationtech.geomesa.utils.io.IsCloseable[C]](evidence$1).close(c)
23 9221 873 - 877 Select scala.None scala.None
23 9222 873 - 877 Block scala.None scala.None
24 9223 955 - 962 Apply scala.Some.apply scala.Some.apply[Throwable](e)
24 9224 902 - 962 Block <nosymbol> { (if (CloseWithLogging.this.logger.underlying.isWarnEnabled()) CloseWithLogging.this.logger.underlying.warn(scala.StringContext.apply("Error calling close on \'", "\': ").s(c), e) else (): Unit); scala.Some.apply[Throwable](e) }
34 9225 1148 - 1199 Select scala.util.Try.toOption scala.Predef.implicitly[org.locationtech.geomesa.utils.io.IsCloseable[C]](evidence$2).close(c).failed.toOption
42 9226 1392 - 1427 Apply org.locationtech.geomesa.utils.io.IsFlushable.flush scala.Predef.implicitly[org.locationtech.geomesa.utils.io.IsFlushable[F]](evidence$3).flush(f)
43 9227 1469 - 1473 Select scala.None scala.None
43 9228 1469 - 1473 Block scala.None scala.None
44 9229 1551 - 1558 Apply scala.Some.apply scala.Some.apply[Throwable](e)
44 9230 1498 - 1558 Block <nosymbol> { (if (FlushWithLogging.this.logger.underlying.isWarnEnabled()) FlushWithLogging.this.logger.underlying.warn(scala.StringContext.apply("Error calling flush on \'", "\': ").s(f), e) else (): Unit); scala.Some.apply[Throwable](e) }
54 9231 1745 - 1796 Select scala.util.Try.toOption scala.Predef.implicitly[org.locationtech.geomesa.utils.io.IsFlushable[F]](evidence$4).flush(f).failed.toOption
63 9232 2012 - 2038 ApplyToImplicitArgs scala.Predef.implicitly scala.Predef.implicitly[org.locationtech.geomesa.utils.io.IsCloseable[C]](evidence$5)
64 9233 2051 - 2056 Apply scala.Function1.apply fn.apply(c)
64 9234 2051 - 2056 Block scala.Function1.apply fn.apply(c)
64 9235 2073 - 2082 Apply scala.Any.!= c.!=(null)
64 9236 2086 - 2097 Apply org.locationtech.geomesa.utils.io.IsCloseable.close ev.close(c)
64 9237 2094 - 2094 Literal <nosymbol> ()
64 9238 2086 - 2097 Block <nosymbol> { ev.close(c); () }
64 9239 2069 - 2069 Literal <nosymbol> ()
64 9240 2069 - 2069 Block <nosymbol> ()
64 9241 2069 - 2099 If <nosymbol> if (c.!=(null)) { ev.close(c); () } else ()
68 9242 2210 - 2260 ApplyToImplicitArgs org.locationtech.geomesa.utils.io.WithClose.apply WithClose.this.apply[C1, T](c1)(((c1: C1) => WithClose.this.apply[C2, T](c2)(((c2: C2) => fn.apply(c1, c2)))(evidence$7)))(evidence$6)