Пример использования библиотеки com4j | Паршин Павел

Com4j - библиотека, предназначенная для интеграции java-приложений и dll-библиотек, использующих COM-технологию (Component Object Model).

Com4j автоматически импортирует библиотеку типов и генерирует необходимые java-классы.

В качестве примера рассмотрим подключение библиотеки TextAnalyst SDK для анализа содержания текста, смыслового поиска информации и множества других возможностей. Условно-бесплатную версию SDK можно скачать на сайте компании. В каталоге с программой есть 4 необходимые библиотеки: Base.dll, KB.dll, tp.dll и vocobj.dll. Также советую скачать документацию к SDK, в которой есть описание всех COM-интерфейсов и примеры использования на C++ и Visual Basic.

Шаг 1: создание проекта в IDE

В качестве среды разработки я использую IntelliJ IDEA 12.1.6. Открываем программу и создаем новый проект под названием com4j_example. Файлы проекта я буду хранить в каталоге C:\projects\other\com4j_example.

Библиотеку com4j разместим в каталоге C:\projects\other. Вышеперечисленные dll-файлы SDK скопируем в каталог C:\projects\other\com4j_example\com_lib.

Также я создал папку lib для хранения jar-файлов проекта (C:\projects\other\com4j_example\lib) - в эту папку копируем файл com4j.jar и подключаем к проекту, и папку dic - в нее скопируем русский и английский словари SDK (файлы с расширениями .dic, .dat, .xpt, .voc, .suf).

Последний подготовительный этап: регистрация COM-компонентов в системе, для этого используем программу regsvr32.exe (нажимаем Win+R, в открывшемся окне вводим: regsvr32.exe "путь к нужному dll-файлу"). Например, в моем случае это будет так: regsvr32.exe C:\projects\other\com4j_example\com_lib\Base.dll. Нажимаем Enter и после этого должно появиться сообщение об успешной регистрации. Этот шаг проделываем для всех четырех файлов.

Шаг 2: создаем java-классы для работы с COM-объектами

Для этого будем использовать tlbimp.jar, поставляемый вместе с com4j. Запускаем командную строку с правами администратора, переходим в каталог com4j и используем следующую команду:

java -jar tlbimp.jar -o "..." -p "..." полный_путь_к_DLL_файлу

где -o - каталог, в который будем сохранять сгенерированные java-классы, -p - имя пакета.

Выполняем для всех 4 компонентов:

Создаем Java классы

Шаг 3: создание консольного java-приложения

Добавим в пакет один класс Com4j_integrate и один интерфейс Config с основными настройками.

В интерфейсе определим путь к словарям и еще некоторые константы:

package pro.parshinpn;

public interface Config {
    // Полный путь к каталогу с словарями
    String vocPath = "C:\\projects\\other\\com4j_example\\dic";
    // Имя русского словаря
    String vocPatternRus = "normal_rus.dic";
    // ID документа (множество документов на данном этапе не рассматриваем)
    int idDoc = 1;
    // Условием окончания перебора узлов является равенство номера ссылки значению END_OF_ENUM
    int END_OF_ENUM = -1;
}

Класс Com4j_integrate:

package pro.parshinpn;

import com4j.Com4jObject;
import com4j.Holder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import pro.parshinpn.base.IBase;
import pro.parshinpn.kb.IKnowledgeBase;
import pro.parshinpn.tp.ITextProcessor;
import pro.parshinpn.vocobj.IDictionary;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

public class Com4j_integrate {
    private static IDictionary vocObj;
    private static ITextProcessor tpObj;
    private static IKnowledgeBase kbObj;
    private static IBase baseObj;

    // Текст, который введет пользователь
    private static String inputText;

    /**
     * Отвечает за создание и инициализацию объектов для работы с COM-библиотекой.
     */
    private static void initLibrary() {
        // Создаем объекты COM-компонентов.
        vocObj = pro.parshinpn.vocobj.ClassFactory.createDictionary();
        tpObj = pro.parshinpn.tp.ClassFactory.createTextProcessor();
        kbObj = pro.parshinpn.kb.ClassFactory.createTAKB();

        // Полный путь к словарю (рассматриваем только русский язык)
        String fullVocPath = Config.vocPath + Config.vocPatternRus;
        File voc = new File(fullVocPath);
        if (voc.exists()) {
            // Загружаем словари
            vocObj.vocPath(Config.vocPath);
            vocObj.pattern(fullVocPath);
        } else {
            // Если файл со словарем не найден, то завершаем выполнение программы
            assert false;
        }

        baseObj = processingText(1, 0, 0, 0, 1, 1, 0, 0, 0);
        kbObj.dictionary(vocObj);
        kbObj.addBase(Config.idDoc, baseObj);
    }

