/*
 * SDK Pullenti Lingvo, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software.
 * This class is generated using the converter Unisharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

package demo;

public class Program {

    public static void main(String[] args) throws Exception, java.io.IOException {
        String vers = com.pullenti.ner.ServerService.getServerVersion(null);
        if (vers != null) {
            System.out.print("Server version = " + vers);
            if (com.pullenti.unisharp.Utils.stringsEq(vers, com.pullenti.ner.ProcessorService.getVersion())) 
                System.out.println(" (equal with current SDK)");
            else 
                System.out.println(" (but version of current SDK " + com.pullenti.ner.ProcessorService.getVersion() + ")!");
            com.pullenti.ner.AnalysisResult sres = com.pullenti.ner.ServerService.processOnServer(null, null, "В США прядь волос третьего президента Соединенных Штатов Томаса\nДжефферсона продали на аукционе в Техасе за 6,9 тысячи долларов,\nпередает Life. Локоны бывшего лидера США ушли с молотка почти\nчерез 190 лет после его смерти. Их покупатель пожелал остаться\nнеизвестным. Перед началом аукциона волосы Джефферсона оценивали\nв 3 тысячи долларов. В январе 2015 года прядь волос 16-го президента\nСША Авраама Линкольна продали за 25 тысяч долларов на аукционе в Далласе.", null);
            System.out.println("Server result: " + sres.toString());
        }
        com.pullenti.unisharp.Stopwatch sw = com.pullenti.unisharp.Utils.startNewStopwatch();
        // инициализация - необходимо проводить один раз до обработки текстов
        System.out.print("Initializing SDK Pullenti ver " + com.pullenti.Sdk.getVersion() + " (" + com.pullenti.Sdk.getVersionDate() + ") ... ");
        // инициализируются движок и все имеющиеся анализаторы
        com.pullenti.Sdk.initializeAll();
        sw.stop();
        System.out.println("OK (by " + ((int)sw.getElapsedMilliseconds()) + " ms), version " + com.pullenti.ner.ProcessorService.getVersion());
        // посмотрим, какие анализаторы доступны
        for (com.pullenti.ner.Analyzer a : com.pullenti.ner.ProcessorService.getAnalyzers()) {
            System.out.println("   " + (a.isSpecific() ? "Specific analyzer" : "Common analyzer") + " " + a.getName() + " \"" + a.getCaption() + "\"");
        }
        // анализируемый текст
        String txt = "Система разрабатывается с 2011 года российским программистом Михаилом Жуковым, проживающим в Москве на Красной площади в доме номер один на втором этаже. Конкурентов у него много: Abbyy, Yandex, ООО \"Russian Context Optimizer\" (RCO) и другие компании. Он планирует продать SDK за 1.120.000.001,99 (миллиард сто двадцать миллионов один рубль 99 копеек) рублей, без НДС.";
        System.out.println("Text: " + txt);
        // запускаем обработку на пустом процессоре (без анализаторов NER)
        com.pullenti.ner.AnalysisResult are = com.pullenti.ner.ProcessorService.getEmptyProcessor().process(new com.pullenti.ner.SourceOfAnalysis(txt), null, null);
        System.out.print("Noun groups: ");
        // перебираем токены
        for (com.pullenti.ner.Token t = are.firstToken; t != null; t = t.getNext()) {
            // выделяем именную группу с текущего токена
            com.pullenti.ner.core.NounPhraseToken npt = com.pullenti.ner.core.NounPhraseHelper.tryParse(t, com.pullenti.ner.core.NounPhraseParseAttr.NO, 0, null);
            // не получилось
            if (npt == null) 
                continue;
            // получилось, выводим в нормализованном виде
            System.out.print("[" + npt.getSourceText() + "=>" + npt.getNormalCaseText(null, com.pullenti.morph.MorphNumber.SINGULAR, com.pullenti.morph.MorphGender.UNDEFINED, false) + "] ");
            // указатель на последний токен именной группы
            t = npt.getEndToken();
        }
        try (com.pullenti.ner.Processor proc = com.pullenti.ner.ProcessorService.createProcessor()) {
            // анализируем текст
            com.pullenti.ner.AnalysisResult ar = proc.process(new com.pullenti.ner.SourceOfAnalysis(txt), null, null);
            // результирующие сущности
            System.out.println("\r\n==========================================\r\nEntities: ");
            for (com.pullenti.ner.Referent e : ar.getEntities()) {
                System.out.println(e.getTypeName() + ": " + e.toString());
                for (com.pullenti.ner.Slot s : e.getSlots()) {
                    System.out.println("   " + s.getTypeName() + ": " + s.getValue());
                }
            }
            // пример выделения именных групп
            System.out.println("\r\n==========================================\r\nNoun groups: ");
            for (com.pullenti.ner.Token t = ar.firstToken; t != null; t = t.getNext()) {
                // токены с сущностями игнорируем
                if (t.getReferent() != null) 
                    continue;
                // пробуем создать именную группу
                com.pullenti.ner.core.NounPhraseToken npt = com.pullenti.ner.core.NounPhraseHelper.tryParse(t, com.pullenti.ner.core.NounPhraseParseAttr.ADJECTIVECANBELAST, 0, null);
                // не получилось
                if (npt == null) 
                    continue;
                System.out.println(npt);
                // указатель перемещаем на последний токен группы
                t = npt.getEndToken();
            }
            // попробуем проанализировать через сервер (если он запущен, естественно)
            String serverAddress = "http://localhost:1111";
            String serverSdkVersion = com.pullenti.ner.ServerService.getServerVersion(serverAddress);
            if (serverSdkVersion == null) 
                System.out.println("Server not exists on " + serverAddress + ", OK");
            else {
                System.out.println("Server SDK Version: " + serverSdkVersion);
                // желательно проверить тождественность версий, а то мало ли...
                if (com.pullenti.unisharp.Utils.stringsNe(serverSdkVersion, com.pullenti.ner.ProcessorService.getVersion())) 
                    System.out.println("Server version " + serverSdkVersion + " not equals current SDK version " + com.pullenti.ner.ProcessorService.getVersion());
                else 
                    try {
                        // по идее, должны получить абсолютно эквивалентный результат, что и в ar
                        com.pullenti.ner.AnalysisResult ar2 = com.pullenti.ner.ServerService.processOnServer(serverAddress, proc, txt, null);
                        if (ar2 == null) 
                            System.out.println("Server execution ERROR! ");
                        else if (ar2.getEntities().size() != ar.getEntities().size()) 
                            System.out.println("Entities on server = " + ar2.getEntities().size() + ", but on local = " + ar.getEntities().size());
                        else {
                            boolean eq = true;
                            for (int i = 0; i < ar2.getEntities().size(); i++) {
                                if (!ar2.getEntities().get(i).canBeEquals(ar.getEntities().get(i), com.pullenti.ner.core.ReferentsEqualType.WITHINONETEXT)) {
                                    System.out.println("Server entity '" + ar2.getEntities().get(i) + "' not equal local entity '" + ar.getEntities().get(i) + "'");
                                    eq = false;
                                }
                            }
                            if (eq) 
                                System.out.println("Process on server equals local process!");
                        }
                    } catch (Exception ex) {
                        System.out.println("Process on server error: " + ex.getMessage());
                    }
            }
        }
        try (com.pullenti.ner.Processor proc = com.pullenti.ner.ProcessorService.createSpecificProcessor(com.pullenti.ner.keyword.KeywordAnalyzer.ANALYZER_NAME)) {
            com.pullenti.ner.AnalysisResult ar = proc.process(new com.pullenti.ner.SourceOfAnalysis(txt), null, null);
            System.out.println("\r\n==========================================\r\nKeywords1: ");
            for (com.pullenti.ner.Referent e : ar.getEntities()) {
                if (e instanceof com.pullenti.ner.keyword.KeywordReferent) 
                    System.out.println(e);
            }
            System.out.println("\r\n==========================================\r\nKeywords2: ");
            for (com.pullenti.ner.Token t = ar.firstToken; t != null; t = t.getNext()) {
                if (t instanceof com.pullenti.ner.ReferentToken) {
                    com.pullenti.ner.keyword.KeywordReferent kw = (com.pullenti.ner.keyword.KeywordReferent)com.pullenti.unisharp.Utils.cast(t.getReferent(), com.pullenti.ner.keyword.KeywordReferent.class);
                    if (kw == null) 
                        continue;
                    String kwstr = com.pullenti.ner.core.MiscHelper.getTextValueOfMetaToken((com.pullenti.ner.ReferentToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.ReferentToken.class), com.pullenti.ner.core.GetTextAttr.of((com.pullenti.ner.core.GetTextAttr.FIRSTNOUNGROUPTONOMINATIVESINGLE.value()) | (com.pullenti.ner.core.GetTextAttr.KEEPREGISTER.value())));
                    System.out.println(kwstr + " = " + kw);
                }
            }
        }
        System.out.println("Over!");
    }
    public Program() {
    }
}
