001    /**
002     * Copyright (c) 2000-2013 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.layoutconfiguration.util.xml.PortletLogic;
028    import com.liferay.portal.model.Group;
029    import com.liferay.portal.model.Layout;
030    import com.liferay.portal.model.PortletConstants;
031    import com.liferay.portal.service.GroupLocalServiceUtil;
032    import com.liferay.portal.service.LayoutLocalServiceUtil;
033    import com.liferay.portal.service.PortletLocalServiceUtil;
034    import com.liferay.portal.util.PortalUtil;
035    import com.liferay.portlet.PortletPreferencesFactoryUtil;
036    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
037    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
038    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
039    import com.liferay.portlet.journal.NoSuchArticleException;
040    import com.liferay.portlet.journal.model.JournalArticle;
041    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
042    import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
043    
044    import java.util.List;
045    
046    import javax.portlet.PortletPreferences;
047    
048    /**
049     * @author Brian Wing Shun Chan
050     * @author Raymond Aug??
051     */
052    public class JournalContentPortletLayoutListener
053            implements PortletLayoutListener {
054    
055            @Override
056            public void onAddToLayout(String portletId, long plid)
057                    throws PortletLayoutListenerException {
058    
059                    if (_log.isDebugEnabled()) {
060                            _log.debug("Add " + portletId + " to layout " + plid);
061                    }
062    
063                    try {
064                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
065    
066                            PortletPreferences preferences =
067                                    PortletPreferencesFactoryUtil.getPortletSetup(
068                                            layout, portletId, StringPool.BLANK);
069    
070                            String articleId = preferences.getValue("articleId", null);
071    
072                            if (Validator.isNull(articleId)) {
073                                    return;
074                            }
075    
076                            JournalContentSearchLocalServiceUtil.updateContentSearch(
077                                    layout.getGroupId(), layout.isPrivateLayout(),
078                                    layout.getLayoutId(), portletId, articleId, true);
079                    }
080                    catch (Exception e) {
081                            throw new PortletLayoutListenerException(e);
082                    }
083            }
084    
085            @Override
086            public void onMoveInLayout(String portletId, long plid)
087                    throws PortletLayoutListenerException {
088    
089                    if (_log.isDebugEnabled()) {
090                            _log.debug("Move " + portletId + " from in " + plid);
091                    }
092            }
093    
094            @Override
095            public void onRemoveFromLayout(String portletId, long plid)
096                    throws PortletLayoutListenerException {
097    
098                    if (_log.isDebugEnabled()) {
099                            _log.debug("Remove " + portletId + " from layout " + plid);
100                    }
101    
102                    try {
103                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
104    
105                            PortletPreferences preferences =
106                                    PortletPreferencesFactoryUtil.getPortletSetup(
107                                            layout, portletId, StringPool.BLANK);
108    
109                            String articleId = preferences.getValue("articleId", null);
110    
111                            if (Validator.isNull(articleId)) {
112                                    return;
113                            }
114    
115                            JournalContentSearchLocalServiceUtil.deleteArticleContentSearch(
116                                    layout.getGroupId(), layout.isPrivateLayout(),
117                                    layout.getLayoutId(), portletId, articleId);
118    
119                            String[] runtimePortletIds = getRuntimePortletIds(
120                                    layout.getCompanyId(), layout.getGroupId(), articleId);
121    
122                            if (runtimePortletIds.length > 0) {
123                                    PortletLocalServiceUtil.deletePortlets(
124                                            layout.getCompanyId(), runtimePortletIds, layout.getPlid());
125                            }
126                    }
127                    catch (Exception e) {
128                            throw new PortletLayoutListenerException(e);
129                    }
130            }
131    
132            protected String getRuntimePortletId(String xml) throws Exception {
133                    Document document = SAXReaderUtil.read(xml);
134    
135                    Element rootElement = document.getRootElement();
136    
137                    String instanceId = rootElement.attributeValue("instance");
138                    String portletId = rootElement.attributeValue("name");
139    
140                    if (Validator.isNotNull(instanceId)) {
141                            portletId += PortletConstants.INSTANCE_SEPARATOR + instanceId;
142                    }
143    
144                    return portletId;
145            }
146    
147            protected String[] getRuntimePortletIds(
148                            long companyId, long scopeGroupId, String articleId)
149                    throws Exception {
150    
151                    Group group = GroupLocalServiceUtil.getCompanyGroup(companyId);
152    
153                    JournalArticle article = null;
154    
155                    try {
156                            article = JournalArticleLocalServiceUtil.getDisplayArticle(
157                                    scopeGroupId, articleId);
158                    }
159                    catch (NoSuchArticleException nsae) {
160                    }
161    
162                    if (article == null) {
163                            try {
164                                    article = JournalArticleLocalServiceUtil.getDisplayArticle(
165                                            group.getGroupId(), articleId);
166                            }
167                            catch (NoSuchArticleException nsae) {
168                                    return new String[0];
169                            }
170                    }
171    
172                    List<String> portletIds = getRuntimePortletIds(article.getContent());
173    
174                    if (Validator.isNotNull(article.getTemplateId())) {
175                            DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
176                                    scopeGroupId, PortalUtil.getClassNameId(DDMStructure.class),
177                                    article.getTemplateId(), true);
178    
179                            portletIds.addAll(getRuntimePortletIds(ddmTemplate.getScript()));
180                    }
181    
182                    return portletIds.toArray(new String[portletIds.size()]);
183            }
184    
185            protected List<String> getRuntimePortletIds(String content)
186                    throws Exception {
187    
188                    List<String> portletIds = new UniqueList<String>();
189    
190                    for (int index = 0;;) {
191                            index = content.indexOf(PortletLogic.OPEN_TAG, index);
192    
193                            if (index == -1) {
194                                    break;
195                            }
196    
197                            int close1 = content.indexOf(PortletLogic.CLOSE_1_TAG, index);
198                            int close2 = content.indexOf(PortletLogic.CLOSE_2_TAG, index);
199    
200                            int closeIndex = -1;
201    
202                            if ((close2 == -1) || ((close1 != -1) && (close1 < close2))) {
203                                    closeIndex = close1 + PortletLogic.CLOSE_1_TAG.length();
204                            }
205                            else {
206                                    closeIndex = close2 + PortletLogic.CLOSE_2_TAG.length();
207                            }
208    
209                            if (closeIndex == -1) {
210                                    break;
211                            }
212    
213                            portletIds.add(
214                                    getRuntimePortletId(content.substring(index, closeIndex)));
215    
216                            index = closeIndex;
217                    }
218    
219                    return portletIds;
220            }
221    
222            private static Log _log = LogFactoryUtil.getLog(
223                    JournalContentPortletLayoutListener.class);
224    
225    }