This is an automated email from the ASF dual-hosted git repository. sergeykamov pushed a commit to branch NLPCRAFT-359 in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
commit 29be252427bcb70b2b7d5ca6d3b3112dcc87fcaf Author: Sergey Kamov <[email protected]> AuthorDate: Wed Jul 7 12:34:25 2021 +0300 WIP. --- .../org/apache/nlpcraft/common/util/NCUtils.scala | 62 +++++++++++++++------- .../apache/nlpcraft/model/NCIntentSampleRef.java | 41 ++++++++++++++ .../probe/mgrs/deploy/NCDeployManager.scala | 50 +++++++++++------ 3 files changed, 120 insertions(+), 33 deletions(-) diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala index ef20c34..becbb36 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala @@ -2233,29 +2233,55 @@ object NCUtils extends LazyLogging { } } + def isFile(path: String): Boolean = { + val f = new File(path) + + f.exists() && f.isFile + } + /** * - * @param s + * @return */ - def isSuitableConfig(s: String): Boolean = { - def isFile: Boolean = { - val f = new File(s) - - f.exists() && f.isFile - } + def isResource(res: String): Boolean = getClass.getClassLoader.getResource(res) != null - def isResource: Boolean = getClass.getClassLoader.getResource(s) != null + /** + * + * @param url + * @return + */ + def isUrl(url: String): Boolean = + try { + new URL(url) - def isUrl: Boolean = - try { - new URL(s) + true + } + catch { + case _: MalformedURLException => false + } - true - } - catch { - case _: MalformedURLException => false - } + /** + * + * @param s + */ + def isSuitableConfig(s: String): Boolean = isFile(s) || isResource(s) || isUrl(s) - isFile || isResource || isUrl - } + /** + * + * @param src + * @throws + * @return + */ + @throws[NCE] + def readAnySource(src: String): List[String] = + if (isFile(src)) + readFile(new File(src)) + else if (isResource(src)) + readResource(src) + else if (isUrl(src)) + Using.resource(new URL(src).openStream()) { is => readStream(is) } + else { + // TODO: + throw new NCE(s"Source is not found: $src") + } } \ No newline at end of file diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentSampleRef.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentSampleRef.java new file mode 100644 index 0000000..19d236b --- /dev/null +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentSampleRef.java @@ -0,0 +1,41 @@ +/* + * 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.model; + +import java.lang.annotation.Documented; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +// TODO: +@Retention(value=RUNTIME) +@Target(value=METHOD) +@Repeatable(NCIntentSampleRef.NCIntentSampleList.class) +public @interface NCIntentSampleRef { + String value(); + @Retention(RetentionPolicy.RUNTIME) + @Target(value=METHOD) + @Documented + @interface NCIntentSampleList { + NCIntentSampleRef[] value(); + } +} diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala index 9e5ec78..b081798 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala @@ -57,6 +57,7 @@ object NCDeployManager extends NCService { private final val CLS_QRY_RES = classOf[NCResult] private final val CLS_SLV_CTX = classOf[NCIntentMatch] private final val CLS_SAMPLE = classOf[NCIntentSample] + private final val CLS_SAMPLE_REF = classOf[NCIntentSampleRef] // Java and scala lists. private final val CLS_SCALA_SEQ = classOf[Seq[_]] @@ -1611,32 +1612,50 @@ object NCDeployManager extends NCService { val mtdStr = method2Str(m) val smpAnns = m.getAnnotationsByType(CLS_SAMPLE) + val smpAnnsRef = m.getAnnotationsByType(CLS_SAMPLE_REF) val intAnns = m.getAnnotationsByType(CLS_INTENT) val refAnns = m.getAnnotationsByType(CLS_INTENT_REF) - if (smpAnns.nonEmpty) { - if (intAnns.isEmpty && refAnns.isEmpty) - throw new NCE(s"@NCIntentSample annotation without corresponding @NCIntent or @NCIntentRef annotations: $mtdStr") + if (smpAnns.nonEmpty || smpAnnsRef.nonEmpty) { + if (intAnns.isEmpty && refAnns.isEmpty) { + // TODO: + throw new NCE(s"@NCIntentSample or @NCIntentSampleRef annotations without corresponding @NCIntent or @NCIntentRef annotations: $mtdStr") + } else { - val seqSeq = smpAnns.toSeq.map(_.value().toSeq) + def read[T](arr: Array[T], claxx: Class[_], getValue: T => Seq[String]): Seq[Seq[String]] = { + val seq = arr.toSeq.map(getValue) + + if (seq.exists(_.isEmpty)) + logger.warn(s"@${claxx.getName} annotation is empty: $mtdStr") - if (seqSeq.exists(_.isEmpty)) - logger.warn(s"@NCIntentSample annotation is empty: $mtdStr") + seq + } + + val seqSeq = + read[NCIntentSample]( + smpAnns, classOf[NCIntentSample], _.value().toSeq + ) ++ + read[NCIntentSampleRef]( + smpAnnsRef, classOf[NCIntentSampleRef], a => U.readAnySource(a.value()) + ) + + // TODO: text if (U.containsDups(seqSeq.flatten.toList)) - logger.warn(s"@NCIntentSample annotation has duplicates: $mtdStr") + logger.warn(s"@NCIntentSample and @NCIntentSampleRef annotations have duplicates: $mtdStr") val distinct = seqSeq.map(_.distinct).distinct - for (ann <- intAnns) { - for (intent <- NCIdlCompiler.compileIntents(ann.value(), mdl, mtdStr)) - samples += (intent.id -> distinct) - } + for (ann <- intAnns; intent <- NCIdlCompiler.compileIntents(ann.value(), mdl, mtdStr)) + samples += (intent.id -> distinct) + for (ann <- refAnns) samples += (ann.value() -> distinct) } } - else if (intAnns.nonEmpty || refAnns.nonEmpty) - logger.warn(s"@NCIntentSample annotation is missing for: $mtdStr") + else if (intAnns.nonEmpty || refAnns.nonEmpty) { + // TODO: text + logger.warn(s"@NCIntentSample or @NCIntentSampleRef annotations are missing for: $mtdStr") + } } if (samples.nonEmpty) { @@ -1656,7 +1675,7 @@ object NCDeployManager extends NCService { val processed = mutable.HashSet.empty[Case] samples. - flatMap { case (_, smp) =>smp.flatten.map(_.toLowerCase) }. + flatMap { case (_, smp) => smp.flatten.map(_.toLowerCase) }. map(s => s -> SEPARATORS.foldLeft(s)((s, ch) => s.replaceAll(s"\\$ch", s" $ch "))). foreach { case (s, sNorm) => @@ -1666,7 +1685,8 @@ object NCDeployManager extends NCService { if (!allSyns.exists(_.intersect(seq).nonEmpty)) { // Not a warning since the parent class can contain direct synonyms (NLPCRAFT-348). // See NLPCRAFT-349 for the additional issue. - logger.debug(s"@NCIntentSample sample doesn't contain any direct synonyms (check if its parent class contains any) [" + + // TODO: text + logger.debug(s"@NCIntentSample or @NCIntentSampleRef sample doesn't contain any direct synonyms (check if its parent class contains any) [" + s"mdlId=$mdlId, " + s"origin=${mdl.getOrigin}, " + s"""sample="$s"""" +
