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.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.dao.orm.DynamicQuery;
022    import com.liferay.portal.kernel.dao.orm.Property;
023    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
024    import com.liferay.portal.kernel.dao.orm.QueryUtil;
025    import com.liferay.portal.kernel.exception.PortalException;
026    import com.liferay.portal.kernel.log.Log;
027    import com.liferay.portal.kernel.log.LogFactoryUtil;
028    import com.liferay.portal.kernel.util.CharPool;
029    import com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.HtmlUtil;
032    import com.liferay.portal.kernel.util.HttpUtil;
033    import com.liferay.portal.kernel.util.StringPool;
034    import com.liferay.portal.kernel.util.StringUtil;
035    import com.liferay.portal.kernel.workflow.WorkflowConstants;
036    import com.liferay.portal.kernel.xml.Document;
037    import com.liferay.portal.kernel.xml.Element;
038    import com.liferay.portal.kernel.xml.Node;
039    import com.liferay.portal.kernel.xml.SAXReaderUtil;
040    import com.liferay.portal.service.ResourceLocalServiceUtil;
041    import com.liferay.portal.util.PortalInstances;
042    import com.liferay.portlet.PortletPreferencesFactoryUtil;
043    import com.liferay.portlet.asset.model.AssetEntry;
044    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
045    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
046    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
047    import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
048    import com.liferay.portlet.dynamicdatamapping.util.DDMFieldsCounter;
049    import com.liferay.portlet.journal.model.JournalArticle;
050    import com.liferay.portlet.journal.model.JournalArticleConstants;
051    import com.liferay.portlet.journal.model.JournalArticleImage;
052    import com.liferay.portlet.journal.model.JournalArticleResource;
053    import com.liferay.portlet.journal.model.JournalContentSearch;
054    import com.liferay.portlet.journal.model.JournalFolder;
055    import com.liferay.portlet.journal.service.JournalArticleImageLocalServiceUtil;
056    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
057    import com.liferay.portlet.journal.service.JournalArticleResourceLocalServiceUtil;
058    import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
059    import com.liferay.portlet.journal.service.JournalFolderLocalServiceUtil;
060    import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
061    
062    import java.sql.Connection;
063    import java.sql.PreparedStatement;
064    import java.sql.ResultSet;
065    
066    import java.util.Date;
067    import java.util.List;
068    import java.util.regex.Pattern;
069    
070    import javax.portlet.PortletPreferences;
071    
072    /**
073     * @author Alexander Chow
074     * @author Shinn Lok
075     */
076    public class VerifyJournal extends VerifyProcess {
077    
078            public static final long DEFAULT_GROUP_ID = 14;
079    
080            public static final int NUM_OF_ARTICLES = 5;
081    
082            @Override
083            protected void doVerify() throws Exception {
084                    verifyArticleAssets();
085                    verifyArticleContents();
086                    verifyArticleStructures();
087                    verifyContentSearch();
088                    verifyFolderAssets();
089                    verifyOracleNewLine();
090                    verifyPermissions();
091                    verifyTree();
092                    verifyURLTitle();
093            }
094    
095            protected void updateContentSearch(long groupId, String portletId)
096                    throws Exception {
097    
098                    Connection con = null;
099                    PreparedStatement ps = null;
100                    ResultSet rs = null;
101    
102                    try {
103                            con = DataAccess.getUpgradeOptimizedConnection();
104    
105                            ps = con.prepareStatement(
106                                    "select preferences from PortletPreferences inner join " +
107                                            "Layout on PortletPreferences.plid = Layout.plid where " +
108                                                    "groupId = ? and portletId = ?");
109    
110                            ps.setLong(1, groupId);
111                            ps.setString(2, portletId);
112    
113                            rs = ps.executeQuery();
114    
115                            while (rs.next()) {
116                                    String xml = rs.getString("preferences");
117    
118                                    PortletPreferences portletPreferences =
119                                            PortletPreferencesFactoryUtil.fromDefaultXML(xml);
120    
121                                    String articleId = portletPreferences.getValue(
122                                            "articleId", null);
123    
124                                    List<JournalContentSearch> contentSearches =
125                                            JournalContentSearchLocalServiceUtil.
126                                                    getArticleContentSearches(groupId, articleId);
127    
128                                    if (contentSearches.isEmpty()) {
129                                            continue;
130                                    }
131    
132                                    JournalContentSearch contentSearch = contentSearches.get(0);
133    
134                                    JournalContentSearchLocalServiceUtil.updateContentSearch(
135                                            contentSearch.getGroupId(), contentSearch.isPrivateLayout(),
136                                            contentSearch.getLayoutId(), contentSearch.getPortletId(),
137                                            articleId, true);
138                            }
139                    }
140                    finally {
141                            DataAccess.cleanUp(con, ps, rs);
142                    }
143            }
144    
145            protected void updateCreateAndModifiedDates() throws Exception {
146                    ActionableDynamicQuery actionableDynamicQuery =
147                            JournalArticleResourceLocalServiceUtil.getActionableDynamicQuery();
148    
149                    if (_log.isDebugEnabled()) {
150                            long count = actionableDynamicQuery.performCount();
151    
152                            _log.debug(
153                                    "Processing " + count +
154                                            " article resources for create and modified dates");
155                    }
156    
157                    actionableDynamicQuery.setPerformActionMethod(
158                            new ActionableDynamicQuery.PerformActionMethod() {
159    
160                                    @Override
161                                    public void performAction(Object object) {
162                                            JournalArticleResource articleResource =
163                                                    (JournalArticleResource)object;
164    
165                                            updateCreateDate(articleResource);
166                                            updateModifiedDate(articleResource);
167                                    }
168    
169                            });
170    
171                    actionableDynamicQuery.performActions();
172    
173                    if (_log.isDebugEnabled()) {
174                            _log.debug("Create and modified dates verified for articles");
175                    }
176            }
177    
178            protected void updateCreateDate(JournalArticleResource articleResource) {
179                    List<JournalArticle> articles =
180                            JournalArticleLocalServiceUtil.getArticles(
181                                    articleResource.getGroupId(), articleResource.getArticleId(),
182                                    QueryUtil.ALL_POS, QueryUtil.ALL_POS,
183                                    new ArticleVersionComparator(true));
184    
185                    if (articles.size() <= 1) {
186                            return;
187                    }
188    
189                    JournalArticle firstArticle = articles.get(0);
190    
191                    Date createDate = firstArticle.getCreateDate();
192    
193                    for (JournalArticle article : articles) {
194                            if (!createDate.equals(article.getCreateDate())) {
195                                    article.setCreateDate(createDate);
196    
197                                    JournalArticleLocalServiceUtil.updateJournalArticle(article);
198                            }
199                    }
200            }
201    
202            protected void updateDocumentLibraryElements(Element element) {
203                    Element dynamicContentElement = element.element("dynamic-content");
204    
205                    String path = dynamicContentElement.getStringValue();
206    
207                    String[] pathArray = StringUtil.split(path, CharPool.SLASH);
208    
209                    if (pathArray.length != 5) {
210                            return;
211                    }
212    
213                    long groupId = GetterUtil.getLong(pathArray[2]);
214                    long folderId = GetterUtil.getLong(pathArray[3]);
215                    String title = HttpUtil.decodeURL(HtmlUtil.escape(pathArray[4]));
216    
217                    DLFileEntry dlFileEntry = DLFileEntryLocalServiceUtil.fetchFileEntry(
218                            groupId, folderId, title);
219    
220                    if (dlFileEntry == null) {
221                            return;
222                    }
223    
224                    Node node = dynamicContentElement.node(0);
225    
226                    node.setText(path + StringPool.SLASH + dlFileEntry.getUuid());
227            }
228    
229            protected void updateDynamicElements(JournalArticle article)
230                    throws Exception {
231    
232                    Document document = SAXReaderUtil.read(article.getContent());
233    
234                    Element rootElement = document.getRootElement();
235    
236                    updateDynamicElements(rootElement.elements("dynamic-element"));
237    
238                    article.setContent(document.asXML());
239    
240                    JournalArticleLocalServiceUtil.updateJournalArticle(article);
241            }
242    
243            protected void updateDynamicElements(List<Element> dynamicElements)
244                    throws PortalException {
245    
246                    DDMFieldsCounter ddmFieldsCounter = new DDMFieldsCounter();
247    
248                    for (Element dynamicElement : dynamicElements) {
249                            updateDynamicElements(dynamicElement.elements("dynamic-element"));
250    
251                            String name = dynamicElement.attributeValue("name");
252    
253                            int index = ddmFieldsCounter.get(name);
254    
255                            dynamicElement.addAttribute("index", String.valueOf(index));
256    
257                            String type = dynamicElement.attributeValue("type");
258    
259                            if (type.equals("image")) {
260                                    updateImageElement(dynamicElement, name, index);
261                            }
262    
263                            ddmFieldsCounter.incrementKey(name);
264                    }
265            }
266    
267            protected void updateElement(long groupId, Element element) {
268                    List<Element> dynamicElementElements = element.elements(
269                            "dynamic-element");
270    
271                    for (Element dynamicElementElement : dynamicElementElements) {
272                            updateElement(groupId, dynamicElementElement);
273                    }
274    
275                    String type = element.attributeValue("type");
276    
277                    if (type.equals("document_library")) {
278                            updateDocumentLibraryElements(element);
279                    }
280                    else if (type.equals("link_to_layout")) {
281                            updateLinkToLayoutElements(groupId, element);
282                    }
283            }
284    
285            protected void updateImageElement(Element element, String name, int index)
286                    throws PortalException {
287    
288                    Element dynamicContentElement = element.element("dynamic-content");
289    
290                    long articleImageId = GetterUtil.getLong(
291                            dynamicContentElement.attributeValue("id"));
292    
293                    JournalArticleImage articleImage =
294                            JournalArticleImageLocalServiceUtil.getArticleImage(articleImageId);
295    
296                    articleImage.setElName(name + StringPool.UNDERLINE + index);
297    
298                    JournalArticleImageLocalServiceUtil.updateJournalArticleImage(
299                            articleImage);
300            }
301    
302            protected void updateLinkToLayoutElements(long groupId, Element element) {
303                    Element dynamicContentElement = element.element("dynamic-content");
304    
305                    Node node = dynamicContentElement.node(0);
306    
307                    String text = node.getText();
308    
309                    if (!text.isEmpty() && !text.endsWith(StringPool.AT + groupId)) {
310                            node.setText(
311                                    dynamicContentElement.getStringValue() + StringPool.AT +
312                                            groupId);
313                    }
314            }
315    
316            protected void updateModifiedDate(JournalArticleResource articleResource) {
317                    JournalArticle article =
318                            JournalArticleLocalServiceUtil.fetchLatestArticle(
319                                    articleResource.getResourcePrimKey(),
320                                    WorkflowConstants.STATUS_APPROVED, true);
321    
322                    if (article == null) {
323                            return;
324                    }
325    
326                    AssetEntry assetEntry = AssetEntryLocalServiceUtil.fetchEntry(
327                            articleResource.getGroupId(), articleResource.getUuid());
328    
329                    if (assetEntry == null) {
330                            return;
331                    }
332    
333                    Date modifiedDate = article.getModifiedDate();
334    
335                    if (modifiedDate.equals(assetEntry.getModifiedDate())) {
336                            return;
337                    }
338    
339                    article.setModifiedDate(assetEntry.getModifiedDate());
340    
341                    JournalArticleLocalServiceUtil.updateJournalArticle(article);
342            }
343    
344            protected void updateResourcePrimKey() throws PortalException {
345                    ActionableDynamicQuery actionableDynamicQuery =
346                            JournalArticleLocalServiceUtil.getActionableDynamicQuery();
347    
348                    actionableDynamicQuery.setAddCriteriaMethod(
349                            new ActionableDynamicQuery.AddCriteriaMethod() {
350    
351                                    @Override
352                                    public void addCriteria(DynamicQuery dynamicQuery) {
353                                            Property resourcePrimKey = PropertyFactoryUtil.forName(
354                                                    "resourcePrimKey");
355    
356                                            dynamicQuery.add(resourcePrimKey.le(0l));
357                                    }
358    
359                            }
360                    );
361    
362                    if (_log.isDebugEnabled()) {
363                            long count = actionableDynamicQuery.performCount();
364    
365                            _log.debug(
366                                    "Processing " + count +
367                                            " default article versions in draft mode");
368                    }
369    
370                    actionableDynamicQuery.setPerformActionMethod(
371                            new ActionableDynamicQuery.PerformActionMethod() {
372    
373                                    @Override
374                                    public void performAction(Object object)
375                                            throws PortalException {
376    
377                                            JournalArticle article = (JournalArticle)object;
378    
379                                            long groupId = article.getGroupId();
380                                            String articleId = article.getArticleId();
381                                            double version = article.getVersion();
382    
383                                            JournalArticleLocalServiceUtil.checkArticleResourcePrimKey(
384                                                    groupId, articleId, version);
385                                    }
386    
387                            });
388    
389                    actionableDynamicQuery.performActions();
390            }
391    
392            protected void updateURLTitle(
393                            long groupId, String articleId, String urlTitle)
394                    throws Exception {
395    
396                    String normalizedURLTitle = FriendlyURLNormalizerUtil.normalize(
397                            urlTitle, _friendlyURLPattern);
398    
399                    if (urlTitle.equals(normalizedURLTitle)) {
400                            return;
401                    }
402    
403                    normalizedURLTitle = JournalArticleLocalServiceUtil.getUniqueUrlTitle(
404                            groupId, articleId, normalizedURLTitle);
405    
406                    Connection con = null;
407                    PreparedStatement ps = null;
408    
409                    try {
410                            con = DataAccess.getUpgradeOptimizedConnection();
411    
412                            ps = con.prepareStatement(
413                                    "update JournalArticle set urlTitle = ? where urlTitle = ?");
414    
415                            ps.setString(1, normalizedURLTitle);
416                            ps.setString(2, urlTitle);
417    
418                            ps.executeUpdate();
419                    }
420                    finally {
421                            DataAccess.cleanUp(con, ps);
422                    }
423            }
424    
425            protected void verifyArticleAssets() throws Exception {
426                    List<JournalArticle> journalArticles =
427                            JournalArticleLocalServiceUtil.getNoAssetArticles();
428    
429                    if (_log.isDebugEnabled()) {
430                            _log.debug(
431                                    "Processing " + journalArticles.size() +
432                                            " articles with no asset");
433                    }
434    
435                    for (JournalArticle journalArticle : journalArticles) {
436                            try {
437                                    JournalArticleLocalServiceUtil.updateAsset(
438                                            journalArticle.getUserId(), journalArticle, null, null,
439                                            null);
440                            }
441                            catch (Exception e) {
442                                    if (_log.isWarnEnabled()) {
443                                            _log.warn(
444                                                    "Unable to update asset for article " +
445                                                            journalArticle.getId() + ": " + e.getMessage());
446                                    }
447                            }
448                    }
449    
450                    ActionableDynamicQuery actionableDynamicQuery =
451                            JournalArticleLocalServiceUtil.getActionableDynamicQuery();
452    
453                    actionableDynamicQuery.setAddCriteriaMethod(
454                            new ActionableDynamicQuery.AddCriteriaMethod() {
455    
456                                    @Override
457                                    public void addCriteria(DynamicQuery dynamicQuery) {
458                                            Property versionProperty = PropertyFactoryUtil.forName(
459                                                    "version");
460    
461                                            dynamicQuery.add(
462                                                    versionProperty.eq(
463                                                            JournalArticleConstants.VERSION_DEFAULT));
464    
465                                            Property statusProperty = PropertyFactoryUtil.forName(
466                                                    "status");
467    
468                                            dynamicQuery.add(
469                                                    statusProperty.eq(WorkflowConstants.STATUS_DRAFT));
470                                    }
471    
472                            });
473    
474                    if (_log.isDebugEnabled()) {
475                            long count = actionableDynamicQuery.performCount();
476    
477                            _log.debug(
478                                    "Processing " + count +
479                                            " default article versions in draft mode");
480                    }
481    
482                    actionableDynamicQuery.setPerformActionMethod(
483                            new ActionableDynamicQuery.PerformActionMethod() {
484    
485                                    @Override
486                                    public void performAction(Object object)
487                                            throws PortalException {
488    
489                                            JournalArticle article = (JournalArticle)object;
490    
491                                            AssetEntry assetEntry =
492                                                    AssetEntryLocalServiceUtil.fetchEntry(
493                                                            JournalArticle.class.getName(),
494                                                            article.getResourcePrimKey());
495    
496                                            AssetEntryLocalServiceUtil.updateEntry(
497                                                    assetEntry.getClassName(), assetEntry.getClassPK(),
498                                                    null, assetEntry.isVisible());
499                                    }
500    
501                            });
502    
503                    actionableDynamicQuery.performActions();
504    
505                    if (_log.isDebugEnabled()) {
506                            _log.debug("Assets verified for articles");
507                    }
508    
509                    updateCreateAndModifiedDates();
510                    updateResourcePrimKey();
511            }
512    
513            protected void verifyArticleContents() throws Exception {
514                    Connection con = null;
515                    PreparedStatement ps = null;
516                    ResultSet rs = null;
517    
518                    try {
519                            con = DataAccess.getUpgradeOptimizedConnection();
520    
521                            ps = con.prepareStatement(
522                                    "select id_ from JournalArticle where (content like " +
523                                            "'%document_library%' or content like '%link_to_layout%')" +
524                                                    " and DDMStructureKey != ''");
525    
526                            rs = ps.executeQuery();
527    
528                            while (rs.next()) {
529                                    long id = rs.getLong("id_");
530    
531                                    JournalArticle article =
532                                            JournalArticleLocalServiceUtil.getArticle(id);
533    
534                                    Document document = SAXReaderUtil.read(article.getContent());
535    
536                                    Element rootElement = document.getRootElement();
537    
538                                    for (Element element : rootElement.elements()) {
539                                            updateElement(article.getGroupId(), element);
540                                    }
541    
542                                    article.setContent(document.asXML());
543    
544                                    JournalArticleLocalServiceUtil.updateJournalArticle(article);
545                            }
546                    }
547                    finally {
548                            DataAccess.cleanUp(con, ps, rs);
549                    }
550            }
551    
552            protected void verifyArticleStructures() throws PortalException {
553                    ActionableDynamicQuery actionableDynamicQuery =
554                            JournalArticleLocalServiceUtil.getActionableDynamicQuery();
555    
556                    if (_log.isDebugEnabled()) {
557                            long count = actionableDynamicQuery.performCount();
558    
559                            _log.debug(
560                                    "Processing " + count + " articles for invalid structures " +
561                                            "and dynamic elements");
562                    }
563    
564                    actionableDynamicQuery.setPerformActionMethod(
565                            new ActionableDynamicQuery.PerformActionMethod() {
566    
567                                    @Override
568                                    public void performAction(Object object) {
569                                            JournalArticle article = (JournalArticle)object;
570    
571                                            try {
572                                                    JournalArticleLocalServiceUtil.checkStructure(
573                                                            article.getGroupId(), article.getArticleId(),
574                                                            article.getVersion());
575                                            }
576                                            catch (NoSuchStructureException nsse) {
577                                                    if (_log.isWarnEnabled()) {
578                                                            _log.warn(
579                                                                    "Removing reference to missing structure for " +
580                                                                            "article " + article.getId());
581                                                    }
582    
583                                                    article.setDDMStructureKey(StringPool.BLANK);
584                                                    article.setDDMTemplateKey(StringPool.BLANK);
585    
586                                                    JournalArticleLocalServiceUtil.updateJournalArticle(
587                                                            article);
588                                            }
589                                            catch (Exception e) {
590                                                    _log.error(
591                                                            "Unable to check the structure for article " +
592                                                                    article.getId(),
593                                                            e);
594                                            }
595    
596                                            try {
597                                                    updateDynamicElements(article);
598                                            }
599                                            catch (Exception e) {
600                                                    _log.error(
601                                                            "Unable to update content for article " +
602                                                                    article.getId(),
603                                                            e);
604                                            }
605                                    }
606    
607                            });
608    
609                    actionableDynamicQuery.performActions();
610            }
611    
612            protected void verifyContentSearch() throws Exception {
613                    Connection con = null;
614                    PreparedStatement ps = null;
615                    ResultSet rs = null;
616    
617                    try {
618                            con = DataAccess.getUpgradeOptimizedConnection();
619    
620                            ps = con.prepareStatement(
621                                    "select groupId, portletId from JournalContentSearch group " +
622                                            "by groupId, portletId having count(groupId) > 1 and " +
623                                                    "count(portletId) > 1");
624    
625                            rs = ps.executeQuery();
626    
627                            while (rs.next()) {
628                                    long groupId = rs.getLong("groupId");
629                                    String portletId = rs.getString("portletId");
630    
631                                    updateContentSearch(groupId, portletId);
632                            }
633                    }
634                    finally {
635                            DataAccess.cleanUp(con, ps, rs);
636                    }
637            }
638    
639            protected void verifyFolderAssets() throws Exception {
640                    List<JournalFolder> folders =
641                            JournalFolderLocalServiceUtil.getNoAssetFolders();
642    
643                    if (_log.isDebugEnabled()) {
644                            _log.debug(
645                                    "Processing " + folders.size() + " folders with no asset");
646                    }
647    
648                    for (JournalFolder folder : folders) {
649                            try {
650                                    JournalFolderLocalServiceUtil.updateAsset(
651                                            folder.getUserId(), folder, null, null, null);
652                            }
653                            catch (Exception e) {
654                                    if (_log.isWarnEnabled()) {
655                                            _log.warn(
656                                                    "Unable to update asset for folder " +
657                                                            folder.getFolderId() + ": " + e.getMessage());
658                                    }
659                            }
660                    }
661    
662                    if (_log.isDebugEnabled()) {
663                            _log.debug("Assets verified for folders");
664                    }
665            }
666    
667            protected void verifyOracleNewLine() throws Exception {
668                    DB db = DBFactoryUtil.getDB();
669    
670                    String dbType = db.getType();
671    
672                    if (!dbType.equals(DB.TYPE_ORACLE)) {
673                            return;
674                    }
675    
676                    // This is a workaround for a limitation in Oracle sqlldr's inability
677                    // insert new line characters for long varchar columns. See
678                    // http://forums.liferay.com/index.php?showtopic=2761&hl=oracle for more
679                    // information. Check several articles because some articles may not
680                    // have new lines.
681    
682                    boolean checkNewLine = false;
683    
684                    List<JournalArticle> articles =
685                            JournalArticleLocalServiceUtil.getArticles(
686                                    DEFAULT_GROUP_ID, 0, NUM_OF_ARTICLES);
687    
688                    for (JournalArticle article : articles) {
689                            String content = article.getContent();
690    
691                            if ((content != null) && content.contains("\\n")) {
692                                    articles = JournalArticleLocalServiceUtil.getArticles(
693                                            DEFAULT_GROUP_ID);
694    
695                                    for (int j = 0; j < articles.size(); j++) {
696                                            article = articles.get(j);
697    
698                                            JournalArticleLocalServiceUtil.checkNewLine(
699                                                    article.getGroupId(), article.getArticleId(),
700                                                    article.getVersion());
701                                    }
702    
703                                    checkNewLine = true;
704    
705                                    break;
706                            }
707                    }
708    
709                    // Only process this once
710    
711                    if (!checkNewLine) {
712                            if (_log.isInfoEnabled()) {
713                                    _log.info("Do not fix oracle new line");
714                            }
715    
716                            return;
717                    }
718                    else {
719                            if (_log.isInfoEnabled()) {
720                                    _log.info("Fix oracle new line");
721                            }
722                    }
723            }
724    
725            protected void verifyPermissions() throws PortalException {
726                    List<JournalArticle> articles =
727                            JournalArticleLocalServiceUtil.getNoPermissionArticles();
728    
729                    for (JournalArticle article : articles) {
730                            ResourceLocalServiceUtil.addResources(
731                                    article.getCompanyId(), 0, 0, JournalArticle.class.getName(),
732                                    article.getResourcePrimKey(), false, false, false);
733                    }
734            }
735    
736            protected void verifyTree() throws Exception {
737                    long[] companyIds = PortalInstances.getCompanyIdsBySQL();
738    
739                    for (long companyId : companyIds) {
740                            JournalFolderLocalServiceUtil.rebuildTree(companyId);
741                    }
742            }
743    
744            protected void verifyURLTitle() throws Exception {
745                    Connection con = null;
746                    PreparedStatement ps = null;
747                    ResultSet rs = null;
748    
749                    try {
750                            con = DataAccess.getUpgradeOptimizedConnection();
751    
752                            ps = con.prepareStatement(
753                                    "select distinct groupId, articleId, urlTitle from " +
754                                            "JournalArticle");
755    
756                            rs = ps.executeQuery();
757    
758                            while (rs.next()) {
759                                    long groupId = rs.getLong("groupId");
760                                    String articleId = rs.getString("articleId");
761                                    String urlTitle = GetterUtil.getString(
762                                            rs.getString("urlTitle"));
763    
764                                    updateURLTitle(groupId, articleId, urlTitle);
765                            }
766                    }
767                    finally {
768                            DataAccess.cleanUp(con, ps, rs);
769                    }
770            }
771    
772            private static Log _log = LogFactoryUtil.getLog(VerifyJournal.class);
773    
774            private static Pattern _friendlyURLPattern = Pattern.compile("[^a-z0-9_-]");
775    
776    }