def sysEnv()

in nlpcraft/src/main/scala/org/apache/nlpcraft/internal/util/NCUtils.scala [52:333]


    def sysEnv(s: String): Option[String] = sysProps.get(s).orElse(sys.env.get(s))

    /**
      * Shortcut to convert given JSON to Scala map with default mapping.
      *
      * @param json JSON to convert.
      */
    @throws[Exception]
    def jsonToScalaMap(json: String): Map[String, Object] =
        GSON.fromJson(json, classOf[java.util.HashMap[String, Object]]).asScala.toMap

    /**
      * Shortcut to convert given JSON to Java map with default mapping.
      *
      * @param json JSON to convert.
      */
    def jsonToJavaMap(json: String): java.util.Map[String, Object] =
        try GSON.fromJson(json, classOf[java.util.HashMap[String, Object]])
        catch case e: Exception => E(s"Cannot deserialize JSON to map: '$json'", e)

    /**
      * Gets now in UTC timezone in milliseconds representation.
      */
    def nowUtcMs(): Long = Instant.now().toEpochMilli

    /**
      * Shortcut - current timestamp in milliseconds.
      */
    def now(): Long = System.currentTimeMillis()

    /**
      * Trims each sequence string and filters out empty ones.
      *
      * @param s String to process.
      */
    private def trimFilter(s: Seq[String]): Seq[String] = s.map(_.strip).filter(_.nonEmpty)

    /**
      * Splits, trims and filters empty strings for the given string.
      *
      * @param s String to split.
      * @param sep Separator (regex) to split by.
      */
    def splitTrimFilter(s: String, sep: String): Seq[String] =
        trimFilter(s.split(sep).toIndexedSeq)

    /**
      * Recursively removes quotes from given string.
      *
      * @param s
      */
    @tailrec
    def trimQuotes(s: String): String =
        val z = s.strip
        if z.startsWith("'") && z.endsWith("'") || z.startsWith("\"") && z.endsWith("\"") then
            trimQuotes(z.substring(1, z.length - 1))
        else
            z

    /**
      * Recursively removes quotes and replaces escaped quotes from given string.
      *
      * @param s
      */
    @tailrec
    private def trimEscapesQuotes(s: String): String =
        val z = s.strip
        if z.nonEmpty then
            if z.head == '\'' && z.last == '\'' then
                trimEscapesQuotes(z.substring(1, z.length - 1).replace("\'", "'"))
            else if z.head == '"' && z.last == '"' then
                trimEscapesQuotes(z.substring(1, z.length - 1).replace("\\\"", "\""))
            else
                z
        else
            z

    /**
      * Recursively removes quotes and replaces escaped quotes from given string.
      *
      * @param s
      */
    @tailrec
    def escapesQuotes(s: String): String =
        if s.nonEmpty then
            if s.head == '\'' && s.last == '\'' then
                escapesQuotes(s.substring(1, s.length - 1).replace("\'", "'"))
            else if s.head == '"' && s.last == '"' then
                escapesQuotes(s.substring(1, s.length - 1).replace("\\\"", "\""))
            else
                s
        else
            s

    /**
      * Makes thread.
      *
      * @param name Name.
      * @param body Thread body.
      */
    def mkThread(name: String)(body: Thread => Unit): Thread =
        new Thread(name):
            @volatile private var stopped = false

            override def isInterrupted: Boolean = super.isInterrupted || stopped
            override def interrupt(): Unit =
                stopped = true
                super.interrupt()

            override def run(): Unit =
                logger.trace(s"Thread started: $name")

                try
                    body(this)
                    logger.trace(s"Thread exited: $name")
                catch
                    case _: InterruptedException => logger.trace(s"Thread interrupted: $name")
                    case e: Throwable => logger.warn(s"Unexpected error during '$name' thread execution:", e)
                finally
                    stopped = true

    /**
      *
      * @param prefix
      * @param mdlId
      * @param body
      */
    def mkThread(prefix: String, mdlId: String)(body: Thread => Unit): Thread = mkThread(s"$prefix-@$mdlId")(body)

    /**
      * Gets resource existing flag.
      *
      * @param res Resource.
      */
    def isResource(res: String): Boolean = getClass.getClassLoader.getResourceAsStream(res) != null

    /**
      *
      * @param url URL to check.
      */
    def isUrl(url: String): Boolean =
        try
            new URL(url)
            true
        catch
            case _: MalformedURLException => false

    /**
      *
      * @param path Local file path to check.
      */
    def isFile(path: String): Boolean =
        val f = new File(path)
        f.exists() && f.isFile

    /**
      *
      * @param f
      */
    def isFile(f: File): Boolean = f.exists() && f.isFile

    /**
      *
      * @param src Local filesystem path, resources file or URL.
      */
    def getStream(src: String): InputStream =
        if isFile(src) then new FileInputStream(new File(src))
        else if isResource(src) then
            getClass.getClassLoader.getResourceAsStream(src) match
                case in if in != null => in
                case _ => E(s"Resource not found: $src")
        else if isUrl(src) then new URL(src).openStream()
        else E(s"Source not found or unsupported: $src")

    /**
      * Interrupts thread and waits for its finish.
      *
      * @param t Thread.
      */
    def stopThread(t: Thread): Unit =
        if t != null then
            t.interrupt()
            try t.join()
            catch case _: InterruptedException => logger.trace("Thread joining was interrupted (ignoring).")

    /**
      * Checks duplicated elements in collection.
      *
      * @param list Collection. Note, it should be list.
      * @param seen Checked elements.
      * @see #getDups
      */
    @tailrec
    def containsDups[T](list: List[T], seen: Set[T] = Set.empty[T]): Boolean =
        list match
            case x :: xs => if seen.contains(x) then true else containsDups(xs, seen + x)
            case _ => false

    /**
      * Gets set of duplicate values from given sequence (potentially empty).
      *
      * @param seq Sequence to check for dups from.
      * @tparam T
      * @see #containsDups
      */
    def getDups[T](seq: Seq[T]): Set[T] = seq.diff(seq.distinct).toSet

    /**
      * Gets a sequence without dups. It works by checking for dups first, before creating a new
      * sequence if dups are found. It's more efficient when dups are rare.
      *
      * @param seq Sequence with potential dups.
      */
    def distinct[T](seq: List[T]): List[T] = if containsDups(seq) then seq.distinct else seq

    /**
      *
      * @param s
      */
    def decapitalize(s: String): String = s"${s.head.toLower}${s.tail}"

    /**
      *
      * @param s
      */
    def capitalize(s: String): String = s"${s.head.toUpper}${s.tail}"

    /**
      * Makes absolute path starting from working directory.
      *
      * @param path Path.
      */
    def mkPath(path: String): String = new File(s"${new File("").getAbsolutePath}/$path").getAbsolutePath

    /**
      * Generates read-only text file with given path and strings.
      * Used by text files auto-generators.
      *
      * @param path Path of the output file.
      * @param lines Text data.
      * @param sort Whether to sort output or not.
      */
    def mkTextFile(path: String, lines: scala.Iterable[Any], sort: Boolean = true): Unit =
        val file = new File(path)

        Using.resource(new PrintStream(file)) {
            ps =>
                import java.util.*

                // Could be long for large sequences...
                val seq = if sort then lines.map(_.toString).toSeq.sorted else lines

                ps.println(s"#")
                ps.println(s"# Licensed to the Apache Software Foundation (ASF) under one or more")
                ps.println(s"# contributor license agreements.  See the NOTICE file distributed with")
                ps.println(s"# this work for additional information regarding copyright ownership.")
                ps.println(s"# The ASF licenses this file to You under the Apache License, Version 2.0")
                ps.println(s"# (the 'License'); you may not use this file except in compliance with")
                ps.println(s"# the License.  You may obtain a copy of the License at")
                ps.println(s"#")
                ps.println(s"#      https://www.apache.org/licenses/LICENSE-2.0")
                ps.println(s"#")
                ps.println(s"# Unless required by applicable law or agreed to in writing, software")
                ps.println(s"# distributed under the License is distributed on an 'AS IS' BASIS,")
                ps.println(s"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.")
                ps.println(s"# See the License for the specific language governing permissions and")
                ps.println(s"# limitations under the License.")
                ps.println(s"#")
                ps.println(s"# Auto-generated on: ${new Date()}")
                ps.println(s"# Total lines: ${seq.size}")
                ps.println(s"#")
                ps.println(s"# +-------------------------+")
                ps.println(s"# | DO NOT MODIFY THIS FILE |")
                ps.println(s"# +-------------------------+")
                ps.println(s"#")
                ps.println()

                seq.foreach(ps.println)

                // Make the file as read-only.
                file.setWritable(false, false)
        }