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

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


The following commit(s) were added to refs/heads/master_test by this push:
     new 2bc6e3c  WIP.
2bc6e3c is described below

commit 2bc6e3cf0a733211b1be05a14df97b0e02a799f6
Author: Sergey Kamov <[email protected]>
AuthorDate: Fri Dec 10 16:31:19 2021 +0300

    WIP.
---
 nlpcraft/pom.xml                                   |  15 +++
 .../impl/enrichers/entity/NCUserEntityParser.scala |  32 -----
 ...ityParser.scala => NCOpenNlpEntityParser.scala} |   6 +-
 ...MoneyEntityParser.scala => NCOpenNlpModel.java} |  23 +++-
 .../opennlp/NCOpenNlpPercentageEntityParser.scala  |  25 ----
 .../opennlp/NCOpenNlpPersonEntityParser.scala      |  25 ----
 .../entity/opennlp/NCOpenNlpTimeEntityParser.scala |  25 ----
 .../NCElement.java}                                |  17 ++-
 .../enrichers/entity/user/NCElementBuilder.java    |  56 +++++++++
 .../entity/{ => user}/NCFileUserEntityParser.scala |   9 +-
 .../NCUserEntityParser.scala}                      |   7 +-
 .../impl/enrichers/entity/user/NCValue.java        |  48 ++++++++
 .../impl/enrichers/entity/user/NCValueLoader.java  |  62 ++++++++++
 .../nlpcraft/impl/tokenizers/NCEnTokenParser.scala |  12 +-
 .../external/NCExternalConfigManager.java}         |  20 +++-
 .../nlpcraft/alarm/LightSwitchModelTest.java       | 133 ++++++++++-----------
 .../nlpcraft/alarm/LightSwitchModelTest2.java      |  75 ------------
 nlpcraft/src/test/resources/lightswitch_model.json |  21 ++--
 nlpcraft/src/test/resources/lightswitch_model.yaml |  16 ++-
 pom.xml                                            |  21 ++++
 20 files changed, 355 insertions(+), 293 deletions(-)

diff --git a/nlpcraft/pom.xml b/nlpcraft/pom.xml
index a01bc70..b4290aa 100644
--- a/nlpcraft/pom.xml
+++ b/nlpcraft/pom.xml
@@ -85,6 +85,16 @@
          ===================
         -->
         <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+
+        <dependency>
             <groupId>org.antlr</groupId>
             <artifactId>antlr4-runtime</artifactId>
         </dependency>
@@ -94,6 +104,11 @@
             <artifactId>gson</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.opennlp</groupId>
+            <artifactId>opennlp-tools</artifactId>
+        </dependency>
+
         <!--
          JUnit & ScalaTest dependencies.
          ===============================
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCUserEntityParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCUserEntityParser.scala
deleted file mode 100644
index d74ffd1..0000000
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCUserEntityParser.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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
- *
- *      https://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.impl.enrichers.entity
-
-import org.apache.nlpcraft.*
-
-import java.util
-
-class NCUserEntityParser(
-    // Element ID / Map element properties (parent, group, etc)
-    elementsProperites: util.Map[String, util.Map[String, String]],
-    // Macros ID / Macros body.
-    macros: util.Map[String, String],
-    // Element ID / Synonyms list, based on words and macros.
-    elementsSynonyms: util.Map[String, util.List[String]]
-) extends NCEntityParser {
-    override def parse(req: NCRequest, cfg: NCModelConfig, toks: 
util.List[NCToken]): util.List[NCEntity] = ???
-}
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpDateEntityParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpEntityParser.scala
similarity index 82%
rename from 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpDateEntityParser.scala
rename to 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpEntityParser.scala
index 5bb1d87..4edc0b3 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpDateEntityParser.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpEntityParser.scala
@@ -18,8 +18,12 @@ package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
 import org.apache.nlpcraft.{NCEntity, NCEntityParser, NCModelConfig, 
NCRequest, NCToken}
 
+import org.apache.nlpcraft.internal.external.NCExternalConfigManager
 import java.util
 
