001    /**
002     * Copyright (c) 2000-present 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.LayoutFriendlyURLException;
018    import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.util.StringBundler;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.Validator;
024    import com.liferay.portal.model.Layout;
025    import com.liferay.portal.model.LayoutFriendlyURL;
026    import com.liferay.portal.service.LayoutFriendlyURLLocalServiceUtil;
027    import com.liferay.portal.service.LayoutLocalServiceUtil;
028    
029    import java.util.ArrayList;
030    import java.util.List;
031    
032    /**
033     * @author Brian Wing Shun Chan
034     * @author Gergely Mathe
035     * @author Kenneth Chang
036     */
037    public class VerifyLayout extends VerifyProcess {
038    
039            protected void deleteOrphanedLayouts() throws Exception {
040                    runSQL(
041                            "delete from Layout where layoutPrototypeUuid != '' and " +
042                                    "layoutPrototypeUuid not in (select uuid_ from " +
043                                            "LayoutPrototype)");
044            }
045    
046            @Override
047            protected void doVerify() throws Exception {
048                    deleteOrphanedLayouts();
049                    verifyFriendlyURL();
050                    verifyLayoutIdFriendlyURL();
051                    verifyLayoutPrototypeLinkEnabled();
052                    verifyUuid();
053            }
054    
055            protected List<Layout> getInvalidLayoutIdFriendlyURLLayouts()
056                    throws Exception {
057    
058                    final List<Layout> layouts = new ArrayList<>();
059    
060                    ActionableDynamicQuery actionableDynamicQuery =
061                            LayoutLocalServiceUtil.getActionableDynamicQuery();
062    
063                    actionableDynamicQuery.setPerformActionMethod(
064                            new ActionableDynamicQuery.PerformActionMethod() {
065    
066                                    @Override
067                                    public void performAction(Object object) {
068                                            Layout layout = (Layout)object;
069    
070                                            String friendlyURL = layout.getFriendlyURL();
071    
072                                            friendlyURL = friendlyURL.substring(1);
073    
074                                            if (Validator.isNumber(friendlyURL) &&
075                                                    !friendlyURL.equals(
076                                                            String.valueOf(layout.getLayoutId()))) {
077    
078                                                    layouts.add(layout);
079                                            }
080                                    }
081    
082                            });
083    
084                    actionableDynamicQuery.performActions();
085    
086                    return layouts;
087            }
088    
089            protected void verifyFriendlyURL() throws Exception {
090                    List<Layout> layouts =
091                            LayoutLocalServiceUtil.getNullFriendlyURLLayouts();
092    
093                    for (Layout layout : layouts) {
094                            List<LayoutFriendlyURL> layoutFriendlyURLs =
095                                    LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLs(
096                                            layout.getPlid());
097    
098                            for (LayoutFriendlyURL layoutFriendlyURL : layoutFriendlyURLs) {
099                                    String friendlyURL = StringPool.SLASH + layout.getLayoutId();
100    
101                                    LayoutLocalServiceUtil.updateFriendlyURL(
102                                            layout.getUserId(), layout.getPlid(), friendlyURL,
103                                            layoutFriendlyURL.getLanguageId());
104                            }
105                    }
106            }
107    
108            protected void verifyLayoutIdFriendlyURL() throws Exception {
109                    while (true) {
110                            List<Layout> layouts = getInvalidLayoutIdFriendlyURLLayouts();
111    
112                            if (layouts.isEmpty()) {
113                                    break;
114                            }
115    
116                            for (Layout layout : layouts) {
117                                    if (verifyLayoutIdFriendlyURL(layout)) {
118                                            continue;
119                                    }
120                            }
121                    }
122            }
123    
124            protected boolean verifyLayoutIdFriendlyURL(Layout layout)
125                    throws Exception {
126    
127                    String oldFriendlyURL = layout.getFriendlyURL();
128                    String newFriendlyURL = StringPool.SLASH + layout.getLayoutId();
129    
130                    if (_log.isDebugEnabled()) {
131                            _log.debug(
132                                    "Updating layout " + layout.getPlid() + " from friendly URL " +
133                                            oldFriendlyURL + " to friendly URL " + newFriendlyURL);
134                    }
135    
136                    List<LayoutFriendlyURL> layoutFriendlyURLs =
137                            LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLs(
138                                    layout.getPlid());
139    
140                    for (LayoutFriendlyURL layoutFriendlyURL : layoutFriendlyURLs) {
141                            if (!oldFriendlyURL.equals(layoutFriendlyURL.getFriendlyURL())) {
142                                    return true;
143                            }
144    
145                            try {
146                                    LayoutLocalServiceUtil.updateFriendlyURL(
147                                            layout.getUserId(), layout.getPlid(), newFriendlyURL,
148                                            layoutFriendlyURL.getLanguageId());
149                            }
150                            catch (LayoutFriendlyURLException lfurle) {
151                                    int type = lfurle.getType();
152    
153                                    if (type == LayoutFriendlyURLException.DUPLICATE) {
154                                            return true;
155                                    }
156                                    else {
157                                            throw lfurle;
158                                    }
159                            }
160                    }
161    
162                    try {
163                            Layout duplicateLayout =
164                                    LayoutLocalServiceUtil.fetchLayoutByFriendlyURL(
165                                            layout.getGroupId(), layout.isPrivateLayout(),
166                                            newFriendlyURL);
167    
168                            if (duplicateLayout != null) {
169                                    throw new LayoutFriendlyURLException(
170                                            LayoutFriendlyURLException.DUPLICATE);
171                            }
172    
173                            layout.setFriendlyURL(newFriendlyURL);
174    
175                            LayoutLocalServiceUtil.updateLayout(layout);
176                    }
177                    catch (LayoutFriendlyURLException lfurle) {
178                            int type = lfurle.getType();
179    
180                            if (type == LayoutFriendlyURLException.DUPLICATE) {
181                                    return true;
182                            }
183                            else {
184                                    throw lfurle;
185                            }
186                    }
187    
188                    return false;
189            }
190    
191            protected void verifyLayoutPrototypeLinkEnabled() throws Exception {
192                    runSQL(
193                            "update Layout set layoutPrototypeLinkEnabled = [$FALSE$] where " +
194                                    "type_ = 'link_to_layout' and layoutPrototypeLinkEnabled = " +
195                                    "[$TRUE$]");
196            }
197    
198            protected void verifyUuid() throws Exception {
199                    verifyUuid("AssetEntry");
200                    verifyUuid("JournalArticle");
201    
202                    runSQL(
203                            "update Layout set uuid_ = sourcePrototypeLayoutUuid where " +
204                                    "sourcePrototypeLayoutUuid != '' and uuid_ != " +
205                                            "sourcePrototypeLayoutUuid");
206            }
207    
208            protected void verifyUuid(String tableName) throws Exception {
209                    StringBundler sb = new StringBundler(12);
210    
211                    sb.append("update ");
212                    sb.append(tableName);
213                    sb.append(" set layoutUuid = (select distinct ");
214                    sb.append("sourcePrototypeLayoutUuid from Layout where ");
215                    sb.append("Layout.uuid_ = ");
216                    sb.append(tableName);
217                    sb.append(".layoutUuid) where exists (select 1 from Layout where ");
218                    sb.append("Layout.uuid_ = ");
219                    sb.append(tableName);
220                    sb.append(".layoutUuid and Layout.uuid_ != ");
221                    sb.append("Layout.sourcePrototypeLayoutUuid and ");
222                    sb.append("Layout.sourcePrototypeLayoutUuid != '')");
223    
224                    runSQL(sb.toString());
225            }
226    
227            private static final Log _log = LogFactoryUtil.getLog(VerifyLayout.class);
228    
229    }