Статьи

Как внедрить зависимости OSGi в пользовательские портлеты в Liferay 7

Эта статья была создана в сотрудничестве с Ktree . Спасибо за поддержку партнеров, которые делают возможным использование SitePoint.

Liferay 7 / DXP использует среду OSGi для предоставления среды разработки для модульных приложений. Недавно мы использовали эту функцию для добавления функциональности стандартного модуля Liferay в наш пользовательский портлет.

Мы достигли этого, внедрив вики-ресурсы как зависимость в наш пользовательский портлет. Для целей этой статьи мы будем использовать один пример пользовательского модуля, который отображает одну текстовую область поля, а ниже мы будем вводить ресурсы вики на экран.

Давайте пройдемся по нескольким понятиям, прежде чем мы начнем реальную программу.

Кратко о OSGI

OSGi (Open Services Gateway Initiative) позволяет разделить ваше приложение на несколько модулей и, таким образом, легче управлять взаимозависимостями между ними. Liferay использует реализацию контейнера Equinox для OSGi.

Основные преимущества OSGi:

  • Вы можете динамически устанавливать, удалять, запускать и останавливать различные модули вашего приложения без перезапуска контейнера.
  • В вашем приложении может быть одновременно запущено несколько версий определенного модуля.
  • OSGi предоставляет очень хорошую инфраструктуру для разработки сервис-ориентированных приложений, а также встраиваемых, мобильных и многофункциональных интернет-приложений.

Для получения дополнительной информации о OSGi, проверьте эти статьи:

Liferay 7 / DXP в настоящее время поддерживает эти типы зависимостей. Это то, что вам нужно указать в файле build.gradle

Compile

Зависимости, необходимые для составления производственного источника проекта. Как вы можете увидеть в следующей части этой статьи, для этой зависимости вам нужно настроить ее как в build.gradlebnd.bnd

CompileOnly

Зависимости, необходимые во время компиляции, но никогда не требующиеся во время выполнения. Поскольку ресурсы вики уже находятся в контейнере OSGi, мы будем использовать эту опцию. Добавление этого в build.gradle

RunTime

Зависимости, требуемые производственными классами во время выполнения. По умолчанию также включает зависимости времени компиляции.

При условии

Зависимость в предоставленной области, которая необходима для компиляции проекта, но не должна распространяться вместе с ней.

Наряду с типом зависимости нам нужно указать еще несколько параметров, которые описаны ниже.

  • группа — обычно это название вашей организации или проекта.
  • name — название проекта.
  • версия — номер версии.
  • fileTree — для предоставления зависимостей от локальной файловой системы.

С этими понятиями мы готовы написать некоторый код, поэтому давайте запустим вашу Eclipse Liferay IDE.

Шаг 1: Создать проект Liferay Workspace

Создайте свой проект Liferay Workspace, перейдя по этой ссылке .

Шаг 2: Создание модуля Liferay

Это создает файл build.gradle Отредактируйте build.gradle Смотрите пример кода.

Чтобы создать модуль Liferay в IDE, выберите « Файл»> «Создать»> «Проект модуля Liferay» .

Пример: файл build.gradle

 dependencies {
        compileOnly group: "com.liferay", name: "com.liferay.wiki.api", version: "2.1.0"
        compile group: 'org.jsoup', name: 'jsoup', version: '1.8.3'
        compile group: 'commons-io', name: 'commons-io', version: '2.0.1'
        compile group: "velocity-tools", name: "velocity-tools", version: "1.4"
        compile group: "org.apache.velocity", name: "velocity", version: "1.6.4"
        compile fileTree(dir:"lib",include:"*.jar")
}