    /**
     * Обрабатывает текст в соответствии с указанными параметрами.
     * Результатом обработки является создание объекта класса TA.Base.
        * Параметры метода можно посмотреть в документации.
     * @return Указатель на объект класса IBase
     */
    private static IBase processingText(int metaData,
                                 int onlyUserWrds,
                                 int singleWrds,
                                 int latins,
                                 int buildRef,
                                 int buildSummary,
                                 int phraseThresh,
                                 int linkThresh,
                                 int fullText)
    {
        tpObj.dictionary(vocObj);
        Com4jObject tpObject = tpObj.processText(inputText, metaData, onlyUserWrds, singleWrds, latins, buildRef, buildSummary, phraseThresh, linkThresh, fullText);
        return tpObject.queryInterface(IBase.class);
    }

    /**
     * Построение семантической сети в формате XML.
     * @return XML-представление семантической сети
     */
    private static Document getNetworkInXmlFormat() {
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        Document doc = null;
        try {
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            doc = docBuilder.newDocument();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }

        if (doc == null) return null;

        /**
         * Создаем root-элемент
         */
        Element rootElement = doc.createElement("TextAnalystNetwork");
        doc.appendChild(rootElement);

        int nodeEnumHandle = baseObj.getNodeEnumHandle();

        // Узлы текста.
        // Используем специальный класс Holder для получения значений по ссылке из библиотеки.
        Holder<Integer> id   = new Holder<>(),
                cnt  = new Holder<>(),
                wght = new Holder<>(),
                attr = new Holder<>();
        Holder<String>  str  = new Holder<>();

        // Связи между узлами
        Holder<Integer> linkID   = new Holder<>(),
                wght12   = new Holder<>(),
                wght21   = new Holder<>(),
                linkCnt  = new Holder<>(),
                linkAttr = new Holder<>();

        for (baseObj.getNextNodeEx(nodeEnumHandle, id, cnt, wght, attr, str);
             id.value != Config.END_OF_ENUM;
             baseObj.getNextNodeEx(nodeEnumHandle, id, cnt, wght, attr, str)) {

            Element nodeElement = doc.createElement("Node");

            nodeElement.setAttribute("weight", String.valueOf(wght.value));
            nodeElement.setAttribute("name", str.value);
            nodeElement.setAttribute("counter", String.valueOf(cnt.value));
            nodeElement.setAttribute("attr", String.valueOf(attr.value));

            rootElement.appendChild(nodeElement);

            /**
             * Нумерация и получение связей между узлами
             */
            int linkEnumHandle = baseObj.getNodeLinkEnumHandle(id.value);

            for (baseObj.getNextNodeLinkEx(linkEnumHandle, linkID, linkCnt, wght12, wght21, linkAttr);
                 linkID.value != Config.END_OF_ENUM;
                 baseObj.getNextNodeLinkEx(linkEnumHandle, linkID, linkCnt, wght12, wght21, linkAttr)) {

                String linkStr = baseObj.getNodeStr(linkID.value);

                Element linkElement = doc.createElement("Link");

                linkElement.setAttribute("weight", String.valueOf(wght12.value));
                linkElement.setAttribute("name", linkStr);
                linkElement.setAttribute("counter", String.valueOf(linkCnt.value));
                linkElement.setAttribute("attr", String.valueOf(linkAttr.value));

                rootElement.getLastChild().appendChild(linkElement);
            }

            baseObj.freeNodeLinkEnumHandle(linkEnumHandle);
        }

        baseObj.freeNodeEnumHandle(nodeEnumHandle);

        return doc;
    }

    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        try {
            System.out.println("Введите текст: ");
            inputText = reader.readLine();

            initLibrary();
            Document doc = getNetworkInXmlFormat();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Предыдущая запись Следующая запись