/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.journal.content.web.internal; import com.liferay.dynamic.data.mapping.model.DDMStructure; import com.liferay.dynamic.data.mapping.model.DDMTemplate; import com.liferay.dynamic.data.mapping.service.DDMTemplateLocalService; import com.liferay.journal.content.web.constants.JournalContentPortletKeys; import com.liferay.journal.exception.NoSuchArticleException; import com.liferay.journal.model.JournalArticle; import com.liferay.journal.service.JournalArticleLocalService; import com.liferay.journal.service.JournalContentSearchLocalService; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.Group; import com.liferay.portal.kernel.model.Layout; import com.liferay.portal.kernel.model.PortletInstance; import com.liferay.portal.kernel.portlet.PortletLayoutListener; import com.liferay.portal.kernel.portlet.PortletLayoutListenerException; import com.liferay.portal.kernel.portlet.PortletPreferencesFactoryUtil; import com.liferay.portal.kernel.service.GroupLocalService; import com.liferay.portal.kernel.service.LayoutLocalService; import com.liferay.portal.kernel.service.PortletLocalService; import com.liferay.portal.kernel.util.Portal; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.UnicodeProperties; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.xml.Document; import com.liferay.portal.kernel.xml.Element; import com.liferay.portal.kernel.xml.SAXReaderUtil; import com.liferay.portal.layoutconfiguration.util.xml.PortletLogic; import java.util.LinkedHashSet; import java.util.Set; import javax.portlet.PortletPreferences; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; /** * @author Brian Wing Shun Chan * @author Raymond Augé */ @Component( immediate = true, property = { "javax.portlet.name=" + JournalContentPortletKeys.JOURNAL_CONTENT }, service = PortletLayoutListener.class ) public class JournalContentPortletLayoutListener implements PortletLayoutListener { @Override public void onAddToLayout(String portletId, long plid) throws PortletLayoutListenerException { if (_log.isDebugEnabled()) { _log.debug("Add " + portletId + " to layout " + plid); } try { Layout layout = _layoutLocalService.getLayout(plid); PortletPreferences portletPreferences = PortletPreferencesFactoryUtil.getPortletSetup( layout, portletId, StringPool.BLANK); String articleId = portletPreferences.getValue("articleId", null); if (Validator.isNull(articleId)) { return; } _journalContentSearchLocalService.updateContentSearch( layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(), portletId, articleId, true); } catch (Exception e) { throw new PortletLayoutListenerException(e); } } @Override public void onMoveInLayout(String portletId, long plid) throws PortletLayoutListenerException { if (_log.isDebugEnabled()) { _log.debug("Move " + portletId + " from in " + plid); } } @Override public void onRemoveFromLayout(String portletId, long plid) throws PortletLayoutListenerException { if (_log.isDebugEnabled()) { _log.debug("Remove " + portletId + " from layout " + plid); } try { Layout layout = _layoutLocalService.getLayout(plid); PortletPreferences portletPreferences = PortletPreferencesFactoryUtil.getPortletSetup( layout, portletId, StringPool.BLANK); String articleId = portletPreferences.getValue("articleId", null); if (Validator.isNull(articleId)) { return; } _journalContentSearchLocalService.deleteArticleContentSearch( layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(), portletId, articleId); String[] runtimePortletIds = getRuntimePortletIds( layout.getCompanyId(), layout.getGroupId(), articleId); if (runtimePortletIds.length > 0) { _portletLocalService.deletePortlets( layout.getCompanyId(), runtimePortletIds, layout.getPlid()); } } catch (Exception e) { throw new PortletLayoutListenerException(e); } } @Override public void onSetup(String portletId, long plid) throws PortletLayoutListenerException { if (_log.isDebugEnabled()) { _log.debug("Setup " + portletId + " from layout " + plid); } try { Layout layout = _layoutLocalService.getLayout(plid); PortletPreferences portletPreferences = PortletPreferencesFactoryUtil.getPortletSetup( layout, portletId, StringPool.BLANK); String articleId = portletPreferences.getValue("articleId", null); if (Validator.isNull(articleId)) { _journalContentSearchLocalService.deleteArticleContentSearch( layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(), portletId); return; } _journalContentSearchLocalService.updateContentSearch( layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(), portletId, articleId, true); } catch (Exception e) { throw new PortletLayoutListenerException(e); } } @Override public void updatePropertiesOnRemoveFromLayout( String portletId, UnicodeProperties typeSettingsProperties) throws PortletLayoutListenerException { } protected String getRuntimePortletId(String xml) throws Exception { Document document = SAXReaderUtil.read(xml); Element rootElement = document.getRootElement(); String portletName = rootElement.attributeValue("name"); String instanceId = rootElement.attributeValue("instance"); PortletInstance portletInstance = new PortletInstance( portletName, instanceId); return portletInstance.getPortletInstanceKey(); } protected String[] getRuntimePortletIds( long companyId, long scopeGroupId, String articleId) throws Exception { Group group = _groupLocalService.getCompanyGroup(companyId); JournalArticle article = null; try { article = _journalArticleLocalService.getDisplayArticle( scopeGroupId, articleId); } catch (NoSuchArticleException nsae) { } if (article == null) { try { article = _journalArticleLocalService.getDisplayArticle( group.getGroupId(), articleId); } catch (NoSuchArticleException nsae) { return new String[0]; } } Set<String> portletIds = getRuntimePortletIds(article.getContent()); if (Validator.isNotNull(article.getDDMTemplateKey())) { DDMTemplate ddmTemplate = _ddmTemplateLocalService.getTemplate( scopeGroupId, _portal.getClassNameId(DDMStructure.class), article.getDDMTemplateKey(), true); portletIds.addAll(getRuntimePortletIds(ddmTemplate.getScript())); } return portletIds.toArray(new String[portletIds.size()]); } protected Set<String> getRuntimePortletIds(String content) throws Exception { Set<String> portletIds = new LinkedHashSet<>(); for (int index = 0;;) { index = content.indexOf(PortletLogic.OPEN_TAG, index); if (index == -1) { break; } int close1 = content.indexOf(PortletLogic.CLOSE_1_TAG, index); int close2 = content.indexOf(PortletLogic.CLOSE_2_TAG, index); int closeIndex = -1; if ((close2 == -1) || ((close1 != -1) && (close1 < close2))) { closeIndex = close1 + PortletLogic.CLOSE_1_TAG.length(); } else { closeIndex = close2 + PortletLogic.CLOSE_2_TAG.length(); } if (closeIndex == -1) { break; } portletIds.add( getRuntimePortletId(content.substring(index, closeIndex))); index = closeIndex; } return portletIds; } @Reference(unbind = "-") protected void setDDMTemplateLocalService( DDMTemplateLocalService ddmTemplateLocalService) { _ddmTemplateLocalService = ddmTemplateLocalService; } @Reference(unbind = "-") protected void setGroupLocalService(GroupLocalService groupLocalService) { _groupLocalService = groupLocalService; } @Reference(unbind = "-") protected void setJournalArticleLocalService( JournalArticleLocalService journalArticleLocalService) { _journalArticleLocalService = journalArticleLocalService; } @Reference(unbind = "-") protected void setJournalContentSearchLocalService( JournalContentSearchLocalService journalContentSearchLocalService) { _journalContentSearchLocalService = journalContentSearchLocalService; } @Reference(unbind = "-") protected void setLayoutLocalService( LayoutLocalService layoutLocalService) { _layoutLocalService = layoutLocalService; } @Reference(unbind = "-") protected void setPortletLocalService( PortletLocalService portletLocalService) { _portletLocalService = portletLocalService; } private static final Log _log = LogFactoryUtil.getLog( JournalContentPortletLayoutListener.class); private DDMTemplateLocalService _ddmTemplateLocalService; private GroupLocalService _groupLocalService; private JournalArticleLocalService _journalArticleLocalService; private JournalContentSearchLocalService _journalContentSearchLocalService; private LayoutLocalService _layoutLocalService; @Reference private Portal _portal; private PortletLocalService _portletLocalService; }