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.portal.verify;
016    
017    import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
018    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
019    import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
020    import com.liferay.portal.kernel.dao.orm.Property;
021    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
022    import com.liferay.portal.kernel.exception.PortalException;
023    import com.liferay.portal.kernel.exception.SystemException;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.util.ArrayUtil;
027    import com.liferay.portal.kernel.util.CharPool;
028    import com.liferay.portal.kernel.util.StringUtil;
029    import com.liferay.portal.model.GroupConstants;
030    import com.liferay.portal.model.Layout;
031    import com.liferay.portal.model.LayoutRevision;
032    import com.liferay.portal.model.LayoutTypePortlet;
033    import com.liferay.portal.model.Portlet;
034    import com.liferay.portal.model.PortletPreferences;
035    import com.liferay.portal.service.ClassNameLocalServiceUtil;
036    import com.liferay.portal.service.LayoutLocalServiceUtil;
037    import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
038    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
039    import com.liferay.portal.service.persistence.PortletPreferencesActionableDynamicQuery;
040    import com.liferay.portlet.PortletPreferencesFactoryUtil;
041    import com.liferay.portlet.assetpublisher.util.AssetPublisher;
042    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
043    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
044    import com.liferay.portlet.journal.model.JournalArticle;
045    
046    import java.util.ArrayList;
047    import java.util.Arrays;
048    import java.util.List;
049    
050    import javax.portlet.ReadOnlyException;
051    
052    /**
053     * @author Andrew Betts
054     * @author Christopher Kian
055     */
056    public class VerifyPortletPreferences extends VerifyProcess {
057    
058            public static void cleanUpLayoutRevisionPortletPreferences()
059                    throws Exception {
060    
061                    ActionableDynamicQuery actionableDynamicQuery =
062                            new PortletPreferencesActionableDynamicQuery() {
063    
064                            @Override
065                            protected void addCriteria(DynamicQuery dynamicQuery) {
066                                    Property plidProperty = PropertyFactoryUtil.forName("plid");
067    
068                                    DynamicQuery layoutRevisionDynamicQuery =
069                                            LayoutRevisionLocalServiceUtil.dynamicQuery();
070    
071                                    layoutRevisionDynamicQuery.setProjection(
072                                            ProjectionFactoryUtil.property("layoutRevisionId"));
073    
074                                    dynamicQuery.add(plidProperty.in(layoutRevisionDynamicQuery));
075                            }
076    
077                            @Override
078                            protected void performAction(Object object)
079                                    throws PortalException, SystemException {
080    
081                                    PortletPreferences portletPreferences =
082                                            (PortletPreferences)object;
083    
084                                    long layoutRevisionId = portletPreferences.getPlid();
085    
086                                    LayoutRevision layoutRevision =
087                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
088                                                    layoutRevisionId);
089    
090                                    Layout layout = LayoutLocalServiceUtil.getLayout(
091                                            layoutRevision.getPlid());
092    
093                                    if (!layout.isTypePortlet()) {
094                                            return;
095                                    }
096    
097                                    LayoutTypePortlet layoutTypePortlet =
098                                            (LayoutTypePortlet)layout.getLayoutType();
099    
100                                    List<Portlet> portlets = layoutTypePortlet.getAllPortlets();
101    
102                                    List<String> portletIds = new ArrayList<String>(
103                                            portlets.size());
104    
105                                    for (Portlet portlet : portlets) {
106                                            portletIds.add(Portlet.PORTLET_ID_ACCESSOR.get(portlet));
107                                    }
108    
109                                    if (portletIds.contains(portletPreferences.getPortletId())) {
110                                            return;
111                                    }
112    
113                                    if (_log.isWarnEnabled()) {
114                                            _log.warn(
115                                                    "Removing portlet preferences " +
116                                                            portletPreferences.getPortletPreferencesId());
117                                    }
118    
119                                    PortletPreferencesLocalServiceUtil.deletePortletPreferences(
120                                            portletPreferences);
121                            }
122    
123                    };
124    
125                    actionableDynamicQuery.performActions();
126            }
127    
128            public static void cleanUpScopeIdPortletPreferences() throws Exception {
129                    final long classNameId = ClassNameLocalServiceUtil.getClassNameId(
130                            JournalArticle.class.getName());
131    
132                    ActionableDynamicQuery actionableDynamicQuery =
133                            new PortletPreferencesActionableDynamicQuery() {
134    
135                            @Override
136                            protected void addCriteria(DynamicQuery dynamicQuery) {
137                                    Property plidProperty = PropertyFactoryUtil.forName("plid");
138    
139                                    DynamicQuery layoutDynamicQuery =
140                                            LayoutLocalServiceUtil.dynamicQuery();
141    
142                                    layoutDynamicQuery.setProjection(
143                                            ProjectionFactoryUtil.property("plid"));
144    
145                                    dynamicQuery.add(plidProperty.in(layoutDynamicQuery));
146                            }
147    
148                            @Override
149                            protected void performAction(Object object)
150                                    throws PortalException, SystemException {
151    
152                                    PortletPreferences portletPreferences =
153                                            (PortletPreferences)object;
154    
155                                    long plid = portletPreferences.getPlid();
156    
157                                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
158    
159                                    if (!layout.isTypePortlet()) {
160                                            return;
161                                    }
162    
163                                    javax.portlet.PortletPreferences jxPortletPreferences =
164                                            PortletPreferencesFactoryUtil.strictFromXML(
165                                                    layout.getCompanyId(), portletPreferences.getOwnerId(),
166                                                    portletPreferences.getOwnerType(), plid,
167                                                    portletPreferences.getPortletId(),
168                                                    portletPreferences.getPreferences());
169    
170                                    String[] scopeIds = jxPortletPreferences.getValues(
171                                            "scopeIds", null);
172    
173                                    String preferenceName =
174                                            "classTypeIdsJournalArticleAssetRendererFactory";
175    
176                                    String[] classTypeIds = jxPortletPreferences.getValues(
177                                            preferenceName, null);
178    
179                                    try {
180                                            if (ArrayUtil.isNotEmpty(classTypeIds) ||
181                                                    ArrayUtil.isNotEmpty(scopeIds)) {
182    
183                                                    if (ArrayUtil.isEmpty(scopeIds)) {
184                                                            scopeIds = new String[] {
185                                                                    AssetPublisher.SCOPE_ID_GROUP_PREFIX +
186                                                                            GroupConstants.DEFAULT
187                                                            };
188    
189                                                            jxPortletPreferences.setValue(
190                                                                    "scopeIds", scopeIds[0]);
191                                                    }
192    
193                                                    long[] groupIds = getGroupIds(
194                                                            scopeIds, layout.getGroupId());
195    
196                                                    List<DDMStructure> structures =
197                                                            DDMStructureLocalServiceUtil.getStructures(
198                                                                    groupIds, classNameId);
199    
200                                                    long[] structureIds = new long[structures.size()];
201    
202                                                    for (DDMStructure structure : structures) {
203                                                            structureIds = ArrayUtil.append(
204                                                                    structureIds, structure.getStructureId());
205                                                    }
206    
207                                                    if (ArrayUtil.isNotEmpty(structureIds)) {
208                                                            String structureIdsString = StringUtil.strip(
209                                                                    Arrays.toString(structureIds),
210                                                                    new char[] {
211                                                                            CharPool.CLOSE_BRACKET,
212                                                                            CharPool.OPEN_BRACKET, CharPool.SPACE
213                                                                    });
214    
215                                                            jxPortletPreferences.setValue(
216                                                                    preferenceName, structureIdsString);
217                                                    }
218                                                    else {
219                                                            jxPortletPreferences.reset(preferenceName);
220                                                    }
221                                            }
222                                            else {
223                                                    jxPortletPreferences.reset(preferenceName);
224                                            }
225                                    }
226                                    catch (ReadOnlyException roe) {
227                                            if (_log.isWarnEnabled()) {
228                                                    _log.warn(
229                                                            "Unable to update portlet preferences " +
230                                                                    portletPreferences.getPortletPreferencesId());
231                                            }
232    
233                                            return;
234                                    }
235    
236                                    if (_log.isInfoEnabled()) {
237                                            _log.info(
238                                                    "Updating portlet preferences " +
239                                                            portletPreferences.getPortletPreferencesId());
240                                    }
241    
242                                    PortletPreferencesLocalServiceUtil.updatePreferences(
243                                            portletPreferences.getOwnerId(),
244                                            portletPreferences.getOwnerType(), plid,
245                                            portletPreferences.getPortletId(), jxPortletPreferences);
246                            }
247    
248                    };
249    
250                    actionableDynamicQuery.performActions();
251            }
252    
253            private static long[] getGroupIds(String[] scopeIds, long defaultGroupId) {
254                    long[] groupIds = new long[0];
255    
256                    for (String scopeId : scopeIds) {
257                            if (!scopeId.startsWith(AssetPublisher.SCOPE_ID_GROUP_PREFIX)) {
258                                    continue;
259                            }
260    
261                            long siteGroupId = 0;
262    
263                            String scopeIdSuffix = scopeId.substring(
264                                    AssetPublisher.SCOPE_ID_GROUP_PREFIX.length());
265    
266                            if (scopeIdSuffix.equals(GroupConstants.DEFAULT)) {
267                                    siteGroupId = defaultGroupId;
268                            }
269                            else {
270                                    siteGroupId = Long.valueOf(scopeIdSuffix);
271                            }
272    
273                            groupIds = ArrayUtil.append(groupIds, siteGroupId);
274                    }
275    
276                    return groupIds;
277            }
278    
279            @Override
280            protected void doVerify() throws Exception {
281                    cleanUpLayoutRevisionPortletPreferences();
282                    cleanUpScopeIdPortletPreferences();
283            }
284    
285            private static Log _log = LogFactoryUtil.getLog(
286                    VerifyPortletPreferences.class);
287    
288    }