This is an automated email from the ASF dual-hosted git repository.

sergeykamov pushed a commit to branch NLPCRAFT-491
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git


The following commit(s) were added to refs/heads/NLPCRAFT-491 by this push:
     new 4d2154f0 WIP.
4d2154f0 is described below

commit 4d2154f0b0ad28fbc94244c76c3e5d6b6025bc07
Author: Sergey Kamov <[email protected]>
AuthorDate: Thu Apr 7 12:26:28 2022 +0300

    WIP.
---
 .../nlpcraft/examples/order/OrderModel.scala       | 12 +++----
 ...taExtenderMapper.scala => EntityExtender.scala} | 37 +++++++++++--------
 .../order/components/RequestValidator.scala        | 42 ++++++++++++++++++++++
 .../order/components/StanfordPipeline.scala        | 15 +++++---
 4 files changed, 81 insertions(+), 25 deletions(-)

diff --git 
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/OrderModel.scala
 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/OrderModel.scala
index 9f4ba3bf..58c84685 100644
--- 
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/OrderModel.scala
+++ 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/OrderModel.scala
@@ -41,6 +41,7 @@ import scala.jdk.OptionConverters.*
   */
 object OrderModel extends LazyLogging:
     private val DFLT_QTY = 1
+    private val UNEXPECTED = new NCRejection("Unexpected request in given 
context.")
     private def toStr[T](name: String, seq: Iterable[T]): String = if 
seq.nonEmpty then s"$name: ${seq.mkString(", ")}." else ""
     private def extractPizzaSize(e: NCEntity): String = 
e.get[String]("ord:pizza:size:value")
     private def extractQty(e: NCEntity, qty: String): Option[Int] = 
Option.when(e.contains(qty))(e.get[String](qty).toDouble.toInt)
@@ -156,7 +157,7 @@ class OrderModel extends NCModelAdapter (new 
NCModelConfig("nlpcraft.order.ex",
                 doExecute(im, o)
             case DIALOG_SHOULD_CANCEL => doStop(im, o)
             case DIALOG_IS_READY => askConfirmOrAskSpecify(o)
-            case DIALOG_SPECIFY | NO_DIALOG => throw new 
NCRejection("Unexpected request.")
+            case DIALOG_SPECIFY | NO_DIALOG => throw UNEXPECTED
     )
 
     /**
@@ -170,7 +171,7 @@ class OrderModel extends NCModelAdapter (new 
NCModelConfig("nlpcraft.order.ex",
         (o: Order) => o.getState match
             case DIALOG_CONFIRM | DIALOG_IS_READY => doContinue(o)
             case DIALOG_SHOULD_CANCEL => askConfirmOrAskSpecify(o)
-            case DIALOG_SPECIFY | NO_DIALOG => throw new 
NCRejection("Unexpected request.")
+            case DIALOG_SPECIFY | NO_DIALOG => throw UNEXPECTED
         )
     /**
       *
@@ -195,7 +196,7 @@ class OrderModel extends NCModelAdapter (new 
NCModelConfig("nlpcraft.order.ex",
     def onOrder(im: NCIntentMatch, @NCIntentTerm("ps") ps: List[NCEntity], 
@NCIntentTerm("ds") ds: List[NCEntity]): NCResult = withLog(
         im,
         (o: Order) =>
-            if ps.isEmpty && ds.isEmpty then throw new NCRejection("Please 
order some pizza or drinks");
+            require(ps.nonEmpty || ds.nonEmpty);
             o.add(ps.map(extractPizza), ds.map(extractDrink)); // It doesn't 
depend on order validity and dialog state.
             askIsReadyOrAskSpecify(o)
         )
@@ -213,9 +214,8 @@ class OrderModel extends NCModelAdapter (new 
NCModelConfig("nlpcraft.order.ex",
                 if o.setPizzaNoSize(extractPizzaSize(size)) then
                     o.setState(NO_DIALOG);
                     askIsReadyOrAskSpecify(o)
-                else
-                    throw new NCRejection("Unexpected request.")
-            case DIALOG_CONFIRM | NO_DIALOG | DIALOG_IS_READY | 
DIALOG_SHOULD_CANCEL => throw new NCRejection("Unexpected request.")
+                else throw UNEXPECTED
+            case DIALOG_CONFIRM | NO_DIALOG | DIALOG_IS_READY | 
DIALOG_SHOULD_CANCEL => throw UNEXPECTED
         )
     /**
       *
diff --git 
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/DataExtenderMapper.scala
 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/EntityExtender.scala
similarity index 57%
rename from 
nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/DataExtenderMapper.scala
rename to 
nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/EntityExtender.scala
index 44278aea..dbd772c3 100644
--- 
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/DataExtenderMapper.scala
+++ 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/EntityExtender.scala
@@ -26,31 +26,40 @@ import scala.jdk.CollectionConverters.*
 
 /**
   *
+  * @param id
+  * @param copyProperty
   */
-case class DataExtenderMapper(key: String, prop: String, extKey: String, 
extProp: String) extends NCEntityMapper:
-    private def extract(e: NCEntity): mutable.Seq[NCToken] = 
e.getTokens.asScala
+case class EntityData(id: String, copyProperty: String)
+
+/**
+  *
+  */
+case class EntityExtender(mainDataSeq: Seq[EntityData], extraData: EntityData) 
extends NCEntityMapper:
+    private def getToks(e: NCEntity): mutable.Seq[NCToken] = 
e.getTokens.asScala
     override def map(req: NCRequest, cfg: NCModelConfig, entities: 
util.List[NCEntity]): util.List[NCEntity] =
+        val mainDataMap = mainDataSeq.map(p => p.id -> p).toMap
+
         var es = entities.asScala
-        val data = es.filter(_.getId == key)
-        val extData = es.filter(_.getId == extKey)
+        val main = es.filter(e => mainDataMap.contains(e.getId))
+        val extra = es.filter(_.getId == extraData.id)
 
-        if data.nonEmpty && data.size == extData.size then
+        if main.nonEmpty && main.size == extra.size then
             var ok = true
             val mapped =
-                for ((e1, e2) <- data.zip(extData) if ok) yield
+                for ((e1, e2) <- main.zip(extra) if ok) yield
                     if e1.getId == e2.getId then
                         ok = false
                         null
                     else
-                        val (data, extData) = if e1.getId == key then (e1, e2) 
else (e2, e1)
+                        val (mEnt, eEnt) = if mainDataMap.contains(e1.getId) 
then (e1, e2) else (e2, e1)
                         new NCPropertyMapAdapter with NCEntity:
-                            data.keysSet().forEach(k => put(k, data.get(k)))
-                            put[String](prop, 
extData.get[String](extProp).toLowerCase)
-                            override val getTokens: JList[NCToken] = 
(extract(data) ++ extract(extData)).sortBy(_.getIndex).asJava
+                            mEnt.keysSet().forEach(k => put(k, mEnt.get(k)))
+                            put[String](mainDataMap(mEnt.getId).copyProperty, 
eEnt.get[String](extraData.copyProperty).toLowerCase)
+                            override val getTokens: JList[NCToken] = 
(getToks(mEnt) ++ getToks(eEnt)).sortBy(_.getIndex).asJava
                             override val getRequestId: String = 
req.getRequestId
-                            override val getId: String = data.getId
+                            override val getId: String = mEnt.getId
 
-            es = es --= data
-            es = es --= extData
-            (es ++ mapped).sortBy(extract(_).head.getIndex).asJava
+            es = es --= main
+            es = es --= extra
+            (es ++ mapped).sortBy(getToks(_).head.getIndex).asJava
         else entities
\ No newline at end of file
diff --git 
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/RequestValidator.scala
 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/RequestValidator.scala
new file mode 100644
index 00000000..ea1534b7
--- /dev/null
+++ 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/RequestValidator.scala
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nlpcraft.examples.order.components
+
+import org.apache.nlpcraft.*
+
+import java.util
+import scala.jdk.CollectionConverters.*
+
+/**
+  *
+  */
+class RequestValidator extends NCEntityValidator:
+    override def validate(req: NCRequest, cfg: NCModelConfig, ents: 
util.List[NCEntity]): Unit =
+        val es = ents.asScala
+
+        def count(id: String): Int = es.count(_.getId == id)
+
+        val cntPizza = count("ord:pizza")
+        val cntDrink = count("ord:drink")
+        val cntNums = count("stanford:number")
+        val cntSize = count("ord:pizza:size")
+
+        if cntNums != 1 && cntNums > cntPizza + cntDrink then
+            throw new NCRejection("Too many unrecognized numerics in the 
request.")
+        if cntSize != 1 && cntSize > cntPizza then
+            throw new NCRejection("Too many unrecognized pizza sizes in the 
request.")
\ No newline at end of file
diff --git 
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/StanfordPipeline.scala
 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/StanfordPipeline.scala
index 440cd61c..34bebf67 100644
--- 
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/StanfordPipeline.scala
+++ 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/components/StanfordPipeline.scala
@@ -42,14 +42,19 @@ object StanfordPipeline:
             private val ps = new PorterStemmer
             override def stem(txt: String): String = ps.synchronized { 
ps.stem(txt) }
 
+        import EntityExtender as Ex
+        import EntityData as D
+
         new NCPipelineBuilder().
             withTokenParser(tokParser).
             withTokenEnricher(new NCEnStopWordsTokenEnricher()).
             withEntityParser(new NCStanfordNLPEntityParser(stanford, 
"number")).
             withEntityParser(new NCSemanticEntityParser(stemmer, tokParser, 
"order_model.yaml")).
-            withEntityMappers(Seq(
-                DataExtenderMapper(key = "ord:pizza", prop = "ord:pizza:size", 
extKey = "ord:pizza:size", extProp = "ord:pizza:size:value"),
-                DataExtenderMapper(key = "ord:pizza", prop = "ord:pizza:qty", 
extKey = "stanford:number", extProp = "stanford:number:nne"),
-                DataExtenderMapper(key = "ord:drink", prop = "ord:drink:qty", 
extKey = "stanford:number", extProp = "stanford:number:nne")
-            ).asJava).
+            withEntityMappers(
+                Seq(
+                    Ex(Seq(D("ord:pizza", "ord:pizza:size")), 
D("ord:pizza:size", "ord:pizza:size:value")),
+                    Ex(Seq(D("ord:pizza", "ord:pizza:qty"), D("ord:drink", 
"ord:drink:qty")), D("stanford:number", "stanford:number:nne")),
+                ).asJava
+            ).
+            withEntityValidator(new RequestValidator()).
             build()
\ No newline at end of file

Reply via email to