-class NCOpenNlpDateEntityParser extends NCEntityParser {
+class NCOpenNlpEntityParse(models: util.List[NCOpenNlpModel], extCfgMgr: 
NCExternalConfigManager) extends NCEntityParser {
+    def start(): Unit = {
+    }
+
     override def parse(req: NCRequest, cfg: NCModelConfig, toks: 
util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpMoneyEntityParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpModel.java
similarity index 66%
rename from 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpMoneyEntityParser.scala
rename to 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpModel.java
index 18378e0..4d5c3b3 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpMoneyEntityParser.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpModel.java
@@ -14,12 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nlpcraft.impl.enrichers.entity.opennlp
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp;
 
-import org.apache.nlpcraft.*
 
-import java.util
+import java.io.File;
 
-class NCOpenNlpMoneyEntityParser extends NCEntityParser {
-    override def parse(req: NCRequest, cfg: NCModelConfig, toks: 
util.List[NCToken]): util.List[NCEntity] = ???
+public class NCOpenNlpModel {
+    private String elementId;
+    private File path;
+
+    public NCOpenNlpModel(String elementId, File path) {
+        this.elementId = elementId;
+        this.path = path;
+    }
+
+    public String getElementId() {
+        return elementId;
+    }
+
+    public File getPath() {
+        return path;
+    }
 }
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPercentageEntityParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPercentageEntityParser.scala
deleted file mode 100644
index ecc1bd6..0000000
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPercentageEntityParser.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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
- *
- *      https://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.impl.enrichers.entity.opennlp
-
-import org.apache.nlpcraft.*
-
-import java.util
-
-class NCOpenNlpPercentageEntityParser extends NCEntityParser {
-    override def parse(req: NCRequest, cfg: NCModelConfig, toks: 
util.List[NCToken]): util.List[NCEntity] = ???
-}
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPersonEntityParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPersonEntityParser.scala
deleted file mode 100644
index 2b4e2ef..0000000
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPersonEntityParser.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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
- *
- *      https://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.impl.enrichers.entity.opennlp
-
-import org.apache.nlpcraft.*
-
-import java.util
-
-class NCOpenNlpPersonEntityParser extends NCEntityParser {
-    override def parse(req: NCRequest, cfg: NCModelConfig, toks: 
util.List[NCToken]): util.List[NCEntity] = ???
-}
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpTimeEntityParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpTimeEntityParser.scala
deleted file mode 100644
index e71870b..0000000
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpTimeEntityParser.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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
- *
- *      https://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.impl.enrichers.entity.opennlp
-
-import org.apache.nlpcraft.*
-
-import java.util
-
-class NCOpenNlpTimeEntityParser extends NCEntityParser {
-    override def parse(req: NCRequest, cfg: NCModelConfig, toks: 
util.List[NCToken]): util.List[NCEntity] = ???
-}
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpOrganizationEntityParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCElement.java
similarity index 67%
rename from 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpOrganizationEntityParser.scala
rename to 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCElement.java
index 560eb88..66f6812 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpOrganizationEntityParser.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCElement.java
@@ -14,12 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nlpcraft.impl.enrichers.entity.opennlp
+package org.apache.nlpcraft.impl.enrichers.entity.user;
 
-import org.apache.nlpcraft.*
+import java.util.Optional;
+import java.util.Set;
+import org.apache.nlpcraft.NCParameterized;
 
-import java.util
-
-class NCOpenNlpOrganizationEntityParser extends NCEntityParser {
-    override def parse(req: NCRequest, cfg: NCModelConfig, toks: 
util.List[NCToken]): util.List[NCEntity] = ???
+public interface NCElement extends NCParameterized {
+    String getId();
+    String getDescription();
+    Optional<String> getParentId();
+    Set<String> getGroups();
+    Set<NCValue> getValues();
+    Optional<NCValueLoader> getValuesLoader();
 }
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCElementBuilder.java
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCElementBuilder.java
new file mode 100644
index 0000000..2ef8793
--- /dev/null
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCElementBuilder.java
@@ -0,0 +1,56 @@
+/*
+ * 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
+ *
+ *      https://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.impl.enrichers.entity.user;
+
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+
+public class NCElementBuilder {
+    public NCElementBuilder(String id, String desc) {
+
+    }
+
+    public NCElementBuilder withParentId(String parentId) {
+        return this;
+    }
+
+    public NCElementBuilder withGroups(Set<String> groups) {
+        return this;
+    }
+
+    public NCElementBuilder withValues(Set<NCValue> values) {
+        return this;
+    }
+
+    public NCElementBuilder withValuesLoader(NCValueLoader loader) {
+        return this;
+    }
+
+    public NCElementBuilder withProperties(Map<String, String> props) {
+        return this;
+    }
+
+    public NCElementBuilder withSynonyms(List<String> syns) {
+        return this;
+    }
+
+
+    public NCElement make() {
+        return null;
+    }
+}
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCFileUserEntityParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCFileUserEntityParser.scala
similarity index 84%
rename from 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCFileUserEntityParser.scala
rename to 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCFileUserEntityParser.scala
index 2c44e25..938c9f7 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCFileUserEntityParser.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCFileUserEntityParser.scala
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nlpcraft.impl.enrichers.entity
+package org.apache.nlpcraft.impl.enrichers.entity.user
 
 import org.apache.nlpcraft.*
 
@@ -25,6 +25,11 @@ import java.util
 // Element ID / Map element properties (parent, group, etc)
 // Macros ID / Macros body.
 // Element ID / Synonyms list, based on words and macros.
-class NCFileUserEntityParser(file: File) extends NCEntityParser {
+class NCFileUserEntityParser(
+    file: File,
+    loaders: util.Map[String, NCValueLoader]
+) extends NCEntityParser {
+    def this (file: File) = this (file, null)
+
     override def parse(req: NCRequest, cfg: NCModelConfig, toks: 
util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpLocationEntityParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCUserEntityParser.scala
similarity index 84%
rename from 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpLocationEntityParser.scala
rename to 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCUserEntityParser.scala
index efd9471..fdc6643 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpLocationEntityParser.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCUserEntityParser.scala
@@ -14,12 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nlpcraft.impl.enrichers.entity.opennlp
+package org.apache.nlpcraft.impl.enrichers.entity.user
 
 import org.apache.nlpcraft.*
 
 import java.util
 
-class NCOpenNlpLocationEntityParser extends NCEntityParser {
+class NCUserEntityParser(
+    macros: util.Map[String, String],
+    elements: util.List[NCElement]
+) extends NCEntityParser {
     override def parse(req: NCRequest, cfg: NCModelConfig, toks: 
util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCValue.java
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCValue.java
new file mode 100644
index 0000000..4e27836
--- /dev/null
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCValue.java
@@ -0,0 +1,48 @@
+/*
+ * 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.impl.enrichers.entity.user;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Model element's value.
+ * <p>
+ * Each model element can generally be recognized either by one of its 
synonyms or values. Elements and their values
+ * are analogous to types and instances of that type in programming languages. 
Each value
+ * has a name and optional set of its own synonyms by which that value, and 
ultimately its element, can be
+ * recognized by. Note that value name itself acts as an implicit synonym even 
when no additional synonyms added
+ * for that value.
+ *
+ * @see NCElement#getValues()
+ */
+public interface NCValue extends Serializable {
+    /**
+     * Gets value name.
+     *
+     * @return Value name.
+     */
+    String getName();
+
+    /**
+     * Gets optional list of value's synonyms.
+     *
+     * @return Potentially empty list of value's synonyms.
+     */
+    List<String> getSynonyms();
+}
\ No newline at end of file
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCValueLoader.java
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCValueLoader.java
new file mode 100644
index 0000000..bf48408
--- /dev/null
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/user/NCValueLoader.java
@@ -0,0 +1,62 @@
+/*
+ * 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.impl.enrichers.entity.user;
+
+import java.util.Set;
+
+/**
+ * Dynamic value loader that can be used by model elements to dynamically load 
or create their values. Note that
+ * the primary use case for this interface is the dynamic value loading for 
the models defines in JSON/YAML
+ * presentation. However, it's not technically limited to that use case only, 
and this interface can be
+ * set programmatically when model elements are created programmatically too.
+ * <p>
+ * <b>JSON</b>
+ * <br>
+ * When using JSON/YAML model presentation element values can be defined 
statically. However, in some
+ * cases, it is required to load these values from external sources like 
database or REST services while
+ * keeping the rest of the model declaration static (i.e. in JSON/YAML). To 
accomplish this you can
+ * define <code>valueLoader</code> property and provide a fully qualified 
class name that implements
+ * this interface. During the model instantiation an instance of that class 
will be created once per
+ * each model and class of loader and method {@link #load(NCElement)} will be 
called to load
+ * element's values. Note that you can use both statically defined values 
(i.e. <code>values</code> property)
+ * and dynamically loaded values together and they will be merged:
+ * <pre class="brush: js, highlight: [11]">
+ *     "elements": [
+ *         {
+ *             "id": "my:id",
+ *             "description": "My description.",
+ *             "values": [
+ *                  {
+ *                      "name": "name1",
+ *                      "synonyms": ["syn1", "syn2"]
+ *                  }
+ *             ],
+ *             "valueLoader": "my.package.MyLoader"
+ *         }
+ *     ]
+ * </pre>
+ */
+public interface NCValueLoader {
+    /**
+     * Loads values for given model element.
+     * 
+     * @param owner Model element to which this value loader belongs to.
+     * @return Set of values, potentially empty but never {@code null}.
+     */
+    Set<NCValue> load(NCElement owner);
+}
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
index cc840a7..e5722c4 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
@@ -16,10 +16,20 @@
  */
 package org.apache.nlpcraft.impl.tokenizers
 
+import org.apache.nlpcraft.internal.external.NCExternalConfigManager
 import org.apache.nlpcraft.{NCRequest, NCToken, NCTokenParser}
 
+import java.io.File
 import java.util;
 
-class NCEnTokenParser extends NCTokenParser {
+class NCEnTokenParser(
+    extCfgMgr: NCExternalConfigManager,
+    tagger: File,
+    lemmatizer: File
+) extends NCTokenParser {
     override def parse(req: NCRequest): util.List[NCToken] = ???
+
+    def start(): Unit = {
+
+    }
 }
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/external/NCExternalConfigManager.java
similarity index 65%
copy from 
nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
copy to 
nlpcraft/src/main/scala/org/apache/nlpcraft/internal/external/NCExternalConfigManager.java
index cc840a7..2be8e28 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/external/NCExternalConfigManager.java
@@ -14,12 +14,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.nlpcraft.impl.tokenizers
+package org.apache.nlpcraft.internal.external;
 
-import org.apache.nlpcraft.{NCRequest, NCToken, NCTokenParser}
+import java.io.File;
 
-import java.util;
+public class NCExternalConfigManager {
+    private final String url;
+    private final boolean checkMd5;
+    private final File localDir;
 
-class NCEnTokenParser extends NCTokenParser {
-    override def parse(req: NCRequest): util.List[NCToken] = ???
+    public NCExternalConfigManager(String url, boolean checkMd5, File 
localDir) {
+        this.url = url;
+        this.checkMd5 = checkMd5;
+        this.localDir = localDir;
+    }
+
+    public void start() {
+
+    }
 }
diff --git 
a/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest.java 
b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest.java
index 92a18ac..3ab9392 100644
--- a/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest.java
+++ b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest.java
@@ -19,13 +19,13 @@ package org.apache.nlpcraft.alarm;
 
 import org.apache.nlpcraft.NCModelClient;
 import org.apache.nlpcraft.NCModelConfigAdapter;
-import org.apache.nlpcraft.NCResult;
-import org.apache.nlpcraft.impl.enrichers.entity.NCFileUserEntityParser;
-import org.apache.nlpcraft.impl.enrichers.entity.NCUserEntityParser;
+import org.apache.nlpcraft.impl.enrichers.entity.user.NCElement;
+import org.apache.nlpcraft.impl.enrichers.entity.user.NCElementBuilder;
+import org.apache.nlpcraft.impl.enrichers.entity.user.NCUserEntityParser;
 import org.apache.nlpcraft.impl.tokenizers.NCEnTokenParser;
+import org.apache.nlpcraft.internal.external.NCExternalConfigManager;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
-import org.apache.nlpcraft.NCModelConfig;
 import org.apache.nlpcraft.NCEntityParser;
 
 
@@ -34,6 +34,7 @@ import static java.util.Arrays.asList;
 import java.io.File;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -45,13 +46,66 @@ public class LightSwitchModelTest {
         Assertions.assertNotNull(client.askSync("Hi!", null, null).getBody());
     }
 
-    private static NCModelConfigAdapter mkConfigAdapter(NCEntityParser 
entityParser) {
+    private static NCModelConfigAdapter mkConfigManual() {
+        Map<String, String> macros = new HashMap<>() {{
+            put("<ACTION>", "{turn|switch|dial|let|set|get|put}");
+            put("<KILL>", "{shut|kill|stop|eliminate}");
+            put("<ENTIRE_OPT>", "{entire|full|whole|total|_}");
+            put("<FLOOR_OPT>", 
"{upstairs|downstairs|{1st|first|2nd|second|3rd|third|4th|fourth|5th|fifth|top|ground}
 floor|_}");
+            put("<TYPE>", "{room|closet|attic|loft|{store|storage} {room|_}}");
+            put("<LIGHT>", "{all|_} 
{it|them|light|illumination|lamp|lamplight}");
+        }};
+
+        List<NCElement> elements =
+            List.of(
+                new NCElementBuilder("ls:loc", "ls:loc").
+                    withSynonyms(
+                        asList(
+                            "<ENTIRE_OPT> <FLOOR_OPT> 
{kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} <TYPE>}",
+                            "<ENTIRE_OPT> <FLOOR_OPT> 
{master|kid|children|child|guest|_} {bedroom|bathroom|washroom|storage} 
{<TYPE>|_}",
+                            "<ENTIRE_OPT> {house|home|building|{1st|first} 
floor|{2nd|second} floor}"
+                        )
+                    ).make(),
+                new NCElementBuilder("ls:on", "ls:on").
+                    withGroups(new HashSet<>() {{
+                        add("act");
+                    }}).
+                    withSynonyms(
+                        asList(
+                            "<ACTION> {on|up|_} <LIGHT> {on|up|_}",
+                            "<LIGHT> {on|up}"
+                        )
+                    ).make(),
+                new NCElementBuilder("ls:off", "ls:off").
+                    withGroups(new HashSet<>() {{
+                        add("act");
+                    }}).
+                    withSynonyms(
+                        asList(
+                            "<ACTION> <LIGHT> {off|out|down}",
+                            "{<ACTION>|<KILL>} {off|out|down} <LIGHT>",
+                            "<KILL> <LIGHT>",
+                            "<LIGHT> <KILL>",
+                            "{out|no|off|down} <LIGHT>",
+                            "<LIGHT> {out|off|down}"
+                        )
+                    ).make()
+            );
+
+        NCExternalConfigManager extCfg = new 
NCExternalConfigManager("nlpcraft.org", true, new File("~"));
+
+        extCfg.start();
+
+        NCEnTokenParser tokParser = new NCEnTokenParser(extCfg, new 
File("open_tagger.dic"), new File("open_lemmatizer.dic"));
+
+        tokParser.start();
+
         NCModelConfigAdapter cfg =
             new NCModelConfigAdapter(
                 "nlpcraft.lightswitch.ex",
                 "Light Switch Example Model",
                 "1.0",
-                new NCEnTokenParser()
+                tokParser
             );
 
         // Order is important.
@@ -63,75 +117,10 @@ public class LightSwitchModelTest {
 //            )
 //        )
 
-        cfg.setEntityParsers(asList(entityParser));
+        cfg.setEntityParsers(asList(new NCUserEntityParser(macros, elements)));
 
 //        // Don't need any entity enrichers.
 //        cfg.setEntityEnrichers(null)
         return cfg;
     }
-
-
-    private static NCModelConfigAdapter mkConfigManual() {
-        Map<String, Map<String, String>> elements = new HashMap<>() {{
-            put(
-                "ls:loc",
-                Collections.emptyMap()
-            );
-
-            put("ls:on",
-                new HashMap<>() {{
-                    put("group", "act");
-                }}
-            );
-
-            put("ls:off",
-                new HashMap<>() {{
-                    put("group", "act");
-                }}
-            );
-        }};
-
-        Map<String, String> macros = new HashMap<>() {{
-            put("<ACTION>", "{turn|switch|dial|let|set|get|put}");
-            put("<KILL>", "{shut|kill|stop|eliminate}");
-            put("<ENTIRE_OPT>", "{entire|full|whole|total|_}");
-            put("<FLOOR_OPT>", 
"{upstairs|downstairs|{1st|first|2nd|second|3rd|third|4th|fourth|5th|fifth|top|ground}
 floor|_}");
-            put("<TYPE>", "{room|closet|attic|loft|{store|storage} {room|_}}");
-            put("<LIGHT>", "{all|_} 
{it|them|light|illumination|lamp|lamplight}");
-        }};
-
-        Map<String, List<String>> synonyms = new HashMap<>() {{
-            put(
-                "ls:loc",
-                asList(
-                    "<ENTIRE_OPT> <FLOOR_OPT> 
{kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} <TYPE>}",
-                    "<ENTIRE_OPT> <FLOOR_OPT> 
{master|kid|children|child|guest|_} {bedroom|bathroom|washroom|storage} 
{<TYPE>|_}",
-                    "<ENTIRE_OPT> {house|home|building|{1st|first} 
floor|{2nd|second} floor}"
-                )
-            );
-
-            put(
-                "ls:on",
-                asList(
-                    "<ACTION> {on|up|_} <LIGHT> {on|up|_}",
-                    "<LIGHT> {on|up}"
-                )
-            );
-
-            put(
-                "ls:off",
-                asList(
-                    "<ACTION> <LIGHT> {off|out|down}",
-                    "{<ACTION>|<KILL>} {off|out|down} <LIGHT>",
-                    "<KILL> <LIGHT>",
-                    "<LIGHT> <KILL>",
-                    "{out|no|off|down} <LIGHT>",
-                    "<LIGHT> {out|off|down}"
-                )
-            );
-
-        }};
-
-        return mkConfigAdapter(new NCUserEntityParser(elements, macros, 
synonyms));
-    }
 }
diff --git 
a/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest2.java 
b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest2.java
deleted file mode 100644
index 47e3ba2..0000000
--- 
a/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest2.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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
- *
- *      https://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.alarm;
-
-import org.apache.nlpcraft.NCEntityParser;
-import org.apache.nlpcraft.NCModelClient;
-import org.apache.nlpcraft.NCModelConfig;
-import org.apache.nlpcraft.NCModelConfigAdapter;
-import org.apache.nlpcraft.impl.enrichers.entity.NCFileUserEntityParser;
-import org.apache.nlpcraft.impl.enrichers.entity.NCUserEntityParser;
-import org.apache.nlpcraft.impl.tokenizers.NCEnTokenParser;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static java.util.Arrays.asList;
-
-public class LightSwitchModelTest2 {
-    @Test
-    public void test() {
-        NCModelClient client = new NCModelClient(new 
LightSwitchModel(mkConfigFile(new File("lightswitch.json"))));
-
-        Assertions.assertNotNull(client.askSync("Hi!", null, null).getBody());
-    }
-
-    private static NCModelConfigAdapter mkConfigAdapter(NCEntityParser 
entityParser) {
-        NCModelConfigAdapter cfg =
-            new NCModelConfigAdapter(
-                "nlpcraft.lightswitch.ex",
-                "Light Switch Example Model",
-                "1.0",
-                new NCEnTokenParser()
-            );
-
-        // Order is important.
-//        cfg.setTokenEnrichers(
-//            asList(
-//                new NCEnDictionaryTokenEnricher(),
-//                new NCEnQuotesTokenEnricher(),
-//                new NCEnSwearWordsTokenEnricher()
-//            )
-//        )
-
-        cfg.setEntityParsers(asList(entityParser));
-
-//        // Don't need any entity enrichers.
-//        cfg.setEntityEnrichers(null)
-        return cfg;
-    }
-
-
-    private static NCModelConfig mkConfigFile(File f) {
-        return mkConfigAdapter(new NCFileUserEntityParser(f));
-    }
-}
diff --git a/nlpcraft/src/test/resources/lightswitch_model.json 
b/nlpcraft/src/test/resources/lightswitch_model.json
index f2b7b57..9b48456 100644
--- a/nlpcraft/src/test/resources/lightswitch_model.json
+++ b/nlpcraft/src/test/resources/lightswitch_model.json
@@ -1,22 +1,19 @@
 {
   "elements": [
     {
-      "ls:loc": [
-      ]
+      "id": "ls:loc",
+      "description": "ls:loc",
+      "groups": []
     },
     {
-      "ls:on": [
-        {
-          "group": "act"
-        }
-      ]
+      "id": "ls:on",
+      "description": "ls:on",
+      "groups": ["act"]
     },
     {
-      "ls:off": [
-        {
-          "group": "act"
-        }
-      ]
+      "id": "ls:off",
+      "description": "ls:off",
+      "groups": ["act"]
     }
   ],
   "macros": [
diff --git a/nlpcraft/src/test/resources/lightswitch_model.yaml 
b/nlpcraft/src/test/resources/lightswitch_model.yaml
index 802197c..f0ca303 100644
--- a/nlpcraft/src/test/resources/lightswitch_model.yaml
+++ b/nlpcraft/src/test/resources/lightswitch_model.yaml
@@ -1,9 +1,15 @@
 elements:
-  - "ls:loc": []
-  - "ls:on":
-      - "group": "act"
-  - "ls:off":
-      - "group": "act"
+  - id: ls:loc
+    description: ls:loc
+    groups: []
+  - id: ls:on
+    description: ls:on
+    groups:
+      - act
+  - id: ls:off
+    description: ls:off
+    groups:
+      - act
 macros:
   - "<ACTION>": "{turn|switch|dial|let|set|get|put}"
   - "<KILL>": "{shut|kill|stop|eliminate}"
diff --git a/pom.xml b/pom.xml
index 6210045..d69acf6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -98,11 +98,14 @@
         <maven.clean.plugin.ver>3.1.0</maven.clean.plugin.ver>
         <org.antlr4.ver>4.9</org.antlr4.ver>
         <jline.ver>3.20.0</jline.ver>
+        <commons.io.ver>2.11.0</commons.io.ver>
         <commons.lang3.ver>3.12.0</commons.lang3.ver>
+        <commons.codec.ver>1.15</commons.codec.ver>
         <scala3.ref.ver>1.0.0</scala3.ref.ver>
         <junit.ver>5.8.1</junit.ver>
         <scalatest.ver>3.2.9</scalatest.ver>
         <gson.ver>2.8.5</gson.ver>
+        <apache.opennlp.ver>1.9.4</apache.opennlp.ver>
 
         <!-- Force specific encoding on text resources. -->
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -155,6 +158,18 @@
             -->
 
             <dependency>
+                <groupId>commons-io</groupId>
+                <artifactId>commons-io</artifactId>
+                <version>${commons.io.ver}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>commons-codec</groupId>
+                <artifactId>commons-codec</artifactId>
+                <version>${commons.codec.ver}</version>
+            </dependency>
+
+            <dependency>
                 <groupId>com.google.code.gson</groupId>
                 <artifactId>gson</artifactId>
                 <version>${gson.ver}</version>
@@ -166,6 +181,12 @@
                 <version>${org.antlr4.ver}</version>
             </dependency>
 
+            <dependency>
+                <groupId>org.apache.opennlp</groupId>
+                <artifactId>opennlp-tools</artifactId>
+                <version>${apache.opennlp.ver}</version>
+            </dependency>
+
             <!--
              JLine dependencies.
              ==================

Reply via email to