Примечание. Поскольку этот пакет ( com.liferay.wiki.apiCompileOnly

Шаг 3: Редактировать bnd.bnd

Отредактируйте файл bnd.bndCompile Eclipse сгенерировал бы этот файл автоматически.

Пример: файл bnd.bnd

Мы можем включить банку двумя различными способами, оба варианта приведены ниже.

Опция 1:

* -включить ресурс:

Этот заголовок используется для добавления внешних зависимостей в наш модуль. Следующий синтаксис извлекает jar и добавляет пакеты в наш модуль.

 -includeresource: \
@jsoup-1.8.3.jar,\
@opencsv-2.2.jar,\
@commons-io-2.0.1.jar,\
@velocity-[0-9]*.jar,\
@velocity-tools-[0-9]*.jar

Вариант 2:

Следующий синтаксис добавляет банки в наш модуль:

 -includeresource: \
lib/jsoup.jar=jsoup-1.8.3.jar,\
lib/opencsv.jar=opencsv-2.2.jar,\
lib/velocity.jar=velocity-[0-9]*.jar,\
lib/velocity-tools.jar=velocity-tools-[0-9]*.jar

Так как мы сделали com.liferay.wiki.api в файле CompileOnlybnd.bnd Если вы не добавите их, bndtool просканирует проект и добавит его в файл манифеста.

 com.liferay.wiki.model;version="[1.0,2)",
com.liferay.wiki.service;version="[1.1,2)"

Шаг 4: Запустите Eclipse Build

Теперь запустите Eclipse Build, используя путь eclipse->Gradle Module -> Eclipse использовал Bndtools для генерации манифеста. Образец манифеста, как показано ниже.

Перейдите к представлению «Задача Gradle». В нем перечислены все модули, доступные в проекте рабочей области. Перейдите в Расширить проект> Построить> Построить .

Это директивы или настройки в заголовке bnd, которые автоматически добавляются в manifest.mf

Пример сгенерированного файла manifest.mf

 Manifest-Version: 1.0
Bnd-LastModified: 1496664974738
Bundle-ManifestVersion: 2
Bundle-Name: ktree_liferay_osgi_example
Bundle-SymbolicName: ktree_liferay_osgi_example
Bundle-Version: 1.0.0
Created-By: 1.8.0_131 (Oracle Corporation)
Import-Package: com.liferay.portal.kernel.exception;version="[7.0,8)",
 com.liferay.portal.kernel.portlet.bridges.mvc;version="[1.0,2)",com.l
 iferay.portal.kernel.service;version="[1.0,2)",com.liferay.portal.ker
 nel.theme;version="[1.0,2)",com.liferay.portal.kernel.util;version="[
 7.0,8)",com.liferay.wiki.model;version="[1.0,2)",com.liferay.wiki.ser
 vice;version="[1.1,2)",javax.portlet;version="[2.0,3)",javax.servlet,
 javax.servlet.http
Javac-Debug: on
Javac-Deprecation: off
Javac-Encoding: UTF-8
Private-Package: com.ktree.portlet,content
Provide-Capability: osgi.service;objectClass:List<String>="javax.portl
 et.Portlet",liferay.resource.bundle;bundle.symbolic.name=ktree_lifera
 y_osgi_example;resource.bundle.base.name="content.Language"
Require-Capability: osgi.extender;filter:="(&(osgi.extender=jsp.taglib
 )(uri=http://java.sun.com/portlet_2_0))",osgi.extender;filter:="(&(os
 gi.extender=jsp.taglib)(uri=http://liferay.com/tld/aui))",osgi.extend
 er;filter:="(&(osgi.extender=jsp.taglib)(uri=http://liferay.com/tld/p
 ortlet))",osgi.extender;filter:="(&(osgi.extender=jsp.taglib)(uri=htt
 p://liferay.com/tld/theme))",osgi.extender;filter:="(&(osgi.extender=
 jsp.taglib)(uri=http://liferay.com/tld/ui))",osgi.ee;filter:="(&(osgi
 .ee=JavaSE)(version=1.8))"
Service-Component: OSGI-INF/com.ktree.portlet.KtreeLiferayOsgiPortlet.
 xml
Tool: Bnd-3.2.0.201605172007

Import-Package:
com.liferay.portal.kernel.exception;version="[7.0,8)",
com.liferay.portal.kernel.portlet.bridges.mvc;version="[1.0,2)",
com.liferay.portal.kernel.service;version="[1.0,2)",
com.liferay.portal.kernel.theme;version="[1.0,2)",
com.liferay.portal.kernel.util;version="[7.0,8)",
javax.portlet;version="[2.0,3)",
javax.servlet,
javax.servlet.http,
com.liferay.wiki.model;version="[1.0,2)",
com.liferay.wiki.service;version="[1.1,2)"

