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.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.HtmlUtil;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.service.ResourceLocalServiceUtil;
028    import com.liferay.portlet.PortletPreferencesFactoryUtil;
029    import com.liferay.portlet.asset.NoSuchEntryException;
030    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
031    import com.liferay.portlet.journal.model.JournalArticle;
032    import com.liferay.portlet.journal.model.JournalContentSearch;
033    import com.liferay.portlet.journal.model.JournalStructure;
034    import com.liferay.portlet.journal.model.JournalTemplate;
035    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
036    import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
037    import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;
038    import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
039    
040    import java.sql.Connection;
041    import java.sql.PreparedStatement;
042    import java.sql.ResultSet;
043    
044    import java.util.List;
045    
046    import javax.portlet.PortletPreferences;
047    
048    /**
049     * @author Alexander Chow
050     * @author Shinn Lok
051     */
052    public class VerifyJournal extends VerifyProcess {
053    
054            public static final long DEFAULT_GROUP_ID = 14;
055    
056            public static final int NUM_OF_ARTICLES = 5;
057    
058            @Override
059            protected void doVerify() throws Exception {
060    
061                    // Oracle new line
062    
063                    verifyOracleNewLine();
064    
065                    // Structures
066    
067                    List<JournalStructure> structures =
068                            JournalStructureLocalServiceUtil.getStructures();
069    
070                    for (JournalStructure structure : structures) {
071                            ResourceLocalServiceUtil.addResources(
072                                    structure.getCompanyId(), 0, 0,
073                                    JournalStructure.class.getName(), structure.getId(), false,
074                                    false, false);
075                    }
076    
077                    if (_log.isDebugEnabled()) {
078                            _log.debug("Permissions verified for structures");
079                    }
080    
081                    // Templates
082    
083                    List<JournalTemplate> templates =
084                            JournalTemplateLocalServiceUtil.getTemplates();
085    
086                    for (JournalTemplate template : templates) {
087                            ResourceLocalServiceUtil.addResources(
088                                    template.getCompanyId(), 0, 0, JournalTemplate.class.getName(),
089                                    template.getId(), false, false, false);
090                    }
091    
092                    if (_log.isDebugEnabled()) {
093                            _log.debug("Permissions verified for templates");
094                    }
095    
096                    // Articles
097    
098                    List<JournalArticle> articles =
099                            JournalArticleLocalServiceUtil.getArticles();
100    
101                    for (JournalArticle article : articles) {
102                            long groupId = article.getGroupId();
103                            String articleId = article.getArticleId();
104                            double version = article.getVersion();
105                            String structureId = article.getStructureId();
106    
107                            if (article.getResourcePrimKey() <= 0) {
108                                    article =
109                                            JournalArticleLocalServiceUtil.checkArticleResourcePrimKey(
110                                                    groupId, articleId, version);
111                            }
112    
113                            ResourceLocalServiceUtil.addResources(
114                                    article.getCompanyId(), 0, 0, JournalArticle.class.getName(),
115                                    article.getResourcePrimKey(), false, false, false);
116    
117                            try {
118                                    AssetEntryLocalServiceUtil.getEntry(
119                                            JournalArticle.class.getName(),
120                                            article.getResourcePrimKey());
121                            }
122                            catch (NoSuchEntryException nsee) {
123                                    try {
124                                            JournalArticleLocalServiceUtil.updateAsset(
125                                                    article.getUserId(), article, null, null, null);
126                                    }
127                                    catch (Exception e) {
128                                            if (_log.isWarnEnabled()) {
129                                                    _log.warn(
130                                                            "Unable to update asset for article " +
131                                                                    article.getId() + ": " + e.getMessage());
132                                            }
133                                    }
134                            }
135    
136                            String content = GetterUtil.getString(article.getContent());
137    
138                            String newContent = HtmlUtil.replaceMsWordCharacters(content);
139    
140                            if (Validator.isNotNull(structureId)) {
141                                    /*JournalStructure structure =
142                                            JournalStructureLocalServiceUtil.getStructure(
143                                                    groupId, structureId);
144    
145                                    newContent = JournalUtil.removeOldContent(
146                                            newContent, structure.getXsd());*/
147                            }
148    
149                            if (!content.equals(newContent)) {
150                                    JournalArticleLocalServiceUtil.updateContent(
151                                            groupId, articleId, version, newContent);
152                            }
153    
154                            JournalArticleLocalServiceUtil.checkStructure(
155                                    groupId, articleId, version);
156                    }
157    
158                    if (_log.isDebugEnabled()) {
159                            _log.debug("Permissions and assets verified for articles");
160                    }
161    
162                    // Content searches
163    
164                    verifyContentSearch();
165    
166                    // URL title
167    
168                    verifyURLTitle();
169            }
170    
171            protected void updateURLTitle(String urlTitle) throws Exception {
172                    Connection con = null;
173                    PreparedStatement ps = null;
174    
175                    try {
176                            con = DataAccess.getUpgradeOptimizedConnection();
177    
178                            ps = con.prepareStatement(
179                                    "update JournalArticle set urlTitle = ? where urlTitle = ?");
180    
181                            ps.setString(1, FriendlyURLNormalizerUtil.normalize(urlTitle));
182                            ps.setString(2, urlTitle);
183    
184                            ps.executeUpdate();
185                    }
186                    finally {
187                            DataAccess.cleanUp(con, ps);
188                    }
189            }
190    
191            protected void verifyContentSearch() throws Exception {
192                    Connection con = null;
193                    PreparedStatement ps = null;
194                    ResultSet rs = null;
195    
196                    try {
197                            con = DataAccess.getUpgradeOptimizedConnection();
198    
199                            ps = con.prepareStatement(
200                                    "select groupId, portletId from JournalContentSearch group " +
201                                            "by groupId, portletId having count(groupId) > 1 and " +
202                                                    "count(portletId) > 1");
203    
204                            rs = ps.executeQuery();
205    
206                            while (rs.next()) {
207                                    long groupId = rs.getLong("groupId");
208                                    String portletId = rs.getString("portletId");
209    
210                                    verifyContentSearch(groupId, portletId);
211                            }
212                    }
213                    finally {
214                            DataAccess.cleanUp(con, ps, rs);
215                    }
216            }
217    
218            protected void verifyContentSearch(long groupId, String portletId)
219                    throws Exception {
220    
221                    Connection con = null;
222                    PreparedStatement ps = null;
223                    ResultSet rs = null;
224    
225                    try {
226                            con = DataAccess.getUpgradeOptimizedConnection();
227    
228                            ps = con.prepareStatement(
229                                    "select preferences from PortletPreferences inner join " +
230                                            "Layout on PortletPreferences.plid = Layout.plid where " +
231                                                    "groupId = ? and portletId = ?");
232    
233                            ps.setLong(1, groupId);
234                            ps.setString(2, portletId);
235    
236                            rs = ps.executeQuery();
237    
238                            while (rs.next()) {
239                                    String xml = rs.getString("preferences");
240    
241                                    PortletPreferences portletPreferences =
242                                            PortletPreferencesFactoryUtil.fromDefaultXML(xml);
243    
244                                    String articleId = portletPreferences.getValue(
245                                            "articleId", null);
246    
247                                    List<JournalContentSearch> contentSearches =
248                                            JournalContentSearchLocalServiceUtil.
249                                                    getArticleContentSearches(groupId, articleId);
250    
251                                    if (contentSearches.isEmpty()) {
252                                            continue;
253                                    }
254    
255                                    JournalContentSearch contentSearch = contentSearches.get(0);
256    
257                                    JournalContentSearchLocalServiceUtil.updateContentSearch(
258                                            contentSearch.getGroupId(), contentSearch.isPrivateLayout(),
259                                            contentSearch.getLayoutId(), contentSearch.getPortletId(),
260                                            articleId, true);
261                            }
262                    }
263                    finally {
264                            DataAccess.cleanUp(con, ps, rs);
265                    }
266            }
267    
268            protected void verifyOracleNewLine() throws Exception {
269                    DB db = DBFactoryUtil.getDB();
270    
271                    String dbType = db.getType();
272    
273                    if (!dbType.equals(DB.TYPE_ORACLE)) {
274                            return;
275                    }
276    
277                    // This is a workaround for a limitation in Oracle sqlldr's inability
278                    // insert new line characters for long varchar columns. See
279                    // http://forums.liferay.com/index.php?showtopic=2761&hl=oracle for more
280                    // information. Check several articles because some articles may not
281                    // have new lines.
282    
283                    boolean checkNewLine = false;
284    
285                    List<JournalArticle> articles =
286                            JournalArticleLocalServiceUtil.getArticles(
287                                    DEFAULT_GROUP_ID, 0, NUM_OF_ARTICLES);
288    
289                    for (JournalArticle article : articles) {
290                            String content = article.getContent();
291    
292                            if ((content != null) && content.contains("\\n")) {
293                                    articles = JournalArticleLocalServiceUtil.getArticles(
294                                            DEFAULT_GROUP_ID);
295    
296                                    for (int j = 0; j < articles.size(); j++) {
297                                            article = articles.get(j);
298    
299                                            JournalArticleLocalServiceUtil.checkNewLine(
300                                                    article.getGroupId(), article.getArticleId(),
301                                                    article.getVersion());
302                                    }
303    
304                                    checkNewLine = true;
305    
306                                    break;
307                            }
308                    }
309    
310                    // Only process this once
311    
312                    if (!checkNewLine) {
313                            if (_log.isInfoEnabled()) {
314                                    _log.info("Do not fix oracle new line");
315                            }
316    
317                            return;
318                    }
319                    else {
320                            if (_log.isInfoEnabled()) {
321                                    _log.info("Fix oracle new line");
322                            }
323                    }
324    
325                    List<JournalStructure> structures =
326                            JournalStructureLocalServiceUtil.getStructures(
327                                    DEFAULT_GROUP_ID, 0, 1);
328    
329                    if (structures.size() == 1) {
330                            JournalStructure structure = structures.get(0);
331    
332                            String xsd = structure.getXsd();
333    
334                            if ((xsd != null) && xsd.contains("\\n")) {
335                                    structures = JournalStructureLocalServiceUtil.getStructures(
336                                            DEFAULT_GROUP_ID);
337    
338                                    for (int i = 0; i < structures.size(); i++) {
339                                            structure = structures.get(i);
340    
341                                            JournalStructureLocalServiceUtil.checkNewLine(
342                                                    structure.getGroupId(), structure.getStructureId());
343                                    }
344                            }
345                    }
346    
347                    List<JournalTemplate> templates =
348                            JournalTemplateLocalServiceUtil.getTemplates(
349                                    DEFAULT_GROUP_ID, 0, 1);
350    
351                    if (templates.size() == 1) {
352                            JournalTemplate template = templates.get(0);
353    
354                            String xsl = template.getXsl();
355    
356                            if ((xsl != null) && xsl.contains("\\n")) {
357                                    templates = JournalTemplateLocalServiceUtil.getTemplates(
358                                            DEFAULT_GROUP_ID);
359    
360                                    for (int i = 0; i < templates.size(); i++) {
361                                            template = templates.get(i);
362    
363                                            JournalTemplateLocalServiceUtil.checkNewLine(
364                                                    template.getGroupId(), template.getTemplateId());
365                                    }
366                            }
367                    }
368            }
369    
370            protected void verifyURLTitle() throws Exception {
371                    Connection con = null;
372                    PreparedStatement ps = null;
373                    ResultSet rs = null;
374    
375                    try {
376                            con = DataAccess.getUpgradeOptimizedConnection();
377    
378                            StringBundler sb = new StringBundler();
379    
380                            sb.append("select distinct urlTitle from JournalArticle where ");
381                            sb.append("urlTitle like '%\u00a3%' or urlTitle like '%\u2018%' ");
382                            sb.append("or urlTitle like '%\u2019%' or urlTitle like ");
383                            sb.append("'%\u201c%' or urlTitle like '%\u201d%'");
384    
385                            ps = con.prepareStatement(sb.toString());
386    
387                            rs = ps.executeQuery();
388    
389                            while (rs.next()) {
390                                    String urlTitle = rs.getString("urlTitle");
391    
392                                    updateURLTitle(urlTitle);
393                            }
394                    }
395                    finally {
396                            DataAccess.cleanUp(con, ps, rs);
397                    }
398            }
399    
400            private static Log _log = LogFactoryUtil.getLog(VerifyJournal.class);
401    
402    }