001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journalcontent;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.portlet.PortletLayoutListener;
020    import com.liferay.portal.kernel.portlet.PortletLayoutListenerException;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.UniqueList;
023    import com.liferay.portal.kernel.util.Validator;
024    import com.liferay.portal.kernel.xml.Document;
025    import com.liferay.portal.kernel.xml.Element;
026    import com.liferay.portal.kernel.xml.SAXReaderUtil;
027    import com.liferay.portal.model.Group;
028    import com.liferay.portal.model.Layout;
029    import com.liferay.portal.model.PortletConstants;
030    import com.liferay.portal.service.GroupLocalServiceUtil;
031    import com.liferay.portal.service.LayoutLocalServiceUtil;
032    import com.liferay.portal.service.PortletLocalServiceUtil;
033    import com.liferay.portlet.PortletPreferencesFactoryUtil;
034    import com.liferay.portlet.journal.NoSuchArticleException;
035    import com.liferay.portlet.journal.NoSuchTemplateException;
036    import com.liferay.portlet.journal.model.JournalArticle;
037    import com.liferay.portlet.journal.model.JournalTemplate;
038    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
039    import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
040    import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
041    import com.liferay.portlet.layoutconfiguration.util.xml.PortletLogic;
042    
043    import java.util.List;
044    
045    import javax.portlet.PortletPreferences;
046    
047    /**
048     * @author Brian Wing Shun Chan
049     * @author Raymond Augé
050     */
051    public class JournalContentPortletLayoutListener
052            implements PortletLayoutListener {
053    
054            public void onAddToLayout(String portletId, long plid)
055                    throws PortletLayoutListenerException {
056    
057                    if (_log.isDebugEnabled()) {
058                            _log.debug("Add " + portletId + " to layout " + plid);
059                    }
060    
061                    try {
062                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
063    
064                            PortletPreferences preferences =
065                                    PortletPreferencesFactoryUtil.getPortletSetup(
066                                            layout, portletId, StringPool.BLANK);
067    
068                            String articleId = preferences.getValue("articleId", null);
069    
070                            if (Validator.isNull(articleId)) {
071                                    return;
072                            }
073    
074                            JournalContentSearchLocalServiceUtil.updateContentSearch(
075                                    layout.getGroupId(), layout.isPrivateLayout(),
076                                    layout.getLayoutId(), portletId, articleId, true);
077                    }
078                    catch (Exception e) {
079                            throw new PortletLayoutListenerException(e);
080                    }
081            }
082    
083            public void onMoveInLayout(String portletId, long plid)
084                    throws PortletLayoutListenerException {
085    
086                    if (_log.isDebugEnabled()) {
087                            _log.debug("Move " + portletId + " from in " + plid);
088                    }
089            }
090    
091            public void onRemoveFromLayout(String portletId, long plid)
092                    throws PortletLayoutListenerException {
093    
094                    if (_log.isDebugEnabled()) {
095                            _log.debug("Remove " + portletId + " from layout " + plid);
096                    }
097    
098                    try {
099                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
100    
101                            PortletPreferences preferences =
102                                    PortletPreferencesFactoryUtil.getPortletSetup(
103                                            layout, portletId, StringPool.BLANK);
104    
105                            String articleId = preferences.getValue("articleId", null);
106    
107                            if (Validator.isNull(articleId)) {
108                                    return;
109                            }
110    
111                            JournalContentSearchLocalServiceUtil.deleteArticleContentSearch(
112                                    layout.getGroupId(), layout.isPrivateLayout(),
113                                    layout.getLayoutId(), portletId, articleId);
114    
115                            String[] runtimePortletIds = getRuntimePortletIds(
116                                    layout.getCompanyId(), layout.getGroupId(), articleId);
117    
118                            if (runtimePortletIds.length > 0) {
119                                    PortletLocalServiceUtil.deletePortlets(
120                                            layout.getCompanyId(), runtimePortletIds, layout.getPlid());
121                            }
122                    }
123                    catch (Exception e) {
124                            throw new PortletLayoutListenerException(e);
125                    }
126            }
127    
128            protected String getRuntimePortletId(String xml) throws Exception {
129                    Document document = SAXReaderUtil.read(xml);
130    
131                    Element rootElement = document.getRootElement();
132    
133                    String instanceId = rootElement.attributeValue("instance");
134                    String portletId = rootElement.attributeValue("name");
135    
136                    if (Validator.isNotNull(instanceId)) {
137                            portletId += PortletConstants.INSTANCE_SEPARATOR + instanceId;
138                    }
139    
140                    return portletId;
141            }
142    
143            protected String[] getRuntimePortletIds(
144                            long companyId, long scopeGroupId, String articleId)
145                    throws Exception {
146    
147                    Group group = GroupLocalServiceUtil.getCompanyGroup(companyId);
148    
149                    JournalArticle article = null;
150    
151                    try {
152                            article = JournalArticleLocalServiceUtil.getDisplayArticle(
153                                    scopeGroupId, articleId);
154                    }
155                    catch (NoSuchArticleException nsae) {
156                    }
157    
158                    if (article == null) {
159                            try {
160                                    article =
161                                            JournalArticleLocalServiceUtil.getDisplayArticle(
162                                                    group.getGroupId(), articleId);
163                            }
164                            catch (NoSuchArticleException nsae) {
165                                    return new String[0];
166                            }
167                    }
168    
169                    List<String> portletIds = getRuntimePortletIds(article.getContent());
170    
171                    if (Validator.isNotNull(article.getTemplateId())) {
172                            JournalTemplate journalTemplate = null;
173    
174                            try {
175                                    journalTemplate = JournalTemplateLocalServiceUtil.getTemplate(
176                                            scopeGroupId, article.getTemplateId());
177                            }
178                            catch (NoSuchTemplateException nste) {
179                                    journalTemplate = JournalTemplateLocalServiceUtil.getTemplate(
180                                            group.getGroupId(), article.getTemplateId());
181                            }
182    
183                            portletIds.addAll(getRuntimePortletIds(journalTemplate.getXsl()));
184                    }
185    
186                    return portletIds.toArray(new String[portletIds.size()]);
187            }
188    
189            protected List<String> getRuntimePortletIds(String content)
190                    throws Exception {
191    
192                    List<String> portletIds = new UniqueList<String>();
193    
194                    for (int index = 0;;) {
195                            index = content.indexOf(PortletLogic.OPEN_TAG, index);
196    
197                            if (index == -1) {
198                                    break;
199                            }
200    
201                            int close1 = content.indexOf(PortletLogic.CLOSE_1_TAG, index);
202                            int close2 = content.indexOf(PortletLogic.CLOSE_2_TAG, index);
203    
204                            int closeIndex = -1;
205    
206                            if ((close2 == -1) || ((close1 != -1) && (close1 < close2))) {
207                                    closeIndex = close1 + PortletLogic.CLOSE_1_TAG.length();
208                            }
209                            else {
210                                    closeIndex = close2 + PortletLogic.CLOSE_2_TAG.length();
211                            }
212    
213                            if (closeIndex == -1) {
214                                    break;
215                            }
216    
217                            portletIds.add(
218                                    getRuntimePortletId(content.substring(index, closeIndex)));
219    
220                            index = closeIndex;
221                    }
222    
223                    return portletIds;
224            }
225    
226            private static Log _log = LogFactoryUtil.getLog(
227                    JournalContentPortletLayoutListener.class);
228    
229    }