A scala bridge library from apache commons lang3 to scala.
Add dependence into sbt like:
libraryDependencies += "net.scalax" %% "commons-lang3-bridge" % "0.1.0"
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.13.0"
or maven:
<dependency>
<groupId>net.scalax</groupId>
<artifactId>commons-lang3-bridge_3</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.13.0</version>
</dependency>
Commons lang3 bridge support scala 2.11, 2.12, 2.13, 3.1, and 3.2, choice edition by prefix.
Add import in your source:
import commons.lang3.bridge.StringUtils.ops._
Now, you can call commons lang string utils functions as String or Option[String]
's method like:
test("test string substring after last separator char") {
assert(nullString.ops.substringAfterLast(0).isEmpty)
assert(noneString.ops.substringAfterLast('X').isEmpty)
assert("".ops.substringAfterLast(0).contains(""))
assert(Some("").ops.substringAfterLast('a').contains(""))
assert("foo".ops.substringAfterLast(0).contains(""))
assert("foo".ops.substringAfterLast('b').contains(""))
assert(Some("foot").ops.substringAfterLast('o').contains("t"))
assert("abc".ops.substringAfterLast('a').contains("bc"))
assert("abcba".ops.substringAfterLast('b').contains("a"))
assert("abc".ops.substringAfterLast('c').contains(""))
assert("".ops.substringAfterLast('d').contains(""))
}
Apache Commons Lang provides a host of helper utilities for the java.lang API, notably String manipulation methods, basic numerical methods, object reflection, concurrency, creation and serialization and System properties. Additionally it contains basic enhancements to java.util.Date and a series of utilities dedicated to help with building methods, such as hashCode, toString and equals.
Commons Lang3 Bridge is a Scala bridge library. It supported use apache commons lang as scala style.
With Apache Commons StringUtils, we call functions as:
public void testDefaultIfEmpty_StringString() {
assertEquals("NULL", StringUtils.defaultIfEmpty(null, "NULL"));
assertEquals("NULL", StringUtils.defaultIfEmpty("", "NULL"));
assertEquals("abc", StringUtils.defaultIfEmpty("abc", "NULL"));
assertNull(StringUtils.getIfEmpty("", null));
// Tests compatibility for the API return type
final String s = StringUtils.defaultIfEmpty("abc", "NULL");
assertEquals("abc", s);
}
It's strong and power, null safe with all side conditions.
And now, in scala, we add a extern field named ops
for String
and Option[String]
type.
Call the functions like OO style methods:
import org.scalatest.funsuite.AnyFunSuite
// import bridge extensions
import commons.lang3.bridge.StringUtils.ops._
// ...
class StringUtilsSpec extends AnyFunSuite {
// ..
test("test string default if empty with string") {
assert(nullString.ops.defaultIfEmpty("NULL") == "NULL")
assert(Some("").ops.defaultIfEmpty("NULL") == "NULL")
assert("abc".ops.defaultIfEmpty(Some("NULL")) == "abc")
assert("".ops.defaultIfEmpty(null) == null)
// Tests compatibility for the API return type
val s = "abc".ops.defaultIfEmpty("NULL")
assert(s == "abc")
}
}
All StringUtils functions in Apache Commons Lang3 is null safe. And the bridge bundle it as null and None safe.
Specifically:
- All functions return String may null that bridged to returns
Option[String]
- All args accepted a String may null that bridged to accepted
Option[String]
or String. You can choose any way as you wish. The bridged methods auto handle them! - When you see a source in document as
none
, It could be aString
variable as null, or aOption[String]
variable as None. In the bridge core, the powerful TypeMapping mechanism known howto convert it. - Some functions have varargs typed
String[]
. We bridged them as scala varargsSeq[(String|Option[String])]*
. The bridge choice String orOption[String]
what ever your pass in. But they must allString
or allOption[String]
same. Don't mix difference type in one varargs Seq. - Some functions have two String parameters. By the bridge you can call them pass etc.
str.ops.method(String, Option[String])
orstr.ops.method(Option[String], String)
or what ever combinators. Because the parameters have independents type definitions. - Some functions are accepted parameters as
CharSequnces
. By bridged you can passCharSequnces
orOption[CharSequence]
as your wish.
Many methods in bridge (They have written in StringCommons.scala
source) with type parameters like:
def removeEnd[R: Adt.Options2[*, String, Option[String]]](rmv: R): Option[String] = {
val rmvStr = mapToStrOpt.input(rmv).orNull
Option(Strings.removeEnd(strOrNull, rmvStr))
}
The type means a union type String
or Option[String]
.
Not all functions in StringUtils class were been bridged.
We skip something like:
- All deprecated functions
- Something like
isNoneBlank
、isAnyEmpty
and so on. They aren't oo style code have subject, predicate and objects. - All join method. Not only isn't OO style but also scala has powerful string function
mkString
. - Bridge support Union Type definition
(String | Option[String])
,but almost char args just bundled asChar
, withoutOption[Char]
. BecauseChar
is a primitive type. - Some functions received char args as int type. The bridged bundled it as Char or Int.
You need recognize it in scala. - In apache commons, when you pass null literal into functions, them returns result safely.
But the bridged methods need now what's type of them. So pass a null
String
or NoneOption[String]
this safe,null
literal without type is exception.