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.db.DB;
018    import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
019    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
020    import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
021    import com.liferay.portal.kernel.exception.PortalException;
022    import com.liferay.portal.kernel.exception.SystemException;
023    import com.liferay.portal.kernel.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.util.GetterUtil;
026    import com.liferay.portal.kernel.util.HtmlUtil;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.kernel.workflow.WorkflowConstants;
029    import com.liferay.portal.service.ResourceLocalServiceUtil;
030    import com.liferay.portlet.PortletPreferencesFactoryUtil;
031    import com.liferay.portlet.asset.NoSuchEntryException;
032    import com.liferay.portlet.asset.model.AssetEntry;
033    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
034    import com.liferay.portlet.journal.model.JournalArticle;
035    import com.liferay.portlet.journal.model.JournalArticleConstants;
036    import com.liferay.portlet.journal.model.JournalContentSearch;
037    import com.liferay.portlet.journal.model.JournalFolder;
038    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
039    import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
040    import com.liferay.portlet.journal.service.JournalFolderLocalServiceUtil;
041    import com.liferay.portlet.journal.service.persistence.JournalArticleActionableDynamicQuery;
042    
043    import java.sql.Connection;
044    import java.sql.PreparedStatement;
045    import java.sql.ResultSet;
046    
047    import java.util.List;
048    
049    import javax.portlet.PortletPreferences;
050    
051    /**
052     * @author Alexander Chow
053     * @author Shinn Lok
054     */
055    public class VerifyJournal extends VerifyProcess {
056    
057            public static final long DEFAULT_GROUP_ID = 14;
058    
059            public static final int NUM_OF_ARTICLES = 5;
060    
061            @Override
062            protected void doVerify() throws Exception {
063                    updateFolderAssets();
064                    verifyOracleNewLine();
065                    verifyPermissionsAndAssets();
066                    verifySearch();
067            }
068    
069            protected void updateFolderAssets() throws Exception {
070                    List<JournalFolder> folders =
071                            JournalFolderLocalServiceUtil.getNoAssetFolders();
072    
073                    if (_log.isDebugEnabled()) {
074                            _log.debug(
075                                    "Processing " + folders.size() + " folders with no asset");
076                    }
077    
078                    for (JournalFolder folder : folders) {
079                            try {
080                                    JournalFolderLocalServiceUtil.updateAsset(
081                                            folder.getUserId(), folder, null, null, null);
082                            }
083                            catch (Exception e) {
084                                    if (_log.isWarnEnabled()) {
085                                            _log.warn(
086                                                    "Unable to update asset for folder " +
087                                                            folder.getFolderId() + ": " + e.getMessage());
088                                    }
089                            }
090                    }
091    
092                    if (_log.isDebugEnabled()) {
093                            _log.debug("Assets verified for folders");
094                    }
095            }
096    
097            protected void verifyContentSearch(long groupId, String portletId)
098                    throws Exception {
099    
100                    Connection con = null;
101                    PreparedStatement ps = null;
102                    ResultSet rs = null;
103    
104                    try {
105                            con = DataAccess.getUpgradeOptimizedConnection();
106    
107                            ps = con.prepareStatement(
108                                    "select preferences from PortletPreferences inner join " +
109                                            "Layout on PortletPreferences.plid = Layout.plid where " +
110                                                    "groupId = ? and portletId = ?");
111    
112                            ps.setLong(1, groupId);
113                            ps.setString(2, portletId);
114    
115                            rs = ps.executeQuery();
116    
117                            while (rs.next()) {
118                                    String xml = rs.getString("preferences");
119    
120                                    PortletPreferences portletPreferences =
121                                            PortletPreferencesFactoryUtil.fromDefaultXML(xml);
122    
123                                    String articleId = portletPreferences.getValue(
124                                            "articleId", null);
125    
126                                    List<JournalContentSearch> contentSearches =
127                                            JournalContentSearchLocalServiceUtil.
128                                                    getArticleContentSearches(groupId, articleId);
129    
130                                    if (contentSearches.isEmpty()) {
131                                            continue;
132                                    }
133    
134                                    JournalContentSearch contentSearch = contentSearches.get(0);
135    
136                                    JournalContentSearchLocalServiceUtil.updateContentSearch(
137                                            contentSearch.getGroupId(), contentSearch.isPrivateLayout(),
138                                            contentSearch.getLayoutId(), contentSearch.getPortletId(),
139                                            articleId, true);
140                            }
141                    }
142                    finally {
143                            DataAccess.cleanUp(con, ps, rs);
144                    }
145            }
146    
147            protected void verifyOracleNewLine() throws Exception {
148                    DB db = DBFactoryUtil.getDB();
149    
150                    String dbType = db.getType();
151    
152                    if (!dbType.equals(DB.TYPE_ORACLE)) {
153                            return;
154                    }
155    
156                    // This is a workaround for a limitation in Oracle sqlldr's inability
157                    // insert new line characters for long varchar columns. See
158                    // http://forums.liferay.com/index.php?showtopic=2761&hl=oracle for more
159                    // information. Check several articles because some articles may not
160                    // have new lines.
161    
162                    boolean checkNewLine = false;
163    
164                    List<JournalArticle> articles =
165                            JournalArticleLocalServiceUtil.getArticles(
166                                    DEFAULT_GROUP_ID, 0, NUM_OF_ARTICLES);
167    
168                    for (JournalArticle article : articles) {
169                            String content = article.getContent();
170    
171                            if ((content != null) && content.contains("\\n")) {
172                                    articles = JournalArticleLocalServiceUtil.getArticles(
173                                            DEFAULT_GROUP_ID);
174    
175                                    for (int j = 0; j < articles.size(); j++) {
176                                            article = articles.get(j);
177    
178                                            JournalArticleLocalServiceUtil.checkNewLine(
179                                                    article.getGroupId(), article.getArticleId(),
180                                                    article.getVersion());
181                                    }
182    
183                                    checkNewLine = true;
184    
185                                    break;
186                            }
187                    }
188    
189                    // Only process this once
190    
191                    if (!checkNewLine) {
192                            if (_log.isInfoEnabled()) {
193                                    _log.info("Do not fix oracle new line");
194                            }
195    
196                            return;
197                    }
198                    else {
199                            if (_log.isInfoEnabled()) {
200                                    _log.info("Fix oracle new line");
201                            }
202                    }
203    
204            }
205    
206            protected void verifyPermissionsAndAssets() throws Exception {
207                    ActionableDynamicQuery actionableDynamicQuery =
208                            new JournalArticleActionableDynamicQuery() {
209    
210                            @Override
211                            protected void performAction(Object object)
212                                    throws PortalException, SystemException {
213    
214                                    JournalArticle article = (JournalArticle)object;
215    
216                                    long groupId = article.getGroupId();
217                                    String articleId = article.getArticleId();
218                                    double version = article.getVersion();
219                                    String structureId = article.getStructureId();
220    
221                                    if (article.getResourcePrimKey() <= 0) {
222                                            article =
223                                                    JournalArticleLocalServiceUtil.
224                                                            checkArticleResourcePrimKey(
225                                                                    groupId, articleId, version);
226                                    }
227    
228                                    ResourceLocalServiceUtil.addResources(
229                                            article.getCompanyId(), 0, 0,
230                                            JournalArticle.class.getName(),
231                                            article.getResourcePrimKey(), false, false, false);
232    
233                                    try {
234                                            AssetEntry assetEntry = AssetEntryLocalServiceUtil.getEntry(
235                                                    JournalArticle.class.getName(),
236                                                    article.getResourcePrimKey());
237    
238                                            if ((article.getStatus() ==
239                                                            WorkflowConstants.STATUS_DRAFT) &&
240                                                    (article.getVersion() ==
241                                                            JournalArticleConstants.VERSION_DEFAULT)) {
242    
243                                                    AssetEntryLocalServiceUtil.updateEntry(
244                                                            assetEntry.getClassName(), assetEntry.getClassPK(),
245                                                            null, assetEntry.isVisible());
246                                            }
247                                    }
248                                    catch (NoSuchEntryException nsee) {
249                                            try {
250                                                    JournalArticleLocalServiceUtil.updateAsset(
251                                                            article.getUserId(), article, null, null, null);
252                                            }
253                                            catch (Exception e) {
254                                                    if (_log.isWarnEnabled()) {
255                                                            _log.warn(
256                                                                    "Unable to update asset for article " +
257                                                                            article.getId() + ": " + e.getMessage());
258                                                    }
259                                            }
260                                    }
261    
262                                    String content = GetterUtil.getString(article.getContent());
263    
264                                    String newContent = HtmlUtil.replaceMsWordCharacters(content);
265    
266                                    if (Validator.isNotNull(structureId)) {
267                                            /*JournalStructure structure =
268                                                    JournalStructureLocalServiceUtil.getStructure(
269                                                            groupId, structureId);
270    
271                                            newContent = JournalUtil.removeOldContent(
272                                                    newContent, structure.getXsd());*/
273                                    }
274    
275                                    if (!content.equals(newContent)) {
276                                            JournalArticleLocalServiceUtil.updateContent(
277                                                    groupId, articleId, version, newContent);
278                                    }
279    
280                                    JournalArticleLocalServiceUtil.checkStructure(
281                                            groupId, articleId, version);
282                            }
283    
284                    };
285    
286                    actionableDynamicQuery.performActions();
287    
288                    if (_log.isDebugEnabled()) {
289                            _log.debug("Permissions and assets verified for articles");
290                    }
291            }
292    
293            protected void verifySearch() throws Exception {
294                    Connection con = null;
295                    PreparedStatement ps = null;
296                    ResultSet rs = null;
297    
298                    try {
299                            con = DataAccess.getUpgradeOptimizedConnection();
300    
301                            ps = con.prepareStatement(
302                                    "select groupId, portletId from JournalContentSearch group " +
303                                            "by groupId, portletId having count(groupId) > 1 and " +
304                                                    "count(portletId) > 1");
305    
306                            rs = ps.executeQuery();
307    
308                            while (rs.next()) {
309                                    long groupId = rs.getLong("groupId");
310                                    String portletId = rs.getString("portletId");
311    
312                                    verifyContentSearch(groupId, portletId);
313                            }
314                    }
315                    finally {
316                            DataAccess.cleanUp(con, ps, rs);
317                    }
318            }
319    
320            private static Log _log = LogFactoryUtil.getLog(VerifyJournal.class);
321    
322    }