Export-Package: эта директива в заголовке bnd экспортирует пакеты в контейнер OSGi, к которому могут обращаться другие модули. Например:

 Export-Package: com.audit.esprocessor

Если пакет уже экспортирован, нам не нужно делать это снова — мы можем немедленно использовать опцию CompileOnlyCompilebuild.gradle

Импорт-пакет:

  • Этот заголовок bnd импортирует указанный пакет во время выполнения в наш модуль.
  • Всякий раз, когда мы импортируем пакет, он должен быть экспортирован другим модулем.
 Import-Package: \
com.audit.esprocessor;version=&quot;1.0.0&quot;,\

В пакете импорта у нас есть два разрешения, а именно:

  1. Обязательный
  2. Необязательный

Обязательный

  • Это разрешение по умолчанию (если разрешение не указано для импорта).
  • Модуль будет в активном состоянии, если импортированный пакет доступен в контейнере, в противном случае модуль будет в установленном состоянии.

Необязательный

  • Модуль перейдет в активное состояние независимо от наличия пакета импорта.
  • Он выдает исключение во время выполнения, если импортированный пакет недоступен в контейнере.
 Import-Package: \
com.audit.esprocessor;version="1.0.0",\

Шаг 5. Создание портлета Liferay MVC

Последний шаг — создать нормальный портлет Liferay MVC и начать использовать зависимости.

Поскольку мы определили зависимости в Eclipse, мы должны иметь возможность выбрать наш класс, который мы связали.

 WikiPageLocalServiceUtil.addPage(themeDisplay.getUserId(), 123, "First Wiki", 1.0, htmlContent, "", false, "html", true, "FrontPage", "", new ServiceContext());

Пожалуйста, обратитесь к источнику для KtreeLiferayOsgiPortlet-> addContentToWiki

 public class KtreeLiferayOsgiPortlet extends MVCPortlet {
    @ProcessAction(name="addContentToWiki")
    public void addContentToWiki(ActionRequest actionRequest,ActionResponse actionResponse) throws PortalException{
        String htmlContent = ParamUtil.getString(actionRequest, "wikiEditor");
        ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
        WikiPageLocalServiceUtil.addPage(themeDisplay.getUserId(), 123, "First Wiki", 1.0, htmlContent, "", false, "html", true, "FrontPage", "", new ServiceContext());
        System.out.println(WikiPageLocalServiceUtil.getWikiPagesCount());

    }
}

Пример модуля Liferay OSGi:

  • Добавлен API вики как зависимость времени компиляции с compileOnly

  • Пользовательский интерфейс построен с компонентами aui

  • Пользовательский интерфейс имеет опции для создания вики-страницы, а также показывает список вики-страниц.

Пример init.jsp

 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>

<liferay-theme:defineObjects />

<portlet:defineObjects />
<portlet:actionURL name="addContentToWiki" var="addContentToWikiUrl">
</portlet:actionURL>

Пример View.jsp

 <%@include file="init.jsp" %>
<aui:form action="${addContentToWikiUrl}" name="wikiform">
<h3>Enter content here</h3>
    <liferay-ui:input-editor name="wikiEditor" placeholder="Enter content here"></liferay-ui:input-editor>
    <aui:button-row>
        <aui:button type="submit"></aui:button>
    </aui:button-row>
    <br/>
    <h3><u>Wiki List</u></h3>
    <liferay-portlet:runtime portletName="com_liferay_wiki_web_portlet_WikiPortlet"/>
</aui:form>

Пример контроллера — KtreeLiferayOsgiPortlet.java

 @Component(
    immediate = true,
    property = {
        "com.liferay.portlet.display-category=KTree",
        "com.liferay.portlet.instanceable=true",
        "javax.portlet.display-name=Ktree Liferay OSGI Portlet",
        "javax.portlet.init-param.template-path=/",
        "javax.portlet.init-param.view-template=/view.jsp",
        "javax.portlet.resource-bundle=content.Language",
        "javax.portlet.security-role-ref=power-user,user"
    },
    service = Portlet.class
)
public class KtreeLiferayOsgiPortlet extends MVCPortlet {
    @ProcessAction(name="addContentToWikiUrl")



    public void addHtmlToWikiPage(ActionRequest actionRequest,ActionResponse actionResponse) throws PortalException{


        //add logic here to add wikipage        
    }
}