From 494a0c732d7bd34126bdf04752a8a233248ed78f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bigorajski?= Date: Mon, 21 Oct 2024 21:47:00 +0200 Subject: [PATCH] [NU-1836] Move converters from CONV util to extension methods. Implement generic conversion extension methods: is, to and toOrNull. # Conflicts: # docs/Changelog.md --- .../nussknacker/engine/api/typed/typing.scala | 7 +- .../ui/api/ExpressionSuggesterSpec.scala | 19 +- docs/Changelog.md | 26 +- docs/scenarios_authoring/Spel.md | 33 +- .../resources/extractedTypes/devCreator.json | 2248 ++++++++++++--- .../extractedTypes/defaultModel.json | 2482 +++++++++++++---- .../engine/extension/ArrayExt.scala | 5 +- .../extension/BooleanConversionExt.scala | 48 + .../nussknacker/engine/extension/Cast.scala | 132 - .../extension/CollectionConversionExt.scala | 120 + .../engine/extension/Conversion.scala | 257 ++ .../engine/extension/ConversionExt.scala | 126 + .../engine/extension/ExtensionMethods.scala | 14 +- .../extension/NumericConversionExt.scala | 75 + .../engine/spel/SpelExpression.scala | 2 +- .../engine/spel/SpelExpressionSuggester.scala | 24 +- .../touk/nussknacker/engine/spel/Typer.scala | 9 +- .../internal/OptimizedEvaluationContext.scala | 6 +- .../engine/util/classes/Extensions.scala | 41 +- ...tionExpressionParameterValidatorTest.scala | 1 - .../extension/ExtensionMethodsSpec.scala | 53 +- .../engine/spel/SpelExpressionSpec.scala | 422 ++- .../engine/util/classes/ExtensionsSpec.scala | 30 - .../engine/util/functions/conversion.scala | 128 - .../util/functions/ConversionUtilsSpec.scala | 115 - 25 files changed, 4925 insertions(+), 1498 deletions(-) create mode 100644 scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/BooleanConversionExt.scala delete mode 100644 scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/Cast.scala create mode 100644 scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/CollectionConversionExt.scala create mode 100644 scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/Conversion.scala create mode 100644 scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ConversionExt.scala create mode 100644 scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/NumericConversionExt.scala delete mode 100644 scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/util/classes/ExtensionsSpec.scala diff --git a/components-api/src/main/scala/pl/touk/nussknacker/engine/api/typed/typing.scala b/components-api/src/main/scala/pl/touk/nussknacker/engine/api/typed/typing.scala index 3b3dd862693..ca5cbde9597 100644 --- a/components-api/src/main/scala/pl/touk/nussknacker/engine/api/typed/typing.scala +++ b/components-api/src/main/scala/pl/touk/nussknacker/engine/api/typed/typing.scala @@ -83,7 +83,7 @@ object typing { fields.map { case (fieldName, fieldType) => fieldName -> fieldType.withoutValue }, - runtimeObjType, + runtimeObjType.withoutValue, additionalInfo ) @@ -206,7 +206,7 @@ object typing { case class TypedClass private[typing] (klass: Class[_], params: List[TypingResult]) extends SingleTypingResult { override val valueOpt: None.type = None - override def withoutValue: TypedClass = this + override def withoutValue: TypedClass = TypedClass(klass, params.map(_.withoutValue)) override def display: String = { val className = if (klass.isArray) "List" else ReflectUtils.simpleNameWithoutSuffix(runtimeObjType.klass) @@ -353,8 +353,9 @@ object typing { supertypeOfElementTypes(javaList.asScala.toList).withoutValue, javaList ) + case set: java.util.Set[_] => + genericTypeClass(classOf[java.util.Set[_]], List(supertypeOfElementTypes(set.asScala.toList))) case typeFromInstance: TypedFromInstance => typeFromInstance.typingResult - // TODO: handle more types, for example Set case other => Typed(other.getClass) match { case typedClass: TypedClass => diff --git a/designer/server/src/test/scala/pl/touk/nussknacker/ui/api/ExpressionSuggesterSpec.scala b/designer/server/src/test/scala/pl/touk/nussknacker/ui/api/ExpressionSuggesterSpec.scala index 3f10b979f96..1a22aebb0f8 100644 --- a/designer/server/src/test/scala/pl/touk/nussknacker/ui/api/ExpressionSuggesterSpec.scala +++ b/designer/server/src/test/scala/pl/touk/nussknacker/ui/api/ExpressionSuggesterSpec.scala @@ -780,17 +780,14 @@ class ExpressionSuggesterSpec } test("should suggest parameters for casts methods") { - spelSuggestionsFor("#unknown.canCastTo('')", column = 20) should contain theSameElementsAs List( - suggestion("String", Typed[String]), - suggestion("Duration", Typed[Duration]), - suggestion("LocalDateTime", Typed[LocalDateTime]), - suggestion("Map", Typed[java.util.Map[_, _]]), - suggestion("A", Typed[A]), - suggestion("AA", Typed[AA]), - suggestion("B", Typed[B]), - suggestion("C", Typed[C]), - suggestion("Util", Typed[Util]), - suggestion("WithList", Typed[WithList]), + spelSuggestionsFor("#unknown.to('')", column = 13) should contain theSameElementsAs List( + suggestion("BigDecimal", Typed[java.math.BigDecimal]), + suggestion("Boolean", Typed[java.lang.Boolean]), + suggestion("Double", Typed[java.lang.Double]), + suggestion("Long", Typed[java.lang.Long]), + suggestion("String", Typed[java.lang.String]), + suggestion("List", Typed.genericTypeClass[java.util.List[_]](List(Unknown))), + suggestion("Map", Typed.genericTypeClass[java.util.Map[_, _]](List(Unknown, Unknown))), ) } diff --git a/docs/Changelog.md b/docs/Changelog.md index b4fea16d22d..326942f308b 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -31,21 +31,7 @@ * [#6750](https://github.com/TouK/nussknacker/pull/6750) Add varargs to `#COLLECTION.concat` and `#COLLECTION.merge`. * [#6778](https://github.com/TouK/nussknacker/pull/6778) SpeL: check for methods if a property for a given name does not exist. * [#6769](https://github.com/TouK/nussknacker/pull/6769) Added possibility to choose presets and define lists for Long typed parameter inputs in fragments. -* [#6807](https://github.com/TouK/nussknacker/pull/6807) Add conversion functions to primitives to: `#CONV`: - * toNumberOrNull - * toString - * toBoolean - * toBooleanOrNull - * toInteger - * toIntegerOrNull - * toLong - * toLongOrNull - * toDouble - * toDoubleOrNull - * toBigInteger - * toBigIntegerOrNull - * toBigDecimal - * toBigDecimalOrNull +* [#6807](https://github.com/TouK/nussknacker/pull/6807) Add `toNumberOrNull` conversion function, to `#CONV`. * [#6995](https://github.com/TouK/nussknacker/pull/6995) Add `toJson` and `toJsonString` conversions (in the `#CONV` helper) * [#6995](https://github.com/TouK/nussknacker/pull/6995) Add `#BASE64` helper to decode/encode Base64 values * [#6826](https://github.com/TouK/nussknacker/pull/6826) Security fix: added validation of expression used inside @@ -71,12 +57,20 @@ * [#6925](https://github.com/TouK/nussknacker/pull/6925) Fix situation when preset labels were presented as `null` when node didn't pass the validation. * [#6935](https://github.com/TouK/nussknacker/pull/6935) Spel: Scenario labels added to meta variable - `#meta.scenarioLabels` * [#6952](https://github.com/TouK/nussknacker/pull/6952) Improvement: TypeInformation support for scala.Option -* [#6840](https://github.com/TouK/nussknacker/pull/6840) Introduce canCastTo, castTo and castToOrNull extension methods in SpeL. * [#6974](https://github.com/TouK/nussknacker/pull/6974) Add SpeL suggestions for cast methods parameter. * [#6958](https://github.com/TouK/nussknacker/pull/6958) Add message size limit in the "Kafka" exceptionHandler * [#6988](https://github.com/TouK/nussknacker/pull/6988) Remove unused API classes: `MultiMap`, `TimestampedEvictableStateFunction` * [#7000](https://github.com/TouK/nussknacker/pull/7000) Show all possible options for dictionary editor on open. * [#6979](https://github.com/TouK/nussknacker/pull/6979) Introduces an activities panel that provides information about all system activities. +* [#7063](https://github.com/TouK/nussknacker/pull/7063) Introduce is, to and toOrNull conversion extension methods in + SpeL. +* [#7063](https://github.com/TouK/nussknacker/pull/7063) SpeL: add conversion to primitives extension methods: + * isBoolean/toBoolean/toBooleanOrNull + * isLong/toLong/toLongOrNull + * isDouble/toDouble/toDoubleOrNull + * isBigDecimal/toBigDecimal/toBigDecimalOrNull + * isList/toList/toListOrNull - a collection or unknown collection can be converted to a list. + * isMap/toMap/toMapOrNull - the list of key-value pairs or unknown map can be converted to a map. ## 1.17 diff --git a/docs/scenarios_authoring/Spel.md b/docs/scenarios_authoring/Spel.md index 350655b5059..5cad8fbc1a6 100644 --- a/docs/scenarios_authoring/Spel.md +++ b/docs/scenarios_authoring/Spel.md @@ -199,12 +199,13 @@ person2 = name: "John"; age: 24 listOfPersons = {person1, person2} ``` -| Expression | Result | Type | -| ------------ | -------- | -------- | -| `{1,2,3,4}.![#this * 2]` | {2, 4, 6, 8} | List[Integer] | -| `#listOfPersons.![#this.name]` | {'Alex', 'John'} | List[String] | -| `#listOfPersons.![#this.age]` | {42, 24} | List[Integer] | -| `#listOfPersons.![7]` | {7, 7} | List[Integer] | +| Expression | Result | Type | +|-----------------------------------------------------------------|----------------------|----------------------| +| `{1,2,3,4}.![#this * 2]` | {2, 4, 6, 8} | List[Integer] | +| `#listOfPersons.![#this.name]` | {'Alex', 'John'} | List[String] | +| `#listOfPersons.![#this.age]` | {42, 24} | List[Integer] | +| `#listOfPersons.![7]` | {7, 7} | List[Integer] | +| `#listOfPersons.![{key: #this.name, value: #this.age}].toMap()` | {Alex: 42, John: 24} | Map[String, Integer] | For other operations on lists, please see the `#COLLECTION` [helper](#built-in-helpers). @@ -278,12 +279,20 @@ More usage examples can be found in [this section](#conversions-between-datetime Explicit conversions are available in utility classes and build-in java conversion mechanisms: -| Expression | Result | Type | -|-----------------------------------------------------------------|----------------------------|-----------------| -| `#NUMERIC.toNumber('42')` | 42 | Number | -| `#NUMERIC.toNumber('42').toString()` | '42' | String | -| `#DATE_FORMAT.parseOffsetDateTime('2018-10-23T12:12:13+00:00')` | 1540296720000 | OffsetDateTime | -| `#DATE_FORMAT.parseLocalDateTime('2018-10-23T12:12:13')` | 2018-10-23T12:12:13+00:00 | LocalDateTime | +| Expression | Result | Type | +|-----------------------------------------------------------------|---------------------------|----------------| +| `#NUMERIC.toNumber('42')` | 42 | Number | +| `#NUMERIC.toNumber('42').toString()` | '42' | String | +| `#DATE_FORMAT.parseOffsetDateTime('2018-10-23T12:12:13+00:00')` | 1540296720000 | OffsetDateTime | +| `#DATE_FORMAT.parseLocalDateTime('2018-10-23T12:12:13')` | 2018-10-23T12:12:13+00:00 | LocalDateTime | +| `'true'.toBoolean` | true | Boolean | +| `'11'.toLong` | 11 | Long | +| `'1.1'.toDouble` | 1.1 | Double | +| `2.1.toBigDecimal` | 2.1 | BigDecimal | + +Functions which start with `to`, e.g. `toBoolean`, have their equivalents: +- to check if a given value can be converted to appropriate type, e.g. `'true'.isBoolean`. +- and to return null if conversion fails, e.g. `'false'.toBooleanOrNull'`. ### Casting diff --git a/engine/flink/management/dev-model/src/test/resources/extractedTypes/devCreator.json b/engine/flink/management/dev-model/src/test/resources/extractedTypes/devCreator.json index 9d98ae655e8..e2e4e35921c 100644 --- a/engine/flink/management/dev-model/src/test/resources/extractedTypes/devCreator.json +++ b/engine/flink/management/dev-model/src/test/resources/extractedTypes/devCreator.json @@ -89,6 +89,30 @@ } } ], + "isList": [ + { + "description": "Check whether can be convert to a list", + "name": "isList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "isMap": [ + { + "description": "Check whether can be convert to a map", + "name": "isMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "lastIndexOf": [ { "name": "lastIndexOf", @@ -109,6 +133,54 @@ } } ], + "toList": [ + { + "description": "Convert to a list or throw exception in case of failure", + "name": "toList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toListOrNull": [ + { + "description": "Convert to a list or null in case of failure", + "name": "toListOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMap": [ + { + "description": "Convert to a map or throw exception in case of failure", + "name": "toMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMapOrNull": [ + { + "description": "Convert to a map or null in case of failure", + "name": "toMapOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -824,6 +896,50 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "longValue": [ { "name": "longValue", @@ -842,6 +958,94 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -1013,48 +1217,6 @@ { "clazzName": {"refClazzName": "java.lang.CharSequence"}, "methods": { - "canCastTo": [ - { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castTo": [ - { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castToOrNull": [ - { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], "charAt": [ { "name": "charAt", @@ -1191,6 +1353,40 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isInfinite": [ { "name": "isInfinite", @@ -1200,6 +1396,16 @@ } } ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isNaN": [ { "name": "isNaN", @@ -1236,65 +1442,153 @@ } } ], - "toString": [ + "to": [ { - "name": "toString", + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.String"} + "result": {"refClazzName": "java.math.BigDecimal"} } } - ] - }, - "staticMethods": { - "BYTES": [ + ], + "toBigDecimalOrNull": [ { - "name": "BYTES", + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.math.BigDecimal"} } } ], - "MAX_EXPONENT": [ + "toDouble": [ { - "name": "MAX_EXPONENT", + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Double"} } } ], - "MAX_VALUE": [ + "toDoubleOrNull": [ { - "name": "MAX_VALUE", + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", "signature": { "noVarArgs": [], "result": {"refClazzName": "java.lang.Double"} } } ], - "MIN_EXPONENT": [ + "toLong": [ { - "name": "MIN_EXPONENT", + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Long"} } } ], - "MIN_NORMAL": [ + "toLongOrNull": [ { - "name": "MIN_NORMAL", + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Double"} + "result": {"refClazzName": "java.lang.Long"} } } ], - "MIN_VALUE": [ + "toOrNull": [ { - "name": "MIN_VALUE", + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toString": [ + { + "name": "toString", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.String"} + } + } + ] + }, + "staticMethods": { + "BYTES": [ + { + "name": "BYTES", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "MAX_EXPONENT": [ + { + "name": "MAX_EXPONENT", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "MAX_VALUE": [ + { + "name": "MAX_VALUE", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "MIN_EXPONENT": [ + { + "name": "MIN_EXPONENT", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "MIN_NORMAL": [ + { + "name": "MIN_NORMAL", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "MIN_VALUE": [ + { + "name": "MIN_VALUE", "signature": { "noVarArgs": [], "result": {"refClazzName": "java.lang.Double"} @@ -1574,6 +1868,40 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isInfinite": [ { "name": "isInfinite", @@ -1583,6 +1911,16 @@ } } ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isNaN": [ { "name": "isNaN", @@ -1619,6 +1957,94 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -1948,114 +2374,246 @@ } } ], - "longValue": [ + "is": [ { - "name": "longValue", - "signature": { - "noVarArgs": [], - "result": {"refClazzName": "java.lang.Long"} - } + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] } ], - "shortValue": [ + "isBigDecimal": [ { - "name": "shortValue", + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Short"} + "result": {"refClazzName": "java.lang.Boolean"} } } ], - "toString": [ + "isDouble": [ { - "name": "toString", + "description": "Check whether can be convert to a Double", + "name": "isDouble", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.String"} + "result": {"refClazzName": "java.lang.Boolean"} } } - ] - }, - "staticMethods": { - "BYTES": [ + ], + "isLong": [ { - "name": "BYTES", + "description": "Check whether can be convert to a Long", + "name": "isLong", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Boolean"} } } ], - "MAX_VALUE": [ + "longValue": [ { - "name": "MAX_VALUE", + "name": "longValue", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Long"} } } ], - "MIN_VALUE": [ + "shortValue": [ { - "name": "MIN_VALUE", + "name": "shortValue", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Short"} } } ], - "SIZE": [ + "to": [ { - "name": "SIZE", + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.math.BigDecimal"} } } ], - "bitCount": [ + "toBigDecimalOrNull": [ { - "name": "bitCount", + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", "signature": { - "noVarArgs": [ - {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}} - ], - "result": {"refClazzName": "java.lang.Integer"} + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} } } ], - "compare": [ + "toDouble": [ { - "name": "compare", + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", "signature": { - "noVarArgs": [ - {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}}, - {"name": "arg1", "refClazz": {"refClazzName": "java.lang.Integer"}} - ], - "result": {"refClazzName": "java.lang.Integer"} + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} } } ], - "compareUnsigned": [ + "toDoubleOrNull": [ { - "name": "compareUnsigned", + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", "signature": { - "noVarArgs": [ - {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}}, - {"name": "arg1", "refClazz": {"refClazzName": "java.lang.Integer"}} - ], - "result": {"refClazzName": "java.lang.Integer"} + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} } } ], - "decode": [ + "toLong": [ { - "name": "decode", + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", "signature": { - "noVarArgs": [ - {"name": "arg0", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"refClazzName": "java.lang.Integer"} + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toString": [ + { + "name": "toString", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.String"} + } + } + ] + }, + "staticMethods": { + "BYTES": [ + { + "name": "BYTES", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "MAX_VALUE": [ + { + "name": "MAX_VALUE", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "MIN_VALUE": [ + { + "name": "MIN_VALUE", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "SIZE": [ + { + "name": "SIZE", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "bitCount": [ + { + "name": "bitCount", + "signature": { + "noVarArgs": [ + {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}} + ], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "compare": [ + { + "name": "compare", + "signature": { + "noVarArgs": [ + {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}}, + {"name": "arg1", "refClazz": {"refClazzName": "java.lang.Integer"}} + ], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "compareUnsigned": [ + { + "name": "compareUnsigned", + "signature": { + "noVarArgs": [ + {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}}, + {"name": "arg1", "refClazz": {"refClazzName": "java.lang.Integer"}} + ], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "decode": [ + { + "name": "decode", + "signature": { + "noVarArgs": [ + {"name": "arg0", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"refClazzName": "java.lang.Integer"} } } ], @@ -2484,6 +3042,50 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "longValue": [ { "name": "longValue", @@ -2502,6 +3104,94 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -2962,10 +3652,173 @@ } } ], - "canCastTo": [ + "doubleValue": [ + { + "name": "doubleValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "floatValue": [ + { + "name": "floatValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Float"} + } + } + ], + "intValue": [ + { + "name": "intValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "longValue": [ + { + "name": "longValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "shortValue": [ + { + "name": "shortValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Short"} + } + } + ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", "signatures": [ { "noVarArgs": [ @@ -2976,10 +3829,25 @@ ] } ], - "castTo": [ + "toString": [ { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", + "name": "toString", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.String"} + } + } + ] + }, + "staticMethods": {} + }, + { + "clazzName": {"type": "Unknown"}, + "methods": { + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", "signatures": [ { "noVarArgs": [ @@ -2990,10 +3858,74 @@ ] } ], - "castToOrNull": [ + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isBoolean": [ { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", + "description": "Check whether can be convert to a Boolean", + "name": "isBoolean", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isList": [ + { + "description": "Check whether can be convert to a list", + "name": "isList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isMap": [ + { + "description": "Check whether can be convert to a map", + "name": "isMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", "signatures": [ { "noVarArgs": [ @@ -3004,98 +3936,138 @@ ] } ], - "doubleValue": [ + "toBigDecimal": [ { - "name": "doubleValue", + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Double"} + "result": {"refClazzName": "java.math.BigDecimal"} } } ], - "floatValue": [ + "toBigDecimalOrNull": [ { - "name": "floatValue", + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Float"} + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBoolean": [ + { + "description": "Convert to Boolean or throw exception in case of failure", + "name": "toBoolean", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "toBooleanOrNull": [ + { + "description": "Convert to Boolean or null in case of failure", + "name": "toBooleanOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} } } ], - "intValue": [ + "toDouble": [ { - "name": "intValue", + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Double"} } } ], - "longValue": [ + "toDoubleOrNull": [ { - "name": "longValue", + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Long"} + "result": {"refClazzName": "java.lang.Double"} } } ], - "shortValue": [ + "toList": [ { - "name": "shortValue", + "description": "Convert to a list or throw exception in case of failure", + "name": "toList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toListOrNull": [ + { + "description": "Convert to a list or null in case of failure", + "name": "toListOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Short"} + "result": {"refClazzName": "java.lang.Long"} } } ], - "toString": [ + "toLongOrNull": [ { - "name": "toString", + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.String"} + "result": {"refClazzName": "java.lang.Long"} } } - ] - }, - "staticMethods": {} - }, - { - "clazzName": {"type": "Unknown"}, - "methods": { - "canCastTo": [ + ], + "toMap": [ { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", + "description": "Convert to a map or throw exception in case of failure", + "name": "toMap", "signatures": [ { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], + "noVarArgs": [], "result": {"type": "Unknown"} } ] } ], - "castTo": [ + "toMapOrNull": [ { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", + "description": "Convert to a map or null in case of failure", + "name": "toMapOrNull", "signatures": [ { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], + "noVarArgs": [], "result": {"type": "Unknown"} } ] } ], - "castToOrNull": [ + "toOrNull": [ { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", "signatures": [ { "noVarArgs": [ @@ -3177,6 +4149,50 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "longValue": [ { "name": "longValue", @@ -3195,6 +4211,94 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -3521,6 +4625,30 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isBlank": [ { "name": "isBlank", @@ -3530,6 +4658,26 @@ } } ], + "isBoolean": [ + { + "description": "Check whether can be convert to a Boolean", + "name": "isBoolean", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isEmpty": [ { "name": "isEmpty", @@ -3539,6 +4687,16 @@ } } ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "lastIndexOf": [ { "name": "lastIndexOf", @@ -3755,6 +4913,100 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBoolean": [ + { + "description": "Convert to Boolean or throw exception in case of failure", + "name": "toBoolean", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "toBooleanOrNull": [ + { + "description": "Convert to Boolean or null in case of failure", + "name": "toBooleanOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], "toLowerCase": [ { "name": "toLowerCase", @@ -3773,6 +5025,20 @@ } } ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -4112,6 +5378,50 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "longValue": [ { "name": "longValue", @@ -4412,6 +5722,40 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], "toBigInteger": [ { "name": "toBigInteger", @@ -4430,6 +5774,26 @@ } } ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], "toEngineeringString": [ { "name": "toEngineeringString", @@ -4439,6 +5803,40 @@ } } ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toPlainString": [ { "name": "toPlainString", @@ -4819,6 +6217,50 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isProbablePrime": [ { "name": "isProbablePrime", @@ -5094,6 +6536,40 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], "toByteArray": [ { "name": "toByteArray", @@ -5113,6 +6589,60 @@ } } ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -10013,72 +11543,30 @@ "ofYears": [ { "name": "ofYears", - "signature": { - "noVarArgs": [ - {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}} - ], - "result": {"refClazzName": "java.time.Period"} - } - } - ], - "parse": [ - { - "name": "parse", - "signature": { - "noVarArgs": [ - {"name": "arg0", "refClazz": {"refClazzName": "java.lang.CharSequence"}} - ], - "result": {"refClazzName": "java.time.Period"} - } - } - ] - } - }, - { - "clazzName": {"refClazzName": "java.time.ZoneId"}, - "methods": { - "canCastTo": [ - { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castTo": [ - { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castToOrNull": [ - { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] + "signature": { + "noVarArgs": [ + {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}} + ], + "result": {"refClazzName": "java.time.Period"} + } } ], + "parse": [ + { + "name": "parse", + "signature": { + "noVarArgs": [ + {"name": "arg0", "refClazz": {"refClazzName": "java.lang.CharSequence"}} + ], + "result": {"refClazzName": "java.time.Period"} + } + } + ] + } + }, + { + "clazzName": {"refClazzName": "java.time.ZoneId"}, + "methods": { "getDisplayName": [ { "name": "getDisplayName", @@ -11402,48 +12890,6 @@ { "clazzName": {"refClazzName": "java.time.temporal.Temporal"}, "methods": { - "canCastTo": [ - { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castTo": [ - { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castToOrNull": [ - { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], "toString": [ { "name": "toString", @@ -11469,48 +12915,6 @@ "refClazzName": "java.util.Collection" }, "methods": { - "canCastTo": [ - { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castTo": [ - { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castToOrNull": [ - { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], "contains": [ { "name": "contains", @@ -11564,6 +12968,30 @@ } } ], + "isList": [ + { + "description": "Check whether can be convert to a list", + "name": "isList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "isMap": [ + { + "description": "Check whether can be convert to a map", + "name": "isMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "size": [ { "name": "size", @@ -11573,6 +13001,54 @@ } } ], + "toList": [ + { + "description": "Convert to a list or throw exception in case of failure", + "name": "toList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toListOrNull": [ + { + "description": "Convert to a list or null in case of failure", + "name": "toListOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMap": [ + { + "description": "Convert to a map or throw exception in case of failure", + "name": "toMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMapOrNull": [ + { + "description": "Convert to a map or null in case of failure", + "name": "toMapOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -11700,6 +13176,30 @@ } } ], + "isList": [ + { + "description": "Check whether can be convert to a list", + "name": "isList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "isMap": [ + { + "description": "Check whether can be convert to a map", + "name": "isMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "lastIndexOf": [ { "name": "lastIndexOf", @@ -11720,6 +13220,54 @@ } } ], + "toList": [ + { + "description": "Convert to a list or throw exception in case of failure", + "name": "toList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toListOrNull": [ + { + "description": "Convert to a list or null in case of failure", + "name": "toListOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMap": [ + { + "description": "Convert to a map or throw exception in case of failure", + "name": "toMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMapOrNull": [ + { + "description": "Convert to a map or null in case of failure", + "name": "toMapOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -11947,6 +13495,30 @@ } } ], + "isList": [ + { + "description": "Check whether can be convert to a list", + "name": "isList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "isMap": [ + { + "description": "Check whether can be convert to a map", + "name": "isMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "size": [ { "name": "size", @@ -11956,6 +13528,54 @@ } } ], + "toList": [ + { + "description": "Convert to a list or throw exception in case of failure", + "name": "toList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toListOrNull": [ + { + "description": "Convert to a list or null in case of failure", + "name": "toListOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMap": [ + { + "description": "Convert to a map or throw exception in case of failure", + "name": "toMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMapOrNull": [ + { + "description": "Convert to a map or null in case of failure", + "name": "toMapOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", diff --git a/engine/flink/tests/src/test/resources/extractedTypes/defaultModel.json b/engine/flink/tests/src/test/resources/extractedTypes/defaultModel.json index c12d863707c..6f4deceb66e 100644 --- a/engine/flink/tests/src/test/resources/extractedTypes/defaultModel.json +++ b/engine/flink/tests/src/test/resources/extractedTypes/defaultModel.json @@ -89,6 +89,30 @@ } } ], + "isList": [ + { + "description": "Check whether can be convert to a list", + "name": "isList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "isMap": [ + { + "description": "Check whether can be convert to a map", + "name": "isMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "lastIndexOf": [ { "name": "lastIndexOf", @@ -109,6 +133,54 @@ } } ], + "toList": [ + { + "description": "Convert to a list or throw exception in case of failure", + "name": "toList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toListOrNull": [ + { + "description": "Convert to a list or null in case of failure", + "name": "toListOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMap": [ + { + "description": "Convert to a map or throw exception in case of failure", + "name": "toMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMapOrNull": [ + { + "description": "Convert to a map or null in case of failure", + "name": "toMapOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -344,6 +416,50 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "longValue": [ { "name": "longValue", @@ -362,6 +478,94 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -533,48 +737,6 @@ { "clazzName": {"refClazzName": "java.lang.CharSequence"}, "methods": { - "canCastTo": [ - { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castTo": [ - { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castToOrNull": [ - { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], "charAt": [ { "name": "charAt", @@ -656,48 +818,6 @@ "refClazzName": "java.lang.Comparable" }, "methods": { - "canCastTo": [ - { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castTo": [ - { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castToOrNull": [ - { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], "toString": [ { "name": "toString", @@ -778,51 +898,183 @@ } } ], - "isInfinite": [ + "is": [ { - "name": "isInfinite", + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", "signature": { "noVarArgs": [], "result": {"refClazzName": "java.lang.Boolean"} } } ], - "isNaN": [ + "isDouble": [ { - "name": "isNaN", + "description": "Check whether can be convert to a Double", + "name": "isDouble", "signature": { "noVarArgs": [], "result": {"refClazzName": "java.lang.Boolean"} } } ], - "longValue": [ + "isInfinite": [ { - "name": "longValue", + "name": "isInfinite", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Long"} + "result": {"refClazzName": "java.lang.Boolean"} } } ], - "naN": [ + "isLong": [ { - "name": "naN", + "description": "Check whether can be convert to a Long", + "name": "isLong", "signature": { "noVarArgs": [], "result": {"refClazzName": "java.lang.Boolean"} } } ], - "shortValue": [ + "isNaN": [ { - "name": "shortValue", + "name": "isNaN", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Short"} + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "longValue": [ + { + "name": "longValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "naN": [ + { + "name": "naN", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "shortValue": [ + { + "name": "shortValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Short"} + } + } + ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} } } ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -1161,6 +1413,40 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isInfinite": [ { "name": "isInfinite", @@ -1170,6 +1456,16 @@ } } ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isNaN": [ { "name": "isNaN", @@ -1206,6 +1502,94 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -1535,65 +1919,197 @@ } } ], - "longValue": [ + "is": [ { - "name": "longValue", - "signature": { - "noVarArgs": [], - "result": {"refClazzName": "java.lang.Long"} - } + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] } ], - "shortValue": [ + "isBigDecimal": [ { - "name": "shortValue", + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Short"} + "result": {"refClazzName": "java.lang.Boolean"} } } ], - "toString": [ + "isDouble": [ { - "name": "toString", + "description": "Check whether can be convert to a Double", + "name": "isDouble", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.String"} + "result": {"refClazzName": "java.lang.Boolean"} } } - ] - }, - "staticMethods": { - "BYTES": [ + ], + "isLong": [ { - "name": "BYTES", + "description": "Check whether can be convert to a Long", + "name": "isLong", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Boolean"} } } ], - "MAX_VALUE": [ + "longValue": [ { - "name": "MAX_VALUE", + "name": "longValue", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Long"} } } ], - "MIN_VALUE": [ + "shortValue": [ { - "name": "MIN_VALUE", + "name": "shortValue", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Short"} } } ], - "SIZE": [ + "to": [ { - "name": "SIZE", + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toString": [ + { + "name": "toString", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.String"} + } + } + ] + }, + "staticMethods": { + "BYTES": [ + { + "name": "BYTES", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "MAX_VALUE": [ + { + "name": "MAX_VALUE", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "MIN_VALUE": [ + { + "name": "MIN_VALUE", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "SIZE": [ + { + "name": "SIZE", "signature": { "noVarArgs": [], "result": {"refClazzName": "java.lang.Integer"} @@ -2071,6 +2587,50 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "longValue": [ { "name": "longValue", @@ -2089,6 +2649,94 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -2549,10 +3197,37 @@ } } ], - "canCastTo": [ + "doubleValue": [ + { + "name": "doubleValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "floatValue": [ { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", + "name": "floatValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Float"} + } + } + ], + "intValue": [ + { + "name": "intValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", "signatures": [ { "noVarArgs": [ @@ -2563,10 +3238,58 @@ ] } ], - "castTo": [ + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "longValue": [ + { + "name": "longValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "shortValue": [ + { + "name": "shortValue", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Short"} + } + } + ], + "to": [ { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", "signatures": [ { "noVarArgs": [ @@ -2577,10 +3300,70 @@ ] } ], - "castToOrNull": [ + "toBigDecimal": [ { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", "signatures": [ { "noVarArgs": [ @@ -2591,98 +3374,245 @@ ] } ], - "doubleValue": [ + "toString": [ { - "name": "doubleValue", + "name": "toString", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Double"} + "result": {"refClazzName": "java.lang.String"} } } + ] + }, + "staticMethods": {} + }, + { + "clazzName": {"type": "Unknown"}, + "methods": { + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } ], - "floatValue": [ + "isBigDecimal": [ { - "name": "floatValue", + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Float"} + "result": {"refClazzName": "java.lang.Boolean"} } } ], - "intValue": [ + "isBoolean": [ { - "name": "intValue", + "description": "Check whether can be convert to a Boolean", + "name": "isBoolean", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Boolean"} } } ], - "longValue": [ + "isDouble": [ { - "name": "longValue", + "description": "Check whether can be convert to a Double", + "name": "isDouble", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Long"} + "result": {"refClazzName": "java.lang.Boolean"} } } ], - "shortValue": [ + "isList": [ { - "name": "shortValue", + "description": "Check whether can be convert to a list", + "name": "isList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isMap": [ + { + "description": "Check whether can be convert to a map", + "name": "isMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBoolean": [ + { + "description": "Convert to Boolean or throw exception in case of failure", + "name": "toBoolean", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "toBooleanOrNull": [ + { + "description": "Convert to Boolean or null in case of failure", + "name": "toBooleanOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toList": [ + { + "description": "Convert to a list or throw exception in case of failure", + "name": "toList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toListOrNull": [ + { + "description": "Convert to a list or null in case of failure", + "name": "toListOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Short"} + "result": {"refClazzName": "java.lang.Long"} } } ], - "toString": [ + "toLongOrNull": [ { - "name": "toString", + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.String"} + "result": {"refClazzName": "java.lang.Long"} } } - ] - }, - "staticMethods": {} - }, - { - "clazzName": {"type": "Unknown"}, - "methods": { - "canCastTo": [ + ], + "toMap": [ { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", + "description": "Convert to a map or throw exception in case of failure", + "name": "toMap", "signatures": [ { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], + "noVarArgs": [], "result": {"type": "Unknown"} } ] } ], - "castTo": [ + "toMapOrNull": [ { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", + "description": "Convert to a map or null in case of failure", + "name": "toMapOrNull", "signatures": [ { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], + "noVarArgs": [], "result": {"type": "Unknown"} } ] } ], - "castToOrNull": [ + "toOrNull": [ { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", "signatures": [ { "noVarArgs": [ @@ -2764,6 +3694,50 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "longValue": [ { "name": "longValue", @@ -2782,6 +3756,94 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -3108,6 +4170,30 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isBlank": [ { "name": "isBlank", @@ -3117,6 +4203,26 @@ } } ], + "isBoolean": [ + { + "description": "Check whether can be convert to a Boolean", + "name": "isBoolean", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isEmpty": [ { "name": "isEmpty", @@ -3126,6 +4232,16 @@ } } ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "lastIndexOf": [ { "name": "lastIndexOf", @@ -3303,42 +4419,136 @@ } } ], - "stripLeading": [ + "stripLeading": [ + { + "name": "stripLeading", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.String"} + } + } + ], + "stripTrailing": [ + { + "name": "stripTrailing", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.String"} + } + } + ], + "substring": [ + { + "name": "substring", + "signature": { + "noVarArgs": [ + {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}} + ], + "result": {"refClazzName": "java.lang.String"} + } + }, + { + "name": "substring", + "signature": { + "noVarArgs": [ + {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}}, + {"name": "arg1", "refClazz": {"refClazzName": "java.lang.Integer"}} + ], + "result": {"refClazzName": "java.lang.String"} + } + } + ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBoolean": [ + { + "description": "Convert to Boolean or throw exception in case of failure", + "name": "toBoolean", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "toBooleanOrNull": [ + { + "description": "Convert to Boolean or null in case of failure", + "name": "toBooleanOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "toDouble": [ { - "name": "stripLeading", + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.String"} + "result": {"refClazzName": "java.lang.Double"} } } ], - "stripTrailing": [ + "toDoubleOrNull": [ { - "name": "stripTrailing", + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.String"} + "result": {"refClazzName": "java.lang.Double"} } } ], - "substring": [ + "toLong": [ { - "name": "substring", + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", "signature": { - "noVarArgs": [ - {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}} - ], - "result": {"refClazzName": "java.lang.String"} + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} } - }, + } + ], + "toLongOrNull": [ { - "name": "substring", + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", "signature": { - "noVarArgs": [ - {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}}, - {"name": "arg1", "refClazz": {"refClazzName": "java.lang.Integer"}} - ], - "result": {"refClazzName": "java.lang.String"} + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} } } ], @@ -3360,6 +4570,20 @@ } } ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -3699,6 +4923,50 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "longValue": [ { "name": "longValue", @@ -3999,6 +5267,40 @@ } } ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], + "toBigDecimalOrNull": [ + { + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} + } + } + ], "toBigInteger": [ { "name": "toBigInteger", @@ -4017,6 +5319,26 @@ } } ], + "toDouble": [ + { + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], + "toDoubleOrNull": [ + { + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} + } + } + ], "toEngineeringString": [ { "name": "toEngineeringString", @@ -4026,6 +5348,40 @@ } } ], + "toLong": [ + { + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], "toPlainString": [ { "name": "toPlainString", @@ -4406,6 +5762,50 @@ } } ], + "is": [ + { + "description": "Checks if a type can be converted to a given class", + "name": "is", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "isBigDecimal": [ + { + "description": "Check whether can be convert to a BigDecimal", + "name": "isBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isDouble": [ + { + "description": "Check whether can be convert to a Double", + "name": "isDouble", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "isLong": [ + { + "description": "Check whether can be convert to a Long", + "name": "isLong", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], "isProbablePrime": [ { "name": "isProbablePrime", @@ -4627,30 +6027,105 @@ "name": "signum", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "sqrt": [ + { + "name": "sqrt", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigInteger"} + } + } + ], + "sqrtAndRemainder": [ + { + "name": "sqrtAndRemainder", + "signature": { + "noVarArgs": [], + "result": { + "params": [ + { + "display": "BigInteger", + "params": [], + "refClazzName": "java.math.BigInteger", + "type": "TypedClass" + } + ], + "refClazzName": "[Ljava.lang.Object;" + } + } + } + ], + "subtract": [ + { + "name": "subtract", + "signature": { + "noVarArgs": [ + {"name": "arg0", "refClazz": {"refClazzName": "java.math.BigInteger"}} + ], + "result": {"refClazzName": "java.math.BigInteger"} + } + } + ], + "testBit": [ + { + "name": "testBit", + "signature": { + "noVarArgs": [ + {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}} + ], + "result": {"refClazzName": "java.lang.Boolean"} + } + } + ], + "to": [ + { + "description": "Converts a type to a given class or throws exception if type cannot be converted.", + "name": "to", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} + ], + "result": {"type": "Unknown"} + } + ] + } + ], + "toBigDecimal": [ + { + "description": "Convert to BigDecimal or throw exception in case of failure", + "name": "toBigDecimal", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.math.BigDecimal"} } } ], - "sqrt": [ + "toBigDecimalOrNull": [ { - "name": "sqrt", + "description": "Convert to BigDecimal or null in case of failure", + "name": "toBigDecimalOrNull", "signature": { "noVarArgs": [], - "result": {"refClazzName": "java.math.BigInteger"} + "result": {"refClazzName": "java.math.BigDecimal"} } } ], - "sqrtAndRemainder": [ + "toByteArray": [ { - "name": "sqrtAndRemainder", + "name": "toByteArray", "signature": { "noVarArgs": [], "result": { "params": [ { - "display": "BigInteger", + "display": "Byte", "params": [], - "refClazzName": "java.math.BigInteger", + "refClazzName": "java.lang.Byte", "type": "TypedClass" } ], @@ -4659,45 +6134,58 @@ } } ], - "subtract": [ + "toDouble": [ { - "name": "subtract", + "description": "Convert to Double or throw exception in case of failure", + "name": "toDouble", "signature": { - "noVarArgs": [ - {"name": "arg0", "refClazz": {"refClazzName": "java.math.BigInteger"}} - ], - "result": {"refClazzName": "java.math.BigInteger"} + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} } } ], - "testBit": [ + "toDoubleOrNull": [ { - "name": "testBit", + "description": "Convert to Double or null in case of failure", + "name": "toDoubleOrNull", "signature": { - "noVarArgs": [ - {"name": "arg0", "refClazz": {"refClazzName": "java.lang.Integer"}} - ], - "result": {"refClazzName": "java.lang.Boolean"} + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Double"} } } ], - "toByteArray": [ + "toLong": [ { - "name": "toByteArray", + "description": "Convert to Long or throw exception in case of failure", + "name": "toLong", "signature": { "noVarArgs": [], - "result": { - "params": [ - { - "display": "Byte", - "params": [], - "refClazzName": "java.lang.Byte", - "type": "TypedClass" - } + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toLongOrNull": [ + { + "description": "Convert to Long or null in case of failure", + "name": "toLongOrNull", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Long"} + } + } + ], + "toOrNull": [ + { + "description": "Converts a type to a given class or return null if type cannot be converted.", + "name": "toOrNull", + "signatures": [ + { + "noVarArgs": [ + {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} ], - "refClazzName": "[Ljava.lang.Object;" + "result": {"type": "Unknown"} } - } + ] } ], "toString": [ @@ -9639,48 +11127,6 @@ { "clazzName": {"refClazzName": "java.time.ZoneId"}, "methods": { - "canCastTo": [ - { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castTo": [ - { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castToOrNull": [ - { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], "getDisplayName": [ { "name": "getDisplayName", @@ -11722,48 +13168,6 @@ { "clazzName": {"refClazzName": "java.time.temporal.Temporal"}, "methods": { - "canCastTo": [ - { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castTo": [ - { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castToOrNull": [ - { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], "toString": [ { "name": "toString", @@ -11779,48 +13183,6 @@ { "clazzName": {"refClazzName": "java.time.temporal.TemporalAccessor"}, "methods": { - "canCastTo": [ - { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castTo": [ - { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castToOrNull": [ - { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], "toString": [ { "name": "toString", @@ -11846,48 +13208,6 @@ "refClazzName": "java.util.Collection" }, "methods": { - "canCastTo": [ - { - "description": "Checks if a type can be cast to a given class", - "name": "canCastTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castTo": [ - { - "description": "Casts a type to a given class or throws exception if type cannot be cast.", - "name": "castTo", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], - "castToOrNull": [ - { - "description": "Casts a type to a given class or return null if type cannot be cast.", - "name": "castToOrNull", - "signatures": [ - { - "noVarArgs": [ - {"name": "className", "refClazz": {"refClazzName": "java.lang.String"}} - ], - "result": {"type": "Unknown"} - } - ] - } - ], "contains": [ { "name": "contains", @@ -11941,13 +13261,85 @@ } } ], + "isList": [ + { + "description": "Check whether can be convert to a list", + "name": "isList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "isMap": [ + { + "description": "Check whether can be convert to a map", + "name": "isMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "size": [ { - "name": "size", - "signature": { - "noVarArgs": [], - "result": {"refClazzName": "java.lang.Integer"} - } + "name": "size", + "signature": { + "noVarArgs": [], + "result": {"refClazzName": "java.lang.Integer"} + } + } + ], + "toList": [ + { + "description": "Convert to a list or throw exception in case of failure", + "name": "toList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toListOrNull": [ + { + "description": "Convert to a list or null in case of failure", + "name": "toListOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMap": [ + { + "description": "Convert to a map or throw exception in case of failure", + "name": "toMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMapOrNull": [ + { + "description": "Convert to a map or null in case of failure", + "name": "toMapOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] } ], "toString": [ @@ -12077,6 +13469,30 @@ } } ], + "isList": [ + { + "description": "Check whether can be convert to a list", + "name": "isList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "isMap": [ + { + "description": "Check whether can be convert to a map", + "name": "isMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "lastIndexOf": [ { "name": "lastIndexOf", @@ -12097,6 +13513,54 @@ } } ], + "toList": [ + { + "description": "Convert to a list or throw exception in case of failure", + "name": "toList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toListOrNull": [ + { + "description": "Convert to a list or null in case of failure", + "name": "toListOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMap": [ + { + "description": "Convert to a map or throw exception in case of failure", + "name": "toMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMapOrNull": [ + { + "description": "Convert to a map or null in case of failure", + "name": "toMapOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -12339,6 +13803,30 @@ } } ], + "isList": [ + { + "description": "Check whether can be convert to a list", + "name": "isList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "isMap": [ + { + "description": "Check whether can be convert to a map", + "name": "isMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "size": [ { "name": "size", @@ -12348,6 +13836,54 @@ } } ], + "toList": [ + { + "description": "Convert to a list or throw exception in case of failure", + "name": "toList", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toListOrNull": [ + { + "description": "Convert to a list or null in case of failure", + "name": "toListOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMap": [ + { + "description": "Convert to a map or throw exception in case of failure", + "name": "toMap", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], + "toMapOrNull": [ + { + "description": "Convert to a map or null in case of failure", + "name": "toMapOrNull", + "signatures": [ + { + "noVarArgs": [], + "result": {"type": "Unknown"} + } + ] + } + ], "toString": [ { "name": "toString", @@ -14141,126 +15677,6 @@ } } ], - "toBigDecimal": [ - { - "description": "Convert any value to BigDecimal or throw exception in case of failure", - "name": "toBigDecimal", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.math.BigDecimal"} - } - } - ], - "toBigDecimalOrNull": [ - { - "description": "Convert any value to BigDecimal or null in case of failure", - "name": "toBigDecimalOrNull", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.math.BigDecimal"} - } - } - ], - "toBigInteger": [ - { - "description": "Convert any value to BigInteger or throw exception in case of failure", - "name": "toBigInteger", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.math.BigInteger"} - } - } - ], - "toBigIntegerOrNull": [ - { - "description": "Convert any value to BigInteger or null in case of failure", - "name": "toBigIntegerOrNull", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.math.BigInteger"} - } - } - ], - "toBoolean": [ - { - "description": "Convert any value to Boolean or throw exception in case of failure", - "name": "toBoolean", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.lang.Boolean"} - } - } - ], - "toBooleanOrNull": [ - { - "description": "Convert any value to Boolean or throw exception in case of failure", - "name": "toBooleanOrNull", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.lang.Boolean"} - } - } - ], - "toDouble": [ - { - "description": "Convert any value to Double or throw exception in case of failure", - "name": "toDouble", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.lang.Double"} - } - } - ], - "toDoubleOrNull": [ - { - "description": "Convert any value to Double or null in case of failure", - "name": "toDoubleOrNull", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.lang.Double"} - } - } - ], - "toInteger": [ - { - "description": "Convert any value to Integer or throw exception in case of failure", - "name": "toInteger", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.lang.Integer"} - } - } - ], - "toIntegerOrNull": [ - { - "description": "Convert any value to Integer or null in case of failure", - "name": "toIntegerOrNull", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.lang.Integer"} - } - } - ], "toJson": [ { "description": "Convert String value to JSON", @@ -14297,30 +15713,6 @@ } } ], - "toLong": [ - { - "description": "Convert any value to Long or throw exception in case of failure", - "name": "toLong", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.lang.Long"} - } - } - ], - "toLongOrNull": [ - { - "description": "Convert any value to Long or null in case of failure", - "name": "toLongOrNull", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.lang.Long"} - } - } - ], "toNumber": [ { "description": "Parse string to number", @@ -14365,18 +15757,6 @@ "result": {"refClazzName": "java.lang.Number"} } } - ], - "toString": [ - { - "description": "Convert any value to String", - "name": "toString", - "signature": { - "noVarArgs": [ - {"name": "value", "refClazz": {"type": "Unknown"}} - ], - "result": {"refClazzName": "java.lang.String"} - } - } ] }, "staticMethods": {} diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ArrayExt.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ArrayExt.scala index f2cfb5747bd..e5dc2f462a4 100644 --- a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ArrayExt.scala +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ArrayExt.scala @@ -25,10 +25,7 @@ object ArrayExt extends ExtensionMethodsHandler { override type ExtensionMethodInvocationTarget = ArrayExt override val invocationTargetClass: Class[ArrayExt] = classOf[ArrayExt] - override def createConverter( - classLoader: ClassLoader, - set: ClassDefinitionSet - ): ToExtensionMethodInvocationTargetConverter[ArrayExt] = + override def createConverter(): ToExtensionMethodInvocationTargetConverter[ArrayExt] = (target: Any) => new ArrayExt(target) override def extractDefinitions(clazz: Class[_], set: ClassDefinitionSet): Map[String, List[MethodDefinition]] = diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/BooleanConversionExt.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/BooleanConversionExt.scala new file mode 100644 index 00000000000..a7030dde1bb --- /dev/null +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/BooleanConversionExt.scala @@ -0,0 +1,48 @@ +package pl.touk.nussknacker.engine.extension + +import pl.touk.nussknacker.engine.api.generics.MethodTypeInfo +import pl.touk.nussknacker.engine.api.typed.typing.Typed +import pl.touk.nussknacker.engine.definition.clazz.{ClassDefinitionSet, MethodDefinition, StaticMethodDefinition} + +import java.lang.{Boolean => JBoolean} + +class BooleanConversionExt(target: Any) { + def isBoolean(): JBoolean = BooleanConversion.canConvert(target) + def toBoolean(): JBoolean = BooleanConversion.convert(target) + def toBooleanOrNull(): JBoolean = BooleanConversion.convertOrNull(target) +} + +object BooleanConversionExt extends ExtensionMethodsHandler { + private val stringClass = classOf[String] + private val unknownClass = classOf[Object] + private val allowedClassesForDefinitions: Set[Class[_]] = Set(stringClass, unknownClass) + private val booleanTyping = Typed.typedClass[JBoolean] + + private val definition = StaticMethodDefinition( + signature = MethodTypeInfo( + noVarArgs = Nil, + varArg = None, + result = booleanTyping + ), + name = "", + description = None + ) + + private val definitions = List( + definition.copy(name = "isBoolean", description = Some("Check whether can be convert to a Boolean")), + definition.copy(name = "toBoolean", description = Some("Convert to Boolean or throw exception in case of failure")), + definition.copy(name = "toBooleanOrNull", description = Some("Convert to Boolean or null in case of failure")), + ).groupBy(_.name) + + override type ExtensionMethodInvocationTarget = BooleanConversionExt + override val invocationTargetClass: Class[BooleanConversionExt] = classOf[BooleanConversionExt] + + override def createConverter(): ToExtensionMethodInvocationTargetConverter[BooleanConversionExt] = + (target: Any) => new BooleanConversionExt(target) + + override def extractDefinitions(clazz: Class[_], set: ClassDefinitionSet): Map[String, List[MethodDefinition]] = + if (allowedClassesForDefinitions.contains(clazz)) definitions + else Map.empty + + override def applies(clazz: Class[_]): Boolean = true +} diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/Cast.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/Cast.scala deleted file mode 100644 index ca0ff138286..00000000000 --- a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/Cast.scala +++ /dev/null @@ -1,132 +0,0 @@ -package pl.touk.nussknacker.engine.extension - -import cats.data.ValidatedNel -import cats.implicits.catsSyntaxValidatedId -import pl.touk.nussknacker.engine.api.generics.{GenericFunctionTypingError, MethodTypeInfo, Parameter} -import pl.touk.nussknacker.engine.api.typed.typing -import pl.touk.nussknacker.engine.api.typed.typing.{Typed, TypedObjectWithValue, TypingResult, Unknown} -import pl.touk.nussknacker.engine.definition.clazz.{ClassDefinitionSet, FunctionalMethodDefinition, MethodDefinition} -import pl.touk.nussknacker.engine.util.Implicits.RichScalaMap -import pl.touk.nussknacker.engine.util.classes.Extensions.{ClassExtensions, ClassesExtensions} - -import scala.util.Try - -class Cast(target: Any, classLoader: ClassLoader, classesBySimpleName: Map[String, Class[_]]) { - - def canCastTo(className: String): Boolean = - getClass(className) match { - case Some(clazz) => clazz.isAssignableFrom(target.getClass) - case None => false - } - - def castTo[T](className: String): T = castToEither[T](className) match { - case Left(ex) => throw ex - case Right(value) => value - } - - def castToOrNull[T >: Null](className: String): T = castToEither[T](className) match { - case Right(value) => value - case _ => null - } - - private def castToEither[T](className: String): Either[Throwable, T] = - getClass(className) match { - case Some(clazz) if clazz.isInstance(target) => Try(clazz.cast(target).asInstanceOf[T]).toEither - case _ => Left(new ClassCastException(s"Cannot cast: ${target.getClass} to: $className")) - } - - private def getClass(name: String): Option[Class[_]] = classesBySimpleName.get(name) match { - case Some(clazz) => Some(clazz) - case None => Try(classLoader.loadClass(name)).toOption - } - -} - -object Cast extends ExtensionMethodsHandler { - private val canCastToMethodName = "canCastTo" - private val castToMethodName = "castTo" - private val castToOrNullMethodName = "castToOrNull" - private val stringClass = classOf[String] - - private val methodTypeInfoWithStringParam = MethodTypeInfo( - noVarArgs = List( - Parameter("className", Typed.genericTypeClass(stringClass, Nil)) - ), - varArg = None, - result = Unknown - ) - - private val castMethodsNames = Set( - canCastToMethodName, - castToMethodName, - castToOrNullMethodName, - ) - - override type ExtensionMethodInvocationTarget = Cast - override val invocationTargetClass: Class[Cast] = classOf[Cast] - - def isCastMethod(methodName: String): Boolean = - castMethodsNames.contains(methodName) - - override def createConverter( - classLoader: ClassLoader, - set: ClassDefinitionSet - ): ToExtensionMethodInvocationTargetConverter[Cast] = { - val classesBySimpleName = set.classDefinitionsMap.keySet.classesBySimpleNamesRegardingClashes() - (target: Any) => new Cast(target, classLoader, classesBySimpleName) - } - - override def extractDefinitions(clazz: Class[_], set: ClassDefinitionSet): Map[String, List[MethodDefinition]] = - clazz - .findAllowedClassesForCastParameter(set) - .mapValuesNow(_.clazzName) match { - case allowedClasses if allowedClasses.isEmpty => Map.empty - case allowedClasses => definitions(allowedClasses) - } - - // Cast method should visible in runtime for every class because we allow invoke cast method on an unknown object - // in Typer, but in the runtime the same type could be known and that's why should add cast method for an every class. - override def applies(clazz: Class[_]): Boolean = true - - private def definitions(allowedClasses: Map[Class[_], TypingResult]): Map[String, List[MethodDefinition]] = - List( - FunctionalMethodDefinition( - (_, x) => canCastToTyping(allowedClasses)(x), - methodTypeInfoWithStringParam, - Cast.canCastToMethodName, - Some("Checks if a type can be cast to a given class") - ), - FunctionalMethodDefinition( - (_, x) => castToTyping(allowedClasses)(x), - methodTypeInfoWithStringParam, - Cast.castToMethodName, - Some("Casts a type to a given class or throws exception if type cannot be cast.") - ), - FunctionalMethodDefinition( - (_, x) => castToTyping(allowedClasses)(x), - methodTypeInfoWithStringParam, - Cast.castToOrNullMethodName, - Some("Casts a type to a given class or return null if type cannot be cast.") - ), - ).groupBy(_.name) - - private def castToTyping(allowedClasses: Map[Class[_], TypingResult])( - arguments: List[typing.TypingResult] - ): ValidatedNel[GenericFunctionTypingError, typing.TypingResult] = arguments match { - case TypedObjectWithValue(_, clazzName: String) :: Nil => - allowedClasses - .find(_._1.equalsScalaClassNameIgnoringCase(clazzName)) - .map(_._2) match { - case Some(typing) => typing.validNel - case None => - GenericFunctionTypingError.OtherError(s"Casting to '$clazzName' is not allowed").invalidNel - } - case _ => GenericFunctionTypingError.ArgumentTypeError.invalidNel - } - - private def canCastToTyping(allowedClasses: Map[Class[_], TypingResult])( - arguments: List[typing.TypingResult] - ): ValidatedNel[GenericFunctionTypingError, typing.TypingResult] = - castToTyping(allowedClasses)(arguments).map(_ => Typed.typedClass[Boolean]) - -} diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/CollectionConversionExt.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/CollectionConversionExt.scala new file mode 100644 index 00000000000..71f502da128 --- /dev/null +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/CollectionConversionExt.scala @@ -0,0 +1,120 @@ +package pl.touk.nussknacker.engine.extension + +import cats.data.ValidatedNel +import cats.implicits.catsSyntaxValidatedId +import pl.touk.nussknacker.engine.api.generics.{GenericFunctionTypingError, MethodTypeInfo} +import pl.touk.nussknacker.engine.api.typed.typing.{Typed, TypedClass, TypedObjectTypingResult, TypingResult, Unknown} +import pl.touk.nussknacker.engine.definition.clazz.{ClassDefinitionSet, FunctionalMethodDefinition, MethodDefinition} +import pl.touk.nussknacker.engine.extension.ListConversion.collectionClass +import pl.touk.nussknacker.engine.extension.MapConversion.{keyName, valueName} +import pl.touk.nussknacker.engine.util.classes.Extensions.ClassExtensions + +import java.util.{List => JList, Map => JMap} + +class CollectionConversionExt(target: Any) { + + def isList(): Boolean = ListConversion.canConvert(target) + def toList(): JList[_] = ListConversion.convert(target) + def toListOrNull(): JList[_] = ListConversion.convertOrNull(target) + def isMap(): Boolean = MapConversion.canConvert(target) + def toMap(): JMap[_, _] = MapConversion.convert(target) + def toMapOrNull(): JMap[_, _] = MapConversion.convertOrNull(target) + +} + +object CollectionConversionExt extends ExtensionMethodsHandler { + private val unknownClass = classOf[Object] + private val booleanTyping = Typed.typedClass[Boolean] + + private val toMapDefinition = FunctionalMethodDefinition( + typeFunction = (invocationTarget, _) => toMapTypeFunction(invocationTarget), + signature = MethodTypeInfo( + noVarArgs = Nil, + varArg = None, + result = Unknown + ), + name = "toMap", + description = Option("Convert to a map or throw exception in case of failure") + ) + + private val toListDefinition = FunctionalMethodDefinition( + typeFunction = (invocationTarget, _) => toListTypeFunction(invocationTarget), + signature = MethodTypeInfo( + noVarArgs = Nil, + varArg = None, + result = Unknown + ), + name = "toList", + description = Option("Convert to a list or throw exception in case of failure") + ) + + private val isMapMethodDefinition = FunctionalMethodDefinition( + typeFunction = (invocationTarget, _) => toMapTypeFunction(invocationTarget).map(_ => booleanTyping), + signature = MethodTypeInfo( + noVarArgs = Nil, + varArg = None, + result = Unknown + ), + name = "isMap", + description = Some("Check whether can be convert to a map") + ) + + private val isListMethodDefinition = FunctionalMethodDefinition( + typeFunction = (invocationTarget, _) => toListTypeFunction(invocationTarget).map(_ => booleanTyping), + signature = MethodTypeInfo( + noVarArgs = Nil, + varArg = None, + result = Unknown + ), + name = "isList", + description = Some("Check whether can be convert to a list") + ) + + private val definitions = List( + isMapMethodDefinition, + toMapDefinition, + toMapDefinition.copy(name = "toMapOrNull", description = Some("Convert to a map or null in case of failure")), + isListMethodDefinition, + toListDefinition, + toListDefinition.copy(name = "toListOrNull", description = Some("Convert to a list or null in case of failure")), + ).groupBy(_.name) + + override type ExtensionMethodInvocationTarget = CollectionConversionExt + override val invocationTargetClass: Class[CollectionConversionExt] = classOf[CollectionConversionExt] + + override def createConverter(): ToExtensionMethodInvocationTargetConverter[CollectionConversionExt] = + (target: Any) => new CollectionConversionExt(target) + + override def extractDefinitions(clazz: Class[_], set: ClassDefinitionSet): Map[String, List[MethodDefinition]] = + if (clazz.isAOrChildOf(collectionClass) || clazz == unknownClass || clazz.isArray) definitions + else Map.empty + + // Conversion extension should be available for every class in a runtime + override def applies(clazz: Class[_]): Boolean = + true + + private def toMapTypeFunction( + invocationTarget: TypingResult + ): ValidatedNel[GenericFunctionTypingError, TypingResult] = + invocationTarget.withoutValue match { + case TypedClass(_, List(TypedObjectTypingResult(fields, _, _))) + if fields.contains(keyName) && fields.contains(valueName) => + val params = List(fields.get(keyName), fields.get(valueName)).flatten + Typed.genericTypeClass[JMap[_, _]](params).validNel + case TypedClass(_, List(TypedObjectTypingResult(_, _, _))) => + GenericFunctionTypingError.OtherError("List element must contain 'key' and 'value' fields").invalidNel + case Unknown => Typed.genericTypeClass[JMap[_, _]](List(Unknown, Unknown)).validNel + case _ => GenericFunctionTypingError.ArgumentTypeError.invalidNel + } + + private def toListTypeFunction( + invocationTarget: TypingResult + ): ValidatedNel[GenericFunctionTypingError, TypingResult] = + invocationTarget.withoutValue match { + case TypedClass(klass, params) if klass.isAOrChildOf(collectionClass) || klass.isArray => + Typed.genericTypeClass[JList[_]](params).validNel + case Unknown => Typed.genericTypeClass[JList[_]](List(Unknown)).validNel + case _ => GenericFunctionTypingError.ArgumentTypeError.invalidNel + } + +} diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/Conversion.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/Conversion.scala new file mode 100644 index 00000000000..14f537805de --- /dev/null +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/Conversion.scala @@ -0,0 +1,257 @@ +package pl.touk.nussknacker.engine.extension + +import pl.touk.nussknacker.engine.api.typed.typing.{Typed, TypingResult, Unknown} +import pl.touk.nussknacker.engine.api.util.ReflectUtils +import pl.touk.nussknacker.engine.extension.Conversion.toNumber +import pl.touk.nussknacker.engine.spel.internal.RuntimeConversionHandler +import pl.touk.nussknacker.engine.util.classes.Extensions.ClassExtensions + +import scala.util.{Success, Try} +import java.util.{ + ArrayList => JArrayList, + Collection => JCollection, + HashMap => JHashMap, + List => JList, + Map => JMap, + Set => JSet +} +import java.lang.{Boolean => JBoolean, Double => JDouble, Long => JLong, Number => JNumber} +import java.math.{BigDecimal => JBigDecimal, BigInteger => JBigInteger} + +sealed trait Conversion { + type ResultType + val resultTypeClass: Class[ResultType] + + def canConvert(value: Any): JBoolean + def convert(value: Any): ResultType + def convertOrNull(value: Any): ResultType + + def typingResult: TypingResult = Typed.typedClass(resultTypeClass) + def simpleSupportedResultTypeName = ReflectUtils.simpleNameWithoutSuffix(resultTypeClass) + def supportedResultTypes: Set[String] = Set(resultTypeClass.getName, simpleSupportedResultTypeName) +} + +object Conversion { + + private[extension] def toNumber(stringOrNumber: Any): JNumber = stringOrNumber match { + case s: CharSequence => + val ss = s.toString + // we pick the narrowest type as possible to reduce the amount of memory and computations overheads + val tries: List[Try[JNumber]] = List( + Try(java.lang.Integer.parseInt(ss)), + Try(java.lang.Long.parseLong(ss)), + Try(java.lang.Double.parseDouble(ss)), + Try(new JBigDecimal(ss)), + Try(new JBigInteger(ss)) + ) + + tries + .collectFirst { case Success(value) => + value + } + .getOrElse(new JBigDecimal(ss)) + + case n: JNumber => n + } + +} + +object LongConversion extends Conversion { + override type ResultType = JLong + override val resultTypeClass: Class[JLong] = classOf[JLong] + + override def canConvert(value: Any): JBoolean = toLongEither(value).isRight + + override def convert(value: Any): JLong = toLongEither(value) match { + case Right(result) => result + case Left(ex) => throw ex + } + + override def convertOrNull(value: Any): JLong = toLongEither(value) match { + case Right(result) => result + case Left(_) => null + } + + private def toLongEither(value: Any): Either[Throwable, JLong] = { + value match { + case v: String => Try(JLong.valueOf(toNumber(v).longValue())).toEither + case v: Number => Right(v.longValue()) + case _ => Left(new IllegalArgumentException(s"Cannot convert: $value to Long")) + } + } + +} + +object DoubleConversion extends Conversion { + override type ResultType = JDouble + override val resultTypeClass: Class[JDouble] = classOf[JDouble] + + override def canConvert(value: Any): JBoolean = toDoubleEither(value).isRight + + override def convert(value: Any): JDouble = toDoubleEither(value) match { + case Right(result) => result + case Left(ex) => throw ex + } + + override def convertOrNull(value: Any): JDouble = toDoubleEither(value) match { + case Right(result) => result + case Left(_) => null + } + + private def toDoubleEither(value: Any): Either[Throwable, JDouble] = { + value match { + case v: String => Try(JDouble.valueOf(toNumber(v).doubleValue())).toEither + case v: Number => Right(v.doubleValue()) + case _ => Left(new IllegalArgumentException(s"Cannot convert: $value to Double")) + } + } + +} + +object BigDecimalConversion extends Conversion { + override type ResultType = JBigDecimal + override val resultTypeClass: Class[JBigDecimal] = classOf[JBigDecimal] + + override def canConvert(value: Any): JBoolean = toBigDecimalEither(value).isRight + + override def convert(value: Any): JBigDecimal = toBigDecimalEither(value) match { + case Right(result) => result + case Left(ex) => throw ex + } + + override def convertOrNull(value: Any): JBigDecimal = toBigDecimalEither(value) match { + case Right(result) => result + case Left(_) => null + } + + private def toBigDecimalEither(value: Any): Either[Throwable, JBigDecimal] = + value match { + case v: String => Try(new JBigDecimal(v)).toEither + case v: JBigInteger => Right(new JBigDecimal(v)) + case v: JBigDecimal => Right(v) + case v: Number => Try(new JBigDecimal(v.toString)).toEither + case _ => Left(new IllegalArgumentException(s"Cannot convert: $value to BigDecimal")) + } + +} + +object BooleanConversion extends Conversion { + private val cannotConvertException = (value: Any) => + new IllegalArgumentException(s"Cannot convert: $value to Boolean") + + override type ResultType = JBoolean + override val resultTypeClass: Class[JBoolean] = classOf[JBoolean] + + override def canConvert(value: Any): JBoolean = convertToBoolean(value).isRight + + override def convert(value: Any): JBoolean = convertToBoolean(value) match { + case Right(value) => value + case Left(ex) => throw ex + } + + override def convertOrNull(value: Any): JBoolean = convertToBoolean(value) match { + case Right(value) => value + case Left(_) => null + } + + private def convertToBoolean(value: Any): Either[Throwable, JBoolean] = value match { + case s: String => stringToBoolean(s).toRight(cannotConvertException(value)) + case b: JBoolean => Right(b) + case _ => Left(cannotConvertException(value)) + } + + private def stringToBoolean(value: String): Option[JBoolean] = + if ("true".equalsIgnoreCase(value)) { + Some(true) + } else if ("false".equalsIgnoreCase(value)) { + Some(false) + } else { + None + } + +} + +object StringConversion extends Conversion { + override type ResultType = String + override val resultTypeClass: Class[ResultType] = classOf[String] + + override def canConvert(value: Any): JBoolean = true + override def convert(value: Any): ResultType = value.toString + override def convertOrNull(value: Any): ResultType = value.toString +} + +object MapConversion extends Conversion { + private[extension] val keyName = "key" + private[extension] val valueName = "value" + private[extension] val keyAndValueNames = JSet.of(keyName, valueName) + + override type ResultType = JMap[_, _] + override val resultTypeClass: Class[JMap[_, _]] = classOf[ResultType] + override def typingResult: TypingResult = Typed.genericTypeClass(resultTypeClass, List(Unknown, Unknown)) + + override def canConvert(value: Any): JBoolean = value match { + case c: JCollection[_] => canConvertToMap(c) + case _: JMap[_, _] => true + case a: Array[_] => canConvertToMap(RuntimeConversionHandler.convert(a)) + case _ => false + } + + override def convert(value: Any): ResultType = convertToMap[Any, Any](value) match { + case Right(value) => value + case Left(ex) => throw ex + } + + override def convertOrNull(value: Any): ResultType = convertToMap[Any, Any](value) match { + case Right(value) => value + case Left(_) => null + } + + private def convertToMap[K, V](value: Any): Either[Throwable, JMap[K, V]] = + value match { + case c: JCollection[JMap[_, _] @unchecked] if canConvertToMap(c) => + val map = new JHashMap[K, V]() + c.forEach(e => map.put(e.get(keyName).asInstanceOf[K], e.get(valueName).asInstanceOf[V])) + Right(map) + case m: JMap[K, V] @unchecked => Right(m) + case a: Array[_] => convertToMap[K, V](RuntimeConversionHandler.convert(a)) + case x => Left(new IllegalArgumentException(s"Cannot convert: $x to a Map")) + } + + private def canConvertToMap(c: JCollection[_]): Boolean = c.isEmpty || c + .stream() + .allMatch { + case m: JMap[_, _] if !m.isEmpty => m.keySet().containsAll(keyAndValueNames) + case _ => false + } + +} + +object ListConversion extends Conversion { + private[extension] val collectionClass = classOf[JCollection[_]] + + override type ResultType = JList[_] + override val resultTypeClass: Class[JList[_]] = classOf[JList[_]] + override def typingResult: TypingResult = Typed.genericTypeClass(resultTypeClass, List(Unknown)) + + override def canConvert(value: Any): JBoolean = value.getClass.isAOrChildOf(collectionClass) || value.getClass.isArray + + override def convert(value: Any): ResultType = convertToList[Any](value) match { + case Right(value) => value + case Left(ex) => throw ex + } + + override def convertOrNull(value: Any): ResultType = convertToList[Any](value) match { + case Right(value) => value + case Left(_) => null + } + + private def convertToList[T](value: Any): Either[Throwable, JList[T]] = { + value match { + case l: JList[T @unchecked] => Right(l) + case c: JCollection[T @unchecked] => Right(new JArrayList[T](c)) + case a: Array[T @unchecked] => Right(RuntimeConversionHandler.convert(a).asInstanceOf[JList[T]]) + case x => Left(new IllegalArgumentException(s"Cannot convert: $x to a List")) + } + } + +} diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ConversionExt.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ConversionExt.scala new file mode 100644 index 00000000000..7282a621999 --- /dev/null +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ConversionExt.scala @@ -0,0 +1,126 @@ +package pl.touk.nussknacker.engine.extension + +import cats.data.ValidatedNel +import cats.implicits.catsSyntaxValidatedId +import pl.touk.nussknacker.engine.api.generics.{GenericFunctionTypingError, MethodTypeInfo, Parameter} +import pl.touk.nussknacker.engine.api.typed.typing +import pl.touk.nussknacker.engine.api.typed.typing.{Typed, TypedObjectWithValue, TypingResult, Unknown} +import pl.touk.nussknacker.engine.definition.clazz.{ClassDefinitionSet, FunctionalMethodDefinition, MethodDefinition} +import pl.touk.nussknacker.engine.extension.ConversionExt.getConversion +import pl.touk.nussknacker.engine.util.classes.Extensions.ClassExtensions + +// todo: lbg - add casting methods to UTIL +class ConversionExt(target: Any) { + + def is(className: String): Boolean = getConversion(className) match { + case Right(conversion) => conversion.canConvert(target) + case Left(ex) => throw ex + } + + def to(className: String): Any = getConversion(className) match { + case Right(conversion) => conversion.convert(target) + case Left(ex) => throw ex + } + + def toOrNull(className: String): Any = getConversion(className) match { + case Right(conversion) => conversion.convertOrNull(target) + case Left(ex) => throw ex + } + +} + +object ConversionExt extends ExtensionMethodsHandler { + private val stringClass = classOf[String] + private val unknownClass = classOf[Object] + private val numberClass = classOf[Number] + + private val methodTypeInfoWithStringParam = MethodTypeInfo( + noVarArgs = List( + Parameter("className", Typed.genericTypeClass(stringClass, Nil)) + ), + varArg = None, + result = Unknown + ) + + private val definitions: Map[String, List[MethodDefinition]] = + List( + FunctionalMethodDefinition( + (_, x) => canConvertToTyping(x), + methodTypeInfoWithStringParam, + "is", + Some("Checks if a type can be converted to a given class") + ), + FunctionalMethodDefinition( + (_, x) => convertToTyping(x), + methodTypeInfoWithStringParam, + "to", + Some("Converts a type to a given class or throws exception if type cannot be converted.") + ), + FunctionalMethodDefinition( + (_, x) => convertToTyping(x), + methodTypeInfoWithStringParam, + "toOrNull", + Some("Converts a type to a given class or return null if type cannot be converted.") + ), + ).groupBy(_.name) + + private val convertMethodsNames = definitions.keySet + + private val conversionsRegistry: List[Conversion] = List( + LongConversion, + DoubleConversion, + BigDecimalConversion, + BooleanConversion, + StringConversion, + MapConversion, + ListConversion, + ) + + private val conversionsByType: Map[String, Conversion] = conversionsRegistry + .flatMap(c => c.supportedResultTypes.map(t => t.toLowerCase -> c)) + .toMap + + val supportedTypes: List[(String, TypingResult)] = + conversionsRegistry.map(c => c.simpleSupportedResultTypeName -> c.typingResult) + + override type ExtensionMethodInvocationTarget = ConversionExt + override val invocationTargetClass: Class[ConversionExt] = classOf[ConversionExt] + + def isConversionMethod(methodName: String): Boolean = + convertMethodsNames.contains(methodName) + + def getConversion(className: String): Either[Throwable, Conversion] = + conversionsByType.get(className.toLowerCase) match { + case Some(conversion) => Right(conversion) + case None => Left(new IllegalArgumentException(s"Conversion for class $className not found")) + } + + override def createConverter(): ToExtensionMethodInvocationTargetConverter[ConversionExt] = + (target: Any) => new ConversionExt(target) + + override def extractDefinitions(clazz: Class[_], set: ClassDefinitionSet): Map[String, List[MethodDefinition]] = + if (clazz.isAOrChildOf(numberClass) || clazz == stringClass || clazz == unknownClass) definitions + else Map.empty + + // Convert methods should visible in runtime for every class because we allow invoke convert methods on an unknown + // object in Typer, but in the runtime the same type could be known and that's why should add convert method for an + // every class. + override def applies(clazz: Class[_]): Boolean = true + + private def convertToTyping( + arguments: List[typing.TypingResult] + ): ValidatedNel[GenericFunctionTypingError, typing.TypingResult] = arguments match { + case TypedObjectWithValue(_, clazzName: String) :: Nil => + getConversion(clazzName) match { + case Right(conversion) => conversion.typingResult.validNel + case Left(ex) => GenericFunctionTypingError.OtherError(ex.getMessage).invalidNel + } + case _ => GenericFunctionTypingError.ArgumentTypeError.invalidNel + } + + private def canConvertToTyping( + arguments: List[typing.TypingResult] + ): ValidatedNel[GenericFunctionTypingError, typing.TypingResult] = + convertToTyping(arguments).map(_ => Typed.typedClass[Boolean]) + +} diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ExtensionMethods.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ExtensionMethods.scala index 750ccfbcc28..5bd50221cbc 100644 --- a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ExtensionMethods.scala +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/ExtensionMethods.scala @@ -5,11 +5,11 @@ import pl.touk.nussknacker.engine.extension.ExtensionMethods.extensionMethodsHan import java.lang.reflect.{Method, Modifier} -class ExtensionsAwareMethodInvoker(classLoader: ClassLoader, classDefinitionSet: ClassDefinitionSet) { +class ExtensionsAwareMethodInvoker { private val toInvocationTargetConvertersByClass = extensionMethodsHandlers - .map(e => e.invocationTargetClass -> e.createConverter(classLoader, classDefinitionSet)) + .map(e => e.invocationTargetClass -> e.createConverter()) .toMap[Class[_], ToExtensionMethodInvocationTargetConverter[_]] def invoke(method: Method)(target: Any, arguments: Array[Object]): Any = { @@ -39,8 +39,11 @@ object ExtensionAwareMethodsDiscovery { object ExtensionMethods { val extensionMethodsHandlers: List[ExtensionMethodsHandler] = List( - Cast, + ConversionExt, ArrayExt, + NumericConversionExt, + BooleanConversionExt, + CollectionConversionExt, ) def enrichWithExtensionMethods(set: ClassDefinitionSet): ClassDefinitionSet = { @@ -64,10 +67,7 @@ trait ExtensionMethodsHandler { invocationTargetClass.getDeclaredMethods .filter(m => Modifier.isPublic(m.getModifiers) && !Modifier.isStatic(m.getModifiers)) - def createConverter( - classLoader: ClassLoader, - set: ClassDefinitionSet - ): ToExtensionMethodInvocationTargetConverter[ExtensionMethodInvocationTarget] + def createConverter(): ToExtensionMethodInvocationTargetConverter[ExtensionMethodInvocationTarget] def extractDefinitions(clazz: Class[_], set: ClassDefinitionSet): Map[String, List[MethodDefinition]] diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/NumericConversionExt.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/NumericConversionExt.scala new file mode 100644 index 00000000000..6abc36ba425 --- /dev/null +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/extension/NumericConversionExt.scala @@ -0,0 +1,75 @@ +package pl.touk.nussknacker.engine.extension + +import pl.touk.nussknacker.engine.api.generics.MethodTypeInfo +import pl.touk.nussknacker.engine.api.typed.typing.{Typed, TypingResult} +import pl.touk.nussknacker.engine.definition.clazz.{ClassDefinitionSet, MethodDefinition, StaticMethodDefinition} +import pl.touk.nussknacker.engine.util.classes.Extensions.ClassExtensions + +import java.lang.{Boolean => JBoolean, Double => JDouble, Long => JLong, Number => JNumber} +import java.math.{BigDecimal => JBigDecimal} + +class NumericConversionExt(target: Any) { + + def isLong(): JBoolean = LongConversion.canConvert(target) + def toLong(): JLong = LongConversion.convert(target) + def toLongOrNull(): JLong = LongConversion.convertOrNull(target) + def isDouble(): JBoolean = DoubleConversion.canConvert(target) + def toDouble(): JDouble = DoubleConversion.convert(target) + def toDoubleOrNull(): JDouble = DoubleConversion.convertOrNull(target) + def isBigDecimal(): JBoolean = BigDecimalConversion.canConvert(target) + def toBigDecimal(): JBigDecimal = BigDecimalConversion.convert(target) + def toBigDecimalOrNull(): JBigDecimal = BigDecimalConversion.convertOrNull(target) +} + +object NumericConversionExt extends ExtensionMethodsHandler { + private val numberClass = classOf[JNumber] + private val stringClass = classOf[String] + private val unknownClass = classOf[Object] + + private val definitions = List( + definition(Typed.typedClass[JBoolean], "isLong", Some("Check whether can be convert to a Long")), + definition(Typed.typedClass[JLong], "toLong", Some("Convert to Long or throw exception in case of failure")), + definition(Typed.typedClass[JLong], "toLongOrNull", Some("Convert to Long or null in case of failure")), + definition(Typed.typedClass[JBoolean], "isDouble", Some("Check whether can be convert to a Double")), + definition(Typed.typedClass[JDouble], "toDouble", Some("Convert to Double or throw exception in case of failure")), + definition(Typed.typedClass[JDouble], "toDoubleOrNull", Some("Convert to Double or null in case of failure")), + definition(Typed.typedClass[JBoolean], "isBigDecimal", Some("Check whether can be convert to a BigDecimal")), + definition( + Typed.typedClass[JBigDecimal], + "toBigDecimal", + Some("Convert to BigDecimal or throw exception in case of failure") + ), + definition( + Typed.typedClass[JBigDecimal], + "toBigDecimalOrNull", + Some("Convert to BigDecimal or null in case of failure") + ), + ).groupBy(_.name) + + override type ExtensionMethodInvocationTarget = NumericConversionExt + override val invocationTargetClass: Class[NumericConversionExt] = classOf[NumericConversionExt] + + override def createConverter(): ToExtensionMethodInvocationTargetConverter[NumericConversionExt] = + (target: Any) => new NumericConversionExt(target) + + override def extractDefinitions(clazz: Class[_], set: ClassDefinitionSet): Map[String, List[MethodDefinition]] = { + if (clazz.isAOrChildOf(numberClass) || clazz == stringClass || clazz == unknownClass) { + definitions + } else { + Map.empty + } + } + + override def applies(clazz: Class[_]): Boolean = true + + private def definition(result: TypingResult, methodName: String, desc: Option[String]) = StaticMethodDefinition( + signature = MethodTypeInfo( + noVarArgs = Nil, + varArg = None, + result = result + ), + name = methodName, + description = desc + ) + +} diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/SpelExpression.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/SpelExpression.scala index a521545c97f..dd839cd210f 100644 --- a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/SpelExpression.scala +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/SpelExpression.scala @@ -257,7 +257,7 @@ object SpelExpressionParser extends LazyLogging { // we have to pass classloader, because default contextClassLoader can be sth different than we expect... new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, classLoader) ) - val evaluationContextPreparer = EvaluationContextPreparer.default(classLoader, expressionConfig, classDefinitionSet) + val evaluationContextPreparer = EvaluationContextPreparer.default(classLoader, expressionConfig) val validator = new SpelExpressionValidator( Typer.default(classLoader, expressionConfig, new KeysDictTyper(dictRegistry), classDefinitionSet) ) diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/SpelExpressionSuggester.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/SpelExpressionSuggester.scala index 70ce08e54ca..2fe1a164841 100644 --- a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/SpelExpressionSuggester.scala +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/SpelExpressionSuggester.scala @@ -13,7 +13,7 @@ import pl.touk.nussknacker.engine.api.validation.Validations.isVariableNameValid import pl.touk.nussknacker.engine.definition.clazz.{ClassDefinition, ClassDefinitionSet} import pl.touk.nussknacker.engine.definition.globalvariables.ExpressionConfigDefinition import pl.touk.nussknacker.engine.dict.LabelsDictTyper -import pl.touk.nussknacker.engine.extension.Cast +import pl.touk.nussknacker.engine.extension.ConversionExt import pl.touk.nussknacker.engine.graph.expression.Expression import pl.touk.nussknacker.engine.graph.expression.Expression.Language import pl.touk.nussknacker.engine.spel.Typer.TypingResultWithContext @@ -23,8 +23,6 @@ import pl.touk.nussknacker.engine.util.CaretPosition2d import scala.collection.compat.immutable.LazyList import cats.implicits._ -import pl.touk.nussknacker.engine.util.Implicits.RichScalaMap -import pl.touk.nussknacker.engine.util.classes.Extensions.{ClassExtensions, ClassesExtensions} import scala.concurrent.{ExecutionContext, Future} import scala.util.{Failure, Try} @@ -287,12 +285,12 @@ class SpelExpressionSuggester( Future.successful(fields.map(f => ExpressionSuggestion(f._1, f._2, fromClass = false, None, Nil))) case _ => successfulNil } - case m: MethodReference if Cast.isCastMethod(m.getName) => + case m: MethodReference if ConversionExt.isConversionMethod(m.getName) => parentPrevNodeTyping match { case Unknown => - castMethodsSuggestions(classOf[Object]) + conversionMethodsSuggestions(classOf[Object]) case TypedClass(klass, _) => - castMethodsSuggestions(klass) + conversionMethodsSuggestions(klass) case _ => successfulNil } case _ => successfulNil @@ -338,18 +336,14 @@ class SpelExpressionSuggester( suggestions } - private def castMethodsSuggestions( + private def conversionMethodsSuggestions( klass: Class[_] )(implicit ec: ExecutionContext): Future[Iterable[ExpressionSuggestion]] = Future { - val allowedClassesForCastParameter = klass - .findAllowedClassesForCastParameter(clssDefinitions) - .mapValuesNow(_.clazzName) - allowedClassesForCastParameter.keySet - .classesBySimpleNamesRegardingClashes() - .map { case (name, clazz) => - ExpressionSuggestion(name, allowedClassesForCastParameter.getOrElse(clazz, Unknown), false, None, Nil) - } + if (ConversionExt.applies(klass)) + ConversionExt.supportedTypes + .map(t => ExpressionSuggestion(t._1, t._2, false, None, Nil)) + else List.empty } private def expressionContainOddNumberOfQuotesOrOddNumberOfDoubleQuotes(plainExpression: String): Boolean = diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/Typer.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/Typer.scala index acdc6ccdb08..55764a56223 100644 --- a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/Typer.scala +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/Typer.scala @@ -434,7 +434,7 @@ private[spel] class Typer( case e: PropertyOrFieldReference => current.stackHead .map(extractProperty(e, _)) - .map(fallbackToCheckMethodsIfPropertyNotExists) + .map(mapErrorAndCheckMethodsIfPropertyNotExists) .getOrElse(invalid(NonReferenceError(e.toStringAST))) .map(toNodeResult) // TODO: what should be here? @@ -735,10 +735,13 @@ private[spel] class Typer( } } - private def fallbackToCheckMethodsIfPropertyNotExists(typing: TypingR[TypingResult]): TypingR[TypingResult] = + private def mapErrorAndCheckMethodsIfPropertyNotExists(typing: TypingR[TypingResult]): TypingR[TypingResult] = typing.mapWritten(_.map { case e: NoPropertyError => methodReferenceTyper.typeMethodReference(typer.MethodReference(e.typ, false, e.property, Nil)) match { + // Right is not mapped because of: pl.touk.nussknacker.engine.spel.Typer.propertyTypeBasedOnMethod and + // pl.touk.nussknacker.engine.spel.internal.propertyAccessors.NoParamMethodPropertyAccessor + // Methods without parameters can be treated as properties. case Left(me: ArgumentTypeError) => me case _ => e } @@ -771,7 +774,7 @@ object Typer { spelDictTyper: SpelDictTyper, classDefinitionSet: ClassDefinitionSet ): Typer = { - val evaluationContextPreparer = EvaluationContextPreparer.default(classLoader, expressionConfig, classDefinitionSet) + val evaluationContextPreparer = EvaluationContextPreparer.default(classLoader, expressionConfig) new Typer( spelDictTyper, diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/internal/OptimizedEvaluationContext.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/internal/OptimizedEvaluationContext.scala index 9d1b062316b..b16fc2d0f3b 100644 --- a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/internal/OptimizedEvaluationContext.scala +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/spel/internal/OptimizedEvaluationContext.scala @@ -5,7 +5,6 @@ import org.springframework.expression.spel.support._ import org.springframework.expression.{EvaluationContext, MethodExecutor, MethodResolver, PropertyAccessor} import pl.touk.nussknacker.engine.api.spel.SpelConversionsProvider import pl.touk.nussknacker.engine.api.{Context, SpelExpressionExcludeList} -import pl.touk.nussknacker.engine.definition.clazz.ClassDefinitionSet import pl.touk.nussknacker.engine.definition.globalvariables.ExpressionConfigDefinition import pl.touk.nussknacker.engine.extension.{ExtensionAwareMethodsDiscovery, ExtensionsAwareMethodInvoker} import pl.touk.nussknacker.engine.spel.{NuReflectiveMethodExecutor, internal} @@ -21,7 +20,6 @@ class EvaluationContextPreparer( propertyAccessors: Seq[PropertyAccessor], conversionService: ConversionService, spelExpressionExcludeList: SpelExpressionExcludeList, - classDefinitionSet: ClassDefinitionSet ) { // this method is evaluated for *each* expression evaluation, we want to extract as much as possible to fields in this class @@ -42,7 +40,7 @@ class EvaluationContextPreparer( private val optimizedMethodResolvers: java.util.List[MethodResolver] = { val mr = new ReflectiveMethodResolver { - private val methodInvoker = new ExtensionsAwareMethodInvoker(classLoader, classDefinitionSet) + private val methodInvoker = new ExtensionsAwareMethodInvoker() override def resolve( context: EvaluationContext, @@ -90,7 +88,6 @@ object EvaluationContextPreparer { def default( classLoader: ClassLoader, expressionConfig: ExpressionConfigDefinition, - classDefinitionSet: ClassDefinitionSet ): EvaluationContextPreparer = { val conversionService = determineConversionService(expressionConfig) val propertyAccessors = internal.propertyAccessors.configured() @@ -100,7 +97,6 @@ object EvaluationContextPreparer { propertyAccessors, conversionService, expressionConfig.spelExpressionExcludeList, - classDefinitionSet ) } diff --git a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/util/classes/Extensions.scala b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/util/classes/Extensions.scala index 94706b5b950..1c69dac76e0 100644 --- a/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/util/classes/Extensions.scala +++ b/scenario-compiler/src/main/scala/pl/touk/nussknacker/engine/util/classes/Extensions.scala @@ -1,48 +1,11 @@ package pl.touk.nussknacker.engine.util.classes -import pl.touk.nussknacker.engine.api.util.ReflectUtils -import pl.touk.nussknacker.engine.definition.clazz.{ClassDefinition, ClassDefinitionSet} -import pl.touk.nussknacker.engine.util.Implicits.RichScalaMap - object Extensions { implicit class ClassExtensions(private val clazz: Class[_]) extends AnyVal { - def isChildOf(targetClazz: Class[_]): Boolean = - clazz != targetClazz && - targetClazz.isAssignableFrom(clazz) - - def isNotFromNuUtilPackage(): Boolean = { - val name = clazz.getName - !(name.contains("nussknacker") && name.contains("util")) - } - - def equalsScalaClassNameIgnoringCase(clazzName: String): Boolean = - clazz.getName.equalsIgnoreCase(clazzName) || - ReflectUtils.simpleNameWithoutSuffix(clazz).equalsIgnoreCase(clazzName) - - def findAllowedClassesForCastParameter(set: ClassDefinitionSet): Map[Class[_], ClassDefinition] = - set.classDefinitionsMap - .filterKeysNow(targetClazz => targetClazz.isChildOf(clazz) && targetClazz.isNotFromNuUtilPackage()) - - } - - implicit class ClassesExtensions(private val set: Set[Class[_]]) extends AnyVal { - - def classesBySimpleNamesRegardingClashes(): Map[String, Class[_]] = { - val nonUniqueClassNames = nonUniqueNames() - set - .map { - case c if nonUniqueClassNames.contains(ReflectUtils.simpleNameWithoutSuffix(c)) => c.getName -> c - case c => ReflectUtils.simpleNameWithoutSuffix(c) -> c - } - .toMap[String, Class[_]] - } - - private def nonUniqueNames(): Set[String] = { - val simpleNames = set.toList.map(c => ReflectUtils.simpleNameWithoutSuffix(c)) - simpleNames.diff(simpleNames.distinct).toSet - } + def isAOrChildOf(targetClazz: Class[_]): Boolean = + targetClazz.isAssignableFrom(clazz) } diff --git a/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/definition/component/parameter/validator/ValidationExpressionParameterValidatorTest.scala b/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/definition/component/parameter/validator/ValidationExpressionParameterValidatorTest.scala index 8e0d17290c4..d8ee233dd76 100644 --- a/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/definition/component/parameter/validator/ValidationExpressionParameterValidatorTest.scala +++ b/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/definition/component/parameter/validator/ValidationExpressionParameterValidatorTest.scala @@ -72,7 +72,6 @@ private class TestSpelExpression(expression: String) extends CompiledExpression .default( getClass.getClassLoader, expressionConfig, - ClassDefinitionTestUtils.createDefinitionWithDefaultsAndExtensions ) .prepareEvaluationContext(ctx, globals) diff --git a/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/extension/ExtensionMethodsSpec.scala b/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/extension/ExtensionMethodsSpec.scala index 6bd07bfcf2b..b8e8c015efb 100644 --- a/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/extension/ExtensionMethodsSpec.scala +++ b/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/extension/ExtensionMethodsSpec.scala @@ -27,11 +27,54 @@ class ExtensionMethodsSpec extends AnyFunSuite with Matchers { ) val definitionsSet = ClassDefinitionSet(Set(stringDefinition, unknownDefinition)) - ExtensionMethods.enrichWithExtensionMethods( - definitionsSet - ).classDefinitionsMap.map(e => e._1.getName -> e._2.methods.keys) shouldBe Map( - "java.lang.String" -> Set("toUpperCase"), - "java.lang.Object" -> Set("toString", "canCastTo", "castTo", "castToOrNull"), + ExtensionMethods + .enrichWithExtensionMethods( + definitionsSet + ) + .classDefinitionsMap + .map(e => e._1.getName -> e._2.methods.keys) shouldBe Map( + "java.lang.String" -> Set( + "isBigDecimal", + "toBigDecimal", + "toBigDecimalOrNull", + "isBoolean", + "toBoolean", + "toBooleanOrNull", + "isDouble", + "toDouble", + "toDoubleOrNull", + "isLong", + "toLong", + "toLongOrNull", + "toUpperCase", + "is", + "to", + "toOrNull", + ), + "java.lang.Object" -> Set( + "isBigDecimal", + "toBigDecimal", + "toBigDecimalOrNull", + "isBoolean", + "toBoolean", + "toBooleanOrNull", + "isDouble", + "toDouble", + "toDoubleOrNull", + "isLong", + "toLong", + "toLongOrNull", + "toString", + "is", + "to", + "toOrNull", + "isMap", + "toMap", + "toMapOrNull", + "isList", + "toList", + "toListOrNull" + ), ) } diff --git a/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/spel/SpelExpressionSpec.scala b/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/spel/SpelExpressionSpec.scala index eb99bd47d53..c0c6a27dd9f 100644 --- a/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/spel/SpelExpressionSpec.scala +++ b/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/spel/SpelExpressionSpec.scala @@ -52,12 +52,13 @@ import pl.touk.nussknacker.engine.spel.SpelExpressionParser.{Flavour, Standard} import pl.touk.nussknacker.engine.testing.ModelDefinitionBuilder import pl.touk.nussknacker.test.ValidatedValuesDetailedMessage -import java.math.{BigDecimal, BigInteger} +import java.lang.{Boolean => JBoolean, Double => JDouble, Long => JLong} +import java.math.{BigDecimal => JBigDecimal, BigInteger => JBigInteger} import java.nio.charset.Charset import java.time.chrono.ChronoLocalDate import java.time.{LocalDate, LocalDateTime} import java.util -import java.util.{Collections, Currency, Locale, Optional, UUID} +import java.util.{Collections, Currency, List => JList, Locale, Map => JMap, Optional, UUID} import scala.annotation.varargs import scala.jdk.CollectionConverters._ import scala.language.implicitConversions @@ -89,7 +90,7 @@ class SpelExpressionSpec extends AnyFunSuite with Matchers with ValidatedValuesD private implicit val nid: NodeId = NodeId("") - private val bigValue = BigDecimal.valueOf(4187338076L) + private val bigValue = JBigDecimal.valueOf(4187338076L) private val testValue = Test("1", 2, List(Test("3", 4), Test("5", 6)).asJava, bigValue) @@ -102,7 +103,8 @@ class SpelExpressionSpec extends AnyFunSuite with Matchers with ValidatedValuesD "intArray" -> Array(1, 2, 3), "nestedArray" -> Array(Array(1, 2), Array(3, 4)), "arrayOfUnknown" -> Array("unknown".asInstanceOf[Any]), - "unknownString" -> ContainerOfUnknown("unknown") + "unknownString" -> ContainerOfUnknown("unknown"), + "setVal" -> Set("a").asJava ) ) @@ -126,7 +128,7 @@ class SpelExpressionSpec extends AnyFunSuite with Matchers with ValidatedValuesD id: String, value: Long, children: java.util.List[Test] = List[Test]().asJava, - bigValue: BigDecimal = BigDecimal.valueOf(0L) + bigValue: JBigDecimal = JBigDecimal.valueOf(0L) ) case class ContainerOfUnknown(value: Any) @@ -241,8 +243,8 @@ class SpelExpressionSpec extends AnyFunSuite with Matchers with ValidatedValuesD ClassDefinitionTestUtils.createDefinitionForClassesWithExtensions(typesFromGlobalVariables ++ customClasses: _*) } - private def evaluate[T: TypeTag](expr: String): T = - parse[T](expr = expr, context = ctx).validExpression.evaluateSync[T](ctx) + private def evaluate[T: TypeTag](expr: String, context: Context = ctx): T = + parse[T](expr = expr, context = context).validExpression.evaluateSync[T](context) test("parsing first selection on array") { parse[Any]("{1,2,3,4,5,6,7,8,9,10}.^[(#this%2==0)]").validExpression @@ -306,11 +308,11 @@ class SpelExpressionSpec extends AnyFunSuite with Matchers with ValidatedValuesD } test("blocking excluded in runtime, without previous static validation, allowed class and package") { - parse[BigInteger]( + parse[JBigInteger]( "T(java.math.BigInteger).valueOf(1L)", staticMethodInvocationsChecking = false, methodExecutionForUnknownAllowed = true - ).validExpression.evaluateSync[BigInteger](ctx) should equal(BigInteger.ONE) + ).validExpression.evaluateSync[JBigInteger](ctx) should equal(JBigInteger.ONE) } test("blocking excluded in runtime, allowed reference") { @@ -517,9 +519,9 @@ class SpelExpressionSpec extends AnyFunSuite with Matchers with ValidatedValuesD } test("handle big decimals") { - bigValue.compareTo(BigDecimal.valueOf(50 * 1024 * 1024)) should be > 0 - bigValue.compareTo(BigDecimal.valueOf(50 * 1024 * 1024L)) should be > 0 - parse[Any]("#obj.bigValue").validExpression.evaluateSync[BigDecimal](ctx) should equal(bigValue) + bigValue.compareTo(JBigDecimal.valueOf(50 * 1024 * 1024)) should be > 0 + bigValue.compareTo(JBigDecimal.valueOf(50 * 1024 * 1024L)) should be > 0 + parse[Any]("#obj.bigValue").validExpression.evaluateSync[JBigDecimal](ctx) should equal(bigValue) parse[Boolean]("#obj.bigValue < 50*1024*1024").validExpression.evaluateSync[Boolean](ctx) should equal(false) parse[Boolean]("#obj.bigValue < 50*1024*1024L").validExpression.evaluateSync[Boolean](ctx) should equal(false) } @@ -1361,59 +1363,6 @@ class SpelExpressionSpec extends AnyFunSuite with Matchers with ValidatedValuesD } } - test("should check if a type can be casted to a given type") { - forAll( - Table( - ("expression", "expectedResult"), - ("#unknownString.value.canCastTo('java.lang.String')", true), - ("#unknownString.value.canCastTo('java.lang.Integer')", false), - ) - ) { (expression, expectedResult) => - evaluate[Any](expression) shouldBe expectedResult - } - } - - test("should return unknownMethodError during invoke cast on simple types") { - forAll( - Table( - ("expression", "expectedMethod", "expectedType"), - ("11.canCastTo('java.lang.String')", "canCastTo", "Integer"), - ("true.canCastTo('java.lang.String')", "canCastTo", "Boolean"), - ("'true'.canCastTo('java.lang.String')", "canCastTo", "String"), - ("11.castTo('java.lang.String')", "castTo", "Integer"), - ("true.castTo('java.lang.String')", "castTo", "Boolean"), - ("'true'.castTo('java.lang.String')", "castTo", "String"), - ) - ) { (expression, expectedMethod, expectedType) => - parse[Any](expression, ctx).invalidValue.toList should matchPattern { - case UnknownMethodError(`expectedMethod`, `expectedType`) :: Nil => - } - } - } - - test("should compute correct result type based on parameter") { - val parsed = parse[Any]("#unknownString.value.castTo('java.lang.String')", ctx).validValue - parsed.returnType shouldBe Typed.typedClass[String] - parsed.expression.evaluateSync[Any](ctx) shouldBe a[java.lang.String] - } - - test("should return an error if the cast return type cannot be determined at parse time") { - parse[Any]("#unknownString.value.castTo('java.util.XYZ')", ctx).invalidValue.toList should matchPattern { - case GenericFunctionError("Casting to 'java.util.XYZ' is not allowed") :: Nil => - } - parse[Any]("#unknownString.value.castTo(#obj.id)", ctx).invalidValue.toList should matchPattern { - case ArgumentTypeError("castTo", _, _) :: Nil => - } - } - - test("should throw exception if cast fails") { - val caught = intercept[SpelExpressionEvaluationException] { - evaluate[Any]("#unknownString.value.castTo('java.lang.Integer')") - } - caught.getCause shouldBe a[ClassCastException] - caught.getMessage should include("Cannot cast: class java.lang.String to: java.lang.Integer") - } - test( "should allow invoke discovered methods for unknown objects - not matter how methodExecutionForUnknownAllowed is set" ) { @@ -1423,31 +1372,7 @@ class SpelExpressionSpec extends AnyFunSuite with Matchers with ValidatedValuesD Table( ("expression", "expectedType", "expectedResult", "methodExecutionForUnknownAllowed"), ("#arrayOfUnknown", typedArray(Unknown), Array("unknown"), false), - ( - "#arrayOfUnknown.![#this.castTo('java.lang.String')]", - typedArray(Typed.typedClass[String]), - Array("unknown"), - false - ), - ( - "#arrayOfUnknown.![#this.canCastTo('java.lang.String')]", - typedArray(Typed.typedClass[Boolean]), - Array(true), - false - ), ("#arrayOfUnknown.![#this.toString()]", typedArray(Typed.typedClass[String]), Array("unknown"), false), - ( - "#arrayOfUnknown.![#this.castTo('java.lang.String')]", - typedArray(Typed.typedClass[String]), - Array("unknown"), - true - ), - ( - "#arrayOfUnknown.![#this.canCastTo('java.lang.String')]", - typedArray(Typed.typedClass[Boolean]), - Array(true), - true - ), ("#arrayOfUnknown.![#this.toString()]", typedArray(Typed.typedClass[String]), Array("unknown"), true), ) ) { (expression, expectedType, expectedResult, methodExecutionForUnknownAllowed) => @@ -1482,30 +1407,315 @@ class SpelExpressionSpec extends AnyFunSuite with Matchers with ValidatedValuesD } } - test("should not allow cast to disallowed classes") { - parse[Any]( - "#hashMap.value.castTo('java.util.HashMap').remove('testKey')", - ctx.withVariable("hashMap", ContainerOfUnknown(new java.util.HashMap[String, Int](Map("testKey" -> 2).asJava))) - ).invalidValue.toList should matchPattern { - case GenericFunctionError("Casting to 'java.util.HashMap' is not allowed") :: IllegalInvocationError( - Unknown - ) :: Nil => + test("should return null if toOrNull fails") { + evaluate[Any]("#unknownString.value.toOrNull('java.lang.Long')") == null shouldBe true + } + + test("should toOrNull succeed") { + evaluate[Any]( + "#unknownLong.value.toOrNull('java.lang.Long')", + ctx.withVariable("unknownLong", ContainerOfUnknown(11L)) + ) shouldBe 11L + } + + test("should allow invoke conversion methods with class simple names") { + evaluate[Any]( + "{#unknownLong.value.toOrNull('Long'), #unknownLong.value.to('Long'), #unknownLong.value.is('Long')}", + ctx.withVariable("unknownLong", ContainerOfUnknown(11L)) + ) shouldBe List(11L, 11L, true).asJava + } + + test("should convert a List to a Map") { + val mapStringStringType = + Typed.genericTypeClass[JMap[_, _]](List(Typed.typedClass[String], Typed.typedClass[String])) + val mapStringUnknownType = + Typed.genericTypeClass[JMap[_, _]](List(Typed.typedClass[String], Unknown)) + val stringMap = Map("foo" -> "bar", "baz" -> "qux").asJava + val nullableMap = { + val result = new util.HashMap[String, String]() + result.put("foo", "bar") + result.put("baz", null) + result.put(null, "qux") + result + } + val mapWithDifferentValueTypes = Map("foo" -> "bar", "baz" -> 1).asJava + val customCtx = ctx + .withVariable("stringMap", stringMap) + .withVariable("mapWithDifferentValueTypes", mapWithDifferentValueTypes) + .withVariable("nullableMap", nullableMap) + + forAll( + Table( + ("expression", "expectedType", "expectedResult"), + ( + "#stringMap.![{key: #this.key + '_k', value: #this.value + '_v'}].toMap()", + mapStringStringType, + Map("foo_k" -> "bar_v", "baz_k" -> "qux_v").asJava + ), + ( + "#mapWithDifferentValueTypes.![{key: #this.key, value: #this.value}].toMap()", + mapStringUnknownType, + mapWithDifferentValueTypes + ), + ( + "#nullableMap.![{key: #this.key, value: #this.value}].toMap()", + mapStringStringType, + nullableMap + ) + ) + ) { (expression, expectedType, expectedResult) => + val parsed = parse[Any](expr = expression, context = customCtx).validValue + parsed.returnType.withoutValue shouldBe expectedType + parsed.expression.evaluateSync[Any](customCtx) shouldBe expectedResult } } - test("should return null if castToOrNull fails") { - evaluate[Any]("#unknownString.value.castToOrNull('java.lang.Integer')") == null shouldBe true + test("should return error msg if record in map project does not contain required fields") { + parse[Any]("#mapValue.![{invalid_key: #this.key}].toMap()", ctx).invalidValue.toList should matchPattern { + case GenericFunctionError("List element must contain 'key' and 'value' fields") :: Nil => + } } - test("should castToOrNull succeed") { - evaluate[Any]("#unknownString.value.castToOrNull('java.lang.String')") shouldBe "unknown" + test("should convert value to a given type") { + val map = Map("a" -> "b").asJava + val emptyMap = Map().asJava + val list = List("a").asJava + val listOfTuples = List(Map("key" -> "a", "value" -> "b").asJava).asJava + val emptyList = List().asJava + val emptyTuplesList = List(Map().asJava).asJava + val customCtx = ctx + .withVariable("unknownInteger", ContainerOfUnknown(1)) + .withVariable("unknownBoolean", ContainerOfUnknown(false)) + .withVariable("unknownBooleanString", ContainerOfUnknown("false")) + .withVariable("unknownLong", ContainerOfUnknown(11L)) + .withVariable("unknownLongString", ContainerOfUnknown("11")) + .withVariable("unknownDouble", ContainerOfUnknown(1.1)) + .withVariable("unknownDoubleString", ContainerOfUnknown("1.1")) + .withVariable("unknownBigDecimal", ContainerOfUnknown(BigDecimal(2.1).bigDecimal)) + .withVariable("unknownBigDecimalString", ContainerOfUnknown("2.1")) + .withVariable("unknownMap", ContainerOfUnknown(map)) + .withVariable("unknownList", ContainerOfUnknown(list)) + .withVariable("unknownListOfTuples", ContainerOfUnknown(listOfTuples)) + .withVariable("unknownEmptyList", ContainerOfUnknown(emptyList)) + .withVariable("unknownEmptyTuplesList", ContainerOfUnknown(emptyTuplesList)) + val longTyping = Typed.typedClass[JLong] + val doubleTyping = Typed.typedClass[JDouble] + val bigDecimalTyping = Typed.typedClass[JBigDecimal] + val booleanTyping = Typed.typedClass[JBoolean] + val stringTyping = Typed.typedClass[String] + val mapTyping = Typed.genericTypeClass[JMap[_, _]](List(Unknown, Unknown)) + val listTyping = Typed.genericTypeClass[JList[_]](List(Unknown)) + forAll( + Table( + ("expression", "expectedType", "expectedResult"), + ("1.to('Long')", longTyping, 1), + ("1.1.to('Long')", longTyping, 1), + ("'1'.to('Long')", longTyping, 1), + ("1.toOrNull('Long')", longTyping, 1), + ("1.1.toOrNull('Long')", longTyping, 1), + ("'1'.toOrNull('Long')", longTyping, 1), + ("'a'.toOrNull('Long')", longTyping, null), + ("#unknownLong.value.to('Long')", longTyping, 11), + ("#unknownLongString.value.to('Long')", longTyping, 11), + ("#unknownDouble.value.to('Long')", longTyping, 1), + ("#unknownDoubleString.value.to('Long')", longTyping, 1), + ("#unknownBoolean.value.toOrNull('Long')", longTyping, null), + ("1.to('Double')", doubleTyping, 1.0), + ("1.1.to('Double')", doubleTyping, 1.1), + ("'1'.to('Double')", doubleTyping, 1.0), + ("1.toOrNull('Double')", doubleTyping, 1.0), + ("1.1.toOrNull('Double')", doubleTyping, 1.1), + ("'1'.toOrNull('Double')", doubleTyping, 1.0), + ("'a'.toOrNull('Double')", doubleTyping, null), + ("#unknownLong.value.to('Double')", doubleTyping, 11.0), + ("#unknownLongString.value.to('Double')", doubleTyping, 11.0), + ("#unknownDouble.value.to('Double')", doubleTyping, 1.1), + ("#unknownDoubleString.value.to('Double')", doubleTyping, 1.1), + ("#unknownBoolean.value.toOrNull('Double')", doubleTyping, null), + ("1.to('BigDecimal')", bigDecimalTyping, BigDecimal(1).bigDecimal), + ("1.1.to('BigDecimal')", bigDecimalTyping, BigDecimal(1.1).bigDecimal), + ("'1'.to('BigDecimal')", bigDecimalTyping, BigDecimal(1).bigDecimal), + ("1.toBigDecimalOrNull()", bigDecimalTyping, BigDecimal(1).bigDecimal), + ("1.1.toOrNull('BigDecimal')", bigDecimalTyping, BigDecimal(1.1).bigDecimal), + ("'1'.toOrNull('BigDecimal')", bigDecimalTyping, BigDecimal(1).bigDecimal), + ("'a'.toOrNull('BigDecimal')", bigDecimalTyping, null), + ("#unknownLong.value.to('BigDecimal')", bigDecimalTyping, BigDecimal(11).bigDecimal), + ("#unknownLongString.value.to('BigDecimal')", bigDecimalTyping, BigDecimal(11).bigDecimal), + ("#unknownDouble.value.to('BigDecimal')", bigDecimalTyping, BigDecimal(1.1).bigDecimal), + ("#unknownDoubleString.value.to('BigDecimal')", bigDecimalTyping, BigDecimal(1.1).bigDecimal), + ("#unknownBoolean.value.toOrNull('BigDecimal')", bigDecimalTyping, null), + ("'true'.to('Boolean')", booleanTyping, true), + ("#unknownInteger.value.toOrNull('Boolean')", booleanTyping, null), + ("'a'.toOrNull('Boolean')", booleanTyping, null), + ("'true'.toOrNull('Boolean')", booleanTyping, true), + ("#unknownBoolean.value.to('Boolean')", booleanTyping, false), + ("'a'.to('String')", stringTyping, "a"), + ("'a'.toOrNull('String')", stringTyping, "a"), + ("#unknownString.value.to('String')", stringTyping, "unknown"), + ("#unknownMap.value.to('Map')", mapTyping, map), + ("#unknownMap.value.toOrNull('Map')", mapTyping, map), + ("#unknownList.value.to('List')", listTyping, list), + ("#unknownList.value.toOrNull('List')", listTyping, list), + ("#unknownListOfTuples.value.to('Map')", mapTyping, map), + ("#unknownListOfTuples.value.toOrNull('Map')", mapTyping, map), + ("#unknownEmptyList.value.to('Map')", mapTyping, emptyMap), + ("#unknownEmptyList.value.to('List')", listTyping, emptyList), + ("#unknownString.value.toOrNull('Map')", mapTyping, null), + ("#unknownEmptyTuplesList.value.toOrNull('Map')", mapTyping, null), + ("#unknownEmptyTuplesList.value.to('List')", listTyping, emptyTuplesList), + ("#unknownString.value.toOrNull('List')", listTyping, null), + ("1.toLong()", longTyping, 1), + ("1.1.toLong()", longTyping, 1), + ("'1'.toLong()", longTyping, 1), + ("1.toLongOrNull()", longTyping, 1), + ("1.1.toLongOrNull()", longTyping, 1), + ("'1'.toLongOrNull()", longTyping, 1), + ("'a'.toLongOrNull()", longTyping, null), + ("#unknownLong.value.toLong()", longTyping, 11), + ("#unknownLongString.value.toLong()", longTyping, 11), + ("#unknownDouble.value.toLong()", longTyping, 1), + ("#unknownDoubleString.value.toLong()", longTyping, 1), + ("#unknownBoolean.value.toLongOrNull()", longTyping, null), + ("1.toDouble()", doubleTyping, 1.0), + ("1.1.toDouble()", doubleTyping, 1.1), + ("'1'.toDouble()", doubleTyping, 1.0), + ("1.toDoubleOrNull()", doubleTyping, 1.0), + ("1.1.toDoubleOrNull()", doubleTyping, 1.1), + ("'1'.toDoubleOrNull()", doubleTyping, 1.0), + ("'a'.toDoubleOrNull()", doubleTyping, null), + ("#unknownLong.value.toDouble()", doubleTyping, 11.0), + ("#unknownLongString.value.toDouble()", doubleTyping, 11.0), + ("#unknownDouble.value.toDouble()", doubleTyping, 1.1), + ("#unknownDoubleString.value.toDouble()", doubleTyping, 1.1), + ("#unknownBoolean.value.toDoubleOrNull()", doubleTyping, null), + ("1.toBigDecimal()", bigDecimalTyping, BigDecimal(1).bigDecimal), + ("1.1.toBigDecimal()", bigDecimalTyping, BigDecimal(1.1).bigDecimal), + ("'1'.toBigDecimal()", bigDecimalTyping, BigDecimal(1).bigDecimal), + ("1.toBigDecimalOrNull()", bigDecimalTyping, BigDecimal(1).bigDecimal), + ("1.1.toBigDecimalOrNull()", bigDecimalTyping, BigDecimal(1.1).bigDecimal), + ("'1'.toBigDecimalOrNull()", bigDecimalTyping, BigDecimal(1).bigDecimal), + ("'a'.toBigDecimalOrNull()", bigDecimalTyping, null), + ("#unknownLong.value.toBigDecimal()", bigDecimalTyping, BigDecimal(11).bigDecimal), + ("#unknownLongString.value.toBigDecimal()", bigDecimalTyping, BigDecimal(11).bigDecimal), + ("#unknownDouble.value.toBigDecimal()", bigDecimalTyping, BigDecimal(1.1).bigDecimal), + ("#unknownDoubleString.value.toBigDecimal()", bigDecimalTyping, BigDecimal(1.1).bigDecimal), + ("#unknownBoolean.value.toBigDecimalOrNull()", bigDecimalTyping, null), + ("'true'.toBoolean()", booleanTyping, true), + ("#unknownInteger.value.toBooleanOrNull()", booleanTyping, null), + ("'a'.toBooleanOrNull()", booleanTyping, null), + ("'true'.toBooleanOrNull()", booleanTyping, true), + ("#unknownBoolean.value.toBoolean()", booleanTyping, false), + ("#unknownMap.value.toMap()", mapTyping, map), + ("#unknownMap.value.toMapOrNull()", mapTyping, map), + ("#unknownList.value.toList()", listTyping, list), + ("#unknownList.value.toListOrNull()", listTyping, list), + ("#unknownListOfTuples.value.toMap()", mapTyping, map), + ("#unknownListOfTuples.value.toMapOrNull()", mapTyping, map), + ("#unknownEmptyList.value.toMap()", mapTyping, emptyMap), + ("#unknownEmptyList.value.toList()", listTyping, emptyList), + ("#unknownString.value.toMapOrNull()", mapTyping, null), + ("#unknownEmptyTuplesList.value.toMapOrNull()", mapTyping, null), + ("#unknownEmptyTuplesList.value.toList()", listTyping, emptyTuplesList), + ("#unknownString.value.toListOrNull()", listTyping, null), + ("#arrayOfUnknown.toList()", listTyping, List("unknown").asJava), + ) + ) { (expression, expectedType, expectedResult) => + val parsed = parse[Any](expr = expression, context = customCtx).validValue + parsed.returnType.withoutValue shouldBe expectedType + parsed.expression.evaluateSync[Any](customCtx) shouldBe expectedResult + } } - test("should allow invoke cast methods with class simple names") { - evaluate[Any]( - "{#unknownString.value.castToOrNull('String'), #unknownString.value.castTo('String'), " + - "#unknownString.value.canCastTo('String')}" - ) shouldBe List("unknown", "unknown", true).asJava + test("should check if unknown can be converted to a given type") { + val map = Map("a" -> "b").asJava + val list = List("a").asJava + val tuplesList = List(Map("key" -> "a", "value" -> "b").asJava).asJava + val customCtx = ctx + .withVariable("unknownBoolean", ContainerOfUnknown(true)) + .withVariable("unknownBooleanString", ContainerOfUnknown("false")) + .withVariable("unknownLong", ContainerOfUnknown(11L)) + .withVariable("unknownLongString", ContainerOfUnknown("11")) + .withVariable("unknownDouble", ContainerOfUnknown(1.1)) + .withVariable("unknownDoubleString", ContainerOfUnknown("1.1")) + .withVariable("unknownBigDecimal", ContainerOfUnknown(BigDecimal(2.1).bigDecimal)) + .withVariable("unknownBigDecimalString", ContainerOfUnknown("2.1")) + .withVariable("unknownList", ContainerOfUnknown(list)) + .withVariable("unknownListOfTuples", ContainerOfUnknown(tuplesList)) + .withVariable("unknownMap", ContainerOfUnknown(map)) + forAll( + Table( + ("expression", "result"), + ("#unknownBoolean.value.is('Boolean')", true), + ("#unknownBooleanString.value.is('Boolean')", true), + ("#unknownString.value.is('Boolean')", false), + ("#unknownLong.value.is('Long')", true), + ("#unknownLongString.value.is('Long')", true), + ("#unknownString.value.is('Long')", false), + ("#unknownDouble.value.is('Double')", true), + ("#unknownDoubleString.value.is('Double')", true), + ("#unknownString.value.is('Double')", false), + ("#unknownBigDecimal.value.is('BigDecimal')", true), + ("#unknownBigDecimalString.value.is('BigDecimal')", true), + ("#unknownString.value.is('BigDecimal')", false), + ("#unknownList.value.is('List')", true), + ("#unknownList.value.is('Map')", false), + ("#unknownMap.value.is('List')", false), + ("#unknownMap.value.is('Map')", true), + ("#unknownListOfTuples.value.is('List')", true), + ("#unknownListOfTuples.value.is('Map')", true), + ("#unknownBoolean.value.isBoolean()", true), + ("#unknownBooleanString.value.isBoolean()", true), + ("#unknownString.value.isBoolean()", false), + ("#unknownLong.value.isLong()", true), + ("#unknownLongString.value.isLong()", true), + ("#unknownString.value.isLong()", false), + ("#unknownDouble.value.isDouble()", true), + ("#unknownDoubleString.value.isDouble()", true), + ("#unknownString.value.isDouble()", false), + ("#unknownBigDecimal.value.isBigDecimal()", true), + ("#unknownBigDecimalString.value.isBigDecimal()", true), + ("#unknownString.value.isBigDecimal()", false), + ("#unknownList.value.isList()", true), + ("#unknownList.value.isMap()", false), + ("#unknownMap.value.isList()", false), + ("#unknownMap.value.isMap()", true), + ("#unknownListOfTuples.value.isList()", true), + ("#unknownListOfTuples.value.isMap()", true), + ("#arrayOfUnknown.isList()", true), + ) + ) { (expression, result) => + evaluate[Any](expression, customCtx) shouldBe result + } + } + + test("should throw exception if a value cannot be converted to primitive") { + val customCtx = ctx + .withVariable("unknownBoolean", ContainerOfUnknown(true)) + .withVariable("unknownLong", ContainerOfUnknown(11L)) + .withVariable("unknownDouble", ContainerOfUnknown(1.1)) + .withVariable("unknownBigDecimal", ContainerOfUnknown(BigDecimal(2.1).bigDecimal)) + Table( + "expression", + "#unknownDouble.value.toBoolean()", + "#unknownLong.value.toBoolean()", + "#unknownString.value.toBoolean()", + "#unknownString.value.toLong()", + "#unknownBoolean.value.toLong()", + "#unknownString.value.toDouble()", + "#unknownBoolean.value.toDouble()", + "#unknownBoolean.value.toBigDecimal()", + "#unknownString.value.toBigDecimal()", + "#unknownString.value.toList()", + "#unknownString.value.toMap()", + ).forEvery { expression => + val caught = intercept[SpelExpressionEvaluationException] { + evaluate[Any](expression, customCtx) + } + caught.getCause.getMessage should ( + include("Cannot convert:") or + include("is neither a decimal digit number") + ) + } } } diff --git a/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/util/classes/ExtensionsSpec.scala b/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/util/classes/ExtensionsSpec.scala deleted file mode 100644 index bb8bca251a5..00000000000 --- a/scenario-compiler/src/test/scala/pl/touk/nussknacker/engine/util/classes/ExtensionsSpec.scala +++ /dev/null @@ -1,30 +0,0 @@ -package pl.touk.nussknacker.engine.util.classes - -import org.scalatest.funsuite.AnyFunSuite -import org.scalatest.matchers.should.Matchers -import pl.touk.nussknacker.engine.util.classes.Extensions.ClassesExtensions - -class ExtensionsSpec extends AnyFunSuite with Matchers { - - object A { - class C {} - } - - object B { - class C {} - } - - class D {} - - test("should return simples names and full name for non unique class names") { - val ac = classOf[A.C] - val bc = classOf[B.C] - val d = classOf[D] - Set[Class[_]](ac, bc, d).classesBySimpleNamesRegardingClashes() shouldBe Map( - "pl.touk.nussknacker.engine.util.classes.ExtensionsSpec$A$C" -> ac, - "pl.touk.nussknacker.engine.util.classes.ExtensionsSpec$B$C" -> bc, - "D" -> d - ) - } - -} diff --git a/utils/default-helpers/src/main/scala/pl/touk/nussknacker/engine/util/functions/conversion.scala b/utils/default-helpers/src/main/scala/pl/touk/nussknacker/engine/util/functions/conversion.scala index 52350def8a0..0b8810cac0b 100644 --- a/utils/default-helpers/src/main/scala/pl/touk/nussknacker/engine/util/functions/conversion.scala +++ b/utils/default-helpers/src/main/scala/pl/touk/nussknacker/engine/util/functions/conversion.scala @@ -2,7 +2,6 @@ package pl.touk.nussknacker.engine.util.functions import pl.touk.nussknacker.engine.api.generics.GenericType import pl.touk.nussknacker.engine.api.{Documentation, HideToString, ParamName} -import pl.touk.nussknacker.engine.util.functions.ConversionUtils.{stringToBigInteger, stringToBoolean} import pl.touk.nussknacker.engine.util.functions.NumericUtils.ToNumberTypingFunction import pl.touk.nussknacker.engine.util.json.{JsonUtils, ToJsonEncoder} @@ -31,114 +30,6 @@ trait ConversionUtils extends HideToString { case _ => null } - @Documentation(description = "Convert any value to String") - def toString(@ParamName("value") value: Any): java.lang.String = value match { - case v: String => v - case null => null - case v => v.toString - } - - @Documentation(description = "Convert any value to Boolean or throw exception in case of failure") - def toBoolean(@ParamName("value") value: Any): java.lang.Boolean = value match { - case v: String => - stringToBoolean(v).getOrElse { - throw new IllegalArgumentException(s"Cannot convert: $value to Boolean") - } - case v: java.lang.Boolean => v - case null => null - case _ => throw new IllegalArgumentException(s"Cannot convert: $value to Boolean") - } - - @Documentation(description = "Convert any value to Boolean or throw exception in case of failure") - def toBooleanOrNull(@ParamName("value") value: Any): java.lang.Boolean = value match { - case v: String => stringToBoolean(v).orNull - case v: java.lang.Boolean => v - case _ => null - } - - @Documentation(description = "Convert any value to Integer or throw exception in case of failure") - def toInteger(@ParamName("value") value: Any): java.lang.Integer = value match { - case v: String => Integer.valueOf(numeric.toNumber(v).intValue()) - case v: Number => v.intValue() - case null => null - case _ => throw new IllegalArgumentException(s"Cannot convert: $value to Integer") - } - - @Documentation(description = "Convert any value to Integer or null in case of failure") - def toIntegerOrNull(@ParamName("value") value: Any): java.lang.Integer = value match { - case v: String => Try(Integer.valueOf(numeric.toNumber(v).intValue())).getOrElse(null) - case v: Number => v.intValue() - case _ => null - } - - @Documentation(description = "Convert any value to Long or throw exception in case of failure") - def toLong(@ParamName("value") value: Any): java.lang.Long = value match { - case v: String => java.lang.Long.valueOf(numeric.toNumber(v).longValue()) - case v: Number => v.longValue() - case null => null - case _ => throw new IllegalArgumentException(s"Cannot convert: $value to Long") - } - - @Documentation(description = "Convert any value to Long or null in case of failure") - def toLongOrNull(@ParamName("value") value: Any): java.lang.Long = value match { - case v: String => Try(java.lang.Long.valueOf(numeric.toNumber(v).longValue())).getOrElse(null) - case v: Number => v.longValue() - case _ => null - } - - @Documentation(description = "Convert any value to Double or throw exception in case of failure") - def toDouble(@ParamName("value") value: Any): java.lang.Double = value match { - case v: String => java.lang.Double.valueOf(numeric.toNumber(v).doubleValue()) - case v: Number => v.doubleValue() - case null => null - case _ => throw new IllegalArgumentException(s"Cannot convert: $value to Double") - } - - @Documentation(description = "Convert any value to Double or null in case of failure") - def toDoubleOrNull(@ParamName("value") value: Any): java.lang.Double = value match { - case v: String => Try(java.lang.Double.valueOf(numeric.toNumber(v).doubleValue())).getOrElse(null) - case v: Number => v.doubleValue() - case _ => null - } - - @Documentation(description = "Convert any value to BigInteger or throw exception in case of failure") - def toBigInteger(@ParamName("value") value: Any): java.math.BigInteger = value match { - case v: String => stringToBigInteger(v) - case v: java.math.BigInteger => v - case v: java.math.BigDecimal => v.toBigInteger - case v: Number => java.math.BigInteger.valueOf(v.longValue()) - case null => null - case _ => throw new IllegalArgumentException(s"Cannot convert: $value to BigInteger") - } - - @Documentation(description = "Convert any value to BigInteger or null in case of failure") - def toBigIntegerOrNull(@ParamName("value") value: Any): java.math.BigInteger = value match { - case v: String => Try(stringToBigInteger(v)).getOrElse(null) - case v: java.math.BigInteger => v - case v: java.math.BigDecimal => v.toBigInteger - case v: Number => java.math.BigInteger.valueOf(v.longValue()) - case _ => null - } - - @Documentation(description = "Convert any value to BigDecimal or throw exception in case of failure") - def toBigDecimal(@ParamName("value") value: Any): java.math.BigDecimal = value match { - case v: String => new java.math.BigDecimal(v) - case v: java.math.BigInteger => new java.math.BigDecimal(v) - case v: java.math.BigDecimal => v - case v: Number => new java.math.BigDecimal(v.toString) - case null => null - case _ => throw new IllegalArgumentException(s"Cannot convert: $value to BigDecimal") - } - - @Documentation(description = "Convert any value to BigDecimal or null in case of failure") - def toBigDecimalOrNull(@ParamName("value") value: Any): java.math.BigDecimal = value match { - case v: String => Try(new java.math.BigDecimal(v)).getOrElse(null) - case v: java.math.BigInteger => new java.math.BigDecimal(v) - case v: java.math.BigDecimal => v - case v: Number => Try(new java.math.BigDecimal(v.toString)).getOrElse(null) - case _ => null - } - @Documentation(description = "Convert String value to JSON") def toJson(@ParamName("value") value: String): Any = { toJsonEither(value).toTry.get @@ -164,22 +55,3 @@ trait ConversionUtils extends HideToString { private lazy val jsonEncoder = new ToJsonEncoder(true, this.getClass.getClassLoader) } - -object ConversionUtils { - - private def stringToBigInteger(value: String): java.math.BigInteger = - numeric.toNumber(value) match { - case n: java.math.BigInteger => n - case n => java.math.BigInteger.valueOf(n.longValue()) - } - - private def stringToBoolean(value: String): Option[java.lang.Boolean] = - if ("true".equalsIgnoreCase(value)) { - Some(true) - } else if ("false".equalsIgnoreCase(value)) { - Some(false) - } else { - None - } - -} diff --git a/utils/default-helpers/src/test/scala/pl/touk/nussknacker/engine/util/functions/ConversionUtilsSpec.scala b/utils/default-helpers/src/test/scala/pl/touk/nussknacker/engine/util/functions/ConversionUtilsSpec.scala index 54ab7ac6263..6f993264605 100644 --- a/utils/default-helpers/src/test/scala/pl/touk/nussknacker/engine/util/functions/ConversionUtilsSpec.scala +++ b/utils/default-helpers/src/test/scala/pl/touk/nussknacker/engine/util/functions/ConversionUtilsSpec.scala @@ -19,75 +19,6 @@ class ConversionUtilsSpec extends AnyFunSuite with BaseSpelSpec with Matchers { ("#CONV.toNumberOrNull('a')", null), ("#CONV.toNumberOrNull(null)", null), ("#CONV.toNumberOrNull(true)", null), - ("#CONV.toString(1)", "1"), - ("#CONV.toString(1.1)", "1.1"), - ("#CONV.toString('a')", "a"), - ("#CONV.toString(null)", null), - ("#CONV.toString(true)", "true"), - ("#CONV.toBoolean(null)", null), - ("#CONV.toBoolean(true)", true), - ("#CONV.toBoolean('true')", true), - ("#CONV.toBooleanOrNull(1)", null), - ("#CONV.toBooleanOrNull(1.1)", null), - ("#CONV.toBooleanOrNull('a')", null), - ("#CONV.toBooleanOrNull(null)", null), - ("#CONV.toBooleanOrNull(true)", true), - ("#CONV.toBooleanOrNull('true')", true), - ("#CONV.toInteger(1)", 1), - ("#CONV.toInteger(1.1)", 1), - ("#CONV.toInteger('1')", 1), - ("#CONV.toInteger(null)", null), - ("#CONV.toIntegerOrNull(1)", 1), - ("#CONV.toIntegerOrNull(1.1)", 1), - ("#CONV.toIntegerOrNull('1')", 1), - ("#CONV.toIntegerOrNull('a')", null), - ("#CONV.toIntegerOrNull(null)", null), - ("#CONV.toIntegerOrNull(true)", null), - ("#CONV.toIntegerOrNull('true')", null), - ("#CONV.toLong(1)", 1), - ("#CONV.toLong(1.1)", 1), - ("#CONV.toLong('1')", 1), - ("#CONV.toLong(null)", null), - ("#CONV.toLongOrNull(1)", 1), - ("#CONV.toLongOrNull(1.1)", 1), - ("#CONV.toLongOrNull('1')", 1), - ("#CONV.toLongOrNull('a')", null), - ("#CONV.toLongOrNull(null)", null), - ("#CONV.toLongOrNull(true)", null), - ("#CONV.toLongOrNull('true')", null), - ("#CONV.toDouble(1)", 1.0), - ("#CONV.toDouble(1.1)", 1.1), - ("#CONV.toDouble('1')", 1.0), - ("#CONV.toDouble(null)", null), - ("#CONV.toDoubleOrNull(1)", 1.0), - ("#CONV.toDoubleOrNull(1.1)", 1.1), - ("#CONV.toDoubleOrNull('1')", 1.0), - ("#CONV.toDoubleOrNull('a')", null), - ("#CONV.toDoubleOrNull(null)", null), - ("#CONV.toDoubleOrNull(true)", null), - ("#CONV.toDoubleOrNull('true')", null), - ("#CONV.toBigInteger(1)", BigInt(1).bigInteger), - ("#CONV.toBigInteger(1.1)", BigInt(1).bigInteger), - ("#CONV.toBigInteger('1')", BigInt(1).bigInteger), - ("#CONV.toBigInteger(null)", null), - ("#CONV.toBigIntegerOrNull(1)", BigInt(1).bigInteger), - ("#CONV.toBigIntegerOrNull(1.1)", BigInt(1).bigInteger), - ("#CONV.toBigIntegerOrNull('1')", BigInt(1).bigInteger), - ("#CONV.toBigIntegerOrNull('a')", null), - ("#CONV.toBigIntegerOrNull(null)", null), - ("#CONV.toBigIntegerOrNull(true)", null), - ("#CONV.toBigIntegerOrNull('true')", null), - ("#CONV.toBigDecimal(1)", BigDecimal(1).bigDecimal), - ("#CONV.toBigDecimal(1.1)", BigDecimal(1.1).bigDecimal), - ("#CONV.toBigDecimal('1')", BigDecimal(1).bigDecimal), - ("#CONV.toBigDecimal(null)", null), - ("#CONV.toBigDecimalOrNull(1)", BigDecimal(1).bigDecimal), - ("#CONV.toBigDecimalOrNull(1.1)", BigDecimal(1.1).bigDecimal), - ("#CONV.toBigDecimalOrNull('1')", BigDecimal(1).bigDecimal), - ("#CONV.toBigDecimalOrNull('a')", null), - ("#CONV.toBigDecimalOrNull(null)", null), - ("#CONV.toBigDecimalOrNull(true)", null), - ("#CONV.toBigDecimalOrNull('true')", null), ).forEvery { (expression, expected) => evaluateAny(expression) shouldBe expected } @@ -95,57 +26,11 @@ class ConversionUtilsSpec extends AnyFunSuite with BaseSpelSpec with Matchers { Table( ("expression", "expected"), ("#CONV.toNumberOrNull(1)", "Number"), - ("#CONV.toString(1)", "String"), - ("#CONV.toBoolean('true')", "Boolean"), - ("#CONV.toBooleanOrNull('true')", "Boolean"), - ("#CONV.toInteger('true')", "Integer"), - ("#CONV.toIntegerOrNull('true')", "Integer"), - ("#CONV.toLong('true')", "Long"), - ("#CONV.toLongOrNull('true')", "Long"), - ("#CONV.toDouble('true')", "Double"), - ("#CONV.toDoubleOrNull('true')", "Double"), - ("#CONV.toBigInteger('true')", "BigInteger"), - ("#CONV.toBigIntegerOrNull('true')", "BigInteger"), - ("#CONV.toBigDecimal('true')", "BigDecimal"), - ("#CONV.toBigDecimalOrNull('true')", "BigDecimal"), ).forEvery { (expression, expected) => evaluateType(expression, types = Map.empty) shouldBe expected.valid } } - test("should throw exception if a value cannot be converted to primitive") { - Table( - "expression", - "#CONV.toBoolean('a')", - "#CONV.toBoolean(1)", - "#CONV.toBoolean(1.1)", - "#CONV.toInteger('a')", - "#CONV.toInteger(true)", - "#CONV.toInteger('true')", - "#CONV.toLong('a')", - "#CONV.toLong(true)", - "#CONV.toLong('true')", - "#CONV.toDouble('a')", - "#CONV.toDouble(true)", - "#CONV.toDouble('true')", - "#CONV.toBigInteger('a')", - "#CONV.toBigInteger(true)", - "#CONV.toBigInteger('true')", - "#CONV.toBigDecimal('a')", - "#CONV.toBigDecimal(true)", - "#CONV.toBigDecimal('true')", - ).forEvery { expression => - val caught = intercept[SpelExpressionEvaluationException] { - evaluateAny(expression, Map.empty) - } - caught.getMessage should ( - include("Cannot convert:") or - include("is neither a decimal digit number") or - include("For input string:") - ) - } - } - test("parse JSON") { Table( ("expression", "expected"),