1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.verify;
24  
25  import com.liferay.portal.kernel.dao.jdbc.DataAccess;
26  import com.liferay.portal.kernel.log.Log;
27  import com.liferay.portal.kernel.log.LogFactoryUtil;
28  import com.liferay.portal.kernel.util.GetterUtil;
29  import com.liferay.portal.kernel.util.HtmlUtil;
30  import com.liferay.portal.service.ResourceLocalServiceUtil;
31  import com.liferay.portal.tools.sql.DBUtil;
32  import com.liferay.portlet.journal.model.JournalArticle;
33  import com.liferay.portlet.journal.model.JournalStructure;
34  import com.liferay.portlet.journal.model.JournalTemplate;
35  import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
36  import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;
37  import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
38  import com.liferay.portlet.tags.NoSuchAssetException;
39  import com.liferay.portlet.tags.service.TagsAssetLocalServiceUtil;
40  
41  import java.sql.Connection;
42  import java.sql.PreparedStatement;
43  import java.sql.ResultSet;
44  
45  import java.util.List;
46  
47  /**
48   * <a href="VerifyJournal.java.html"><b><i>View Source</i></b></a>
49   *
50   * @author Alexander Chow
51   *
52   */
53  public class VerifyJournal extends VerifyProcess {
54  
55      public static final long DEFAULT_GROUP_ID = 14;
56  
57      public static final int NUM_OF_ARTICLES = 5;
58  
59      public void verify() throws VerifyException {
60          _log.info("Verifying");
61  
62          try {
63              verifyJournal();
64          }
65          catch (Exception e) {
66              throw new VerifyException(e);
67          }
68      }
69  
70      protected void verifyOracleNewLine() throws Exception {
71          DBUtil dbUtil = DBUtil.getInstance();
72  
73          if (!dbUtil.getType().equals(DBUtil.TYPE_ORACLE)) {
74              return;
75          }
76  
77          // This is a workaround for a limitation in Oracle sqlldr's inability
78          // insert new line characters for long varchar columns. See
79          // http://forums.liferay.com/index.php?showtopic=2761&hl=oracle for more
80          // information. Check several articles because some articles may not
81          // have new lines.
82  
83          boolean checkNewLine = false;
84  
85          List<JournalArticle> articles = null;
86  
87          if (NUM_OF_ARTICLES <= 0) {
88              checkNewLine = true;
89  
90              articles = JournalArticleLocalServiceUtil.getArticles(
91                  DEFAULT_GROUP_ID);
92          }
93          else {
94              articles = JournalArticleLocalServiceUtil.getArticles(
95                  DEFAULT_GROUP_ID, 0, NUM_OF_ARTICLES);
96          }
97  
98          for (JournalArticle article : articles) {
99              String content = article.getContent();
100 
101             if ((content != null) && (content.indexOf("\\n") != -1)) {
102                 articles = JournalArticleLocalServiceUtil.getArticles(
103                     DEFAULT_GROUP_ID);
104 
105                 for (int j = 0; j < articles.size(); j++) {
106                     article = articles.get(j);
107 
108                     JournalArticleLocalServiceUtil.checkNewLine(
109                         article.getGroupId(), article.getArticleId(),
110                         article.getVersion());
111                 }
112 
113                 checkNewLine = true;
114 
115                 break;
116             }
117         }
118 
119         // Only process this once
120 
121         if (!checkNewLine) {
122             if (_log.isInfoEnabled()) {
123                 _log.debug("Do not fix oracle new line");
124             }
125 
126             return;
127         }
128         else {
129             if (_log.isInfoEnabled()) {
130                 _log.info("Fix oracle new line");
131             }
132         }
133 
134         List<JournalStructure> structures =
135             JournalStructureLocalServiceUtil.getStructures(
136                 DEFAULT_GROUP_ID, 0, 1);
137 
138         if (structures.size() == 1) {
139             JournalStructure structure = structures.get(0);
140 
141             String xsd = structure.getXsd();
142 
143             if ((xsd != null) && (xsd.indexOf("\\n") != -1)) {
144                 structures = JournalStructureLocalServiceUtil.getStructures(
145                     DEFAULT_GROUP_ID);
146 
147                 for (int i = 0; i < structures.size(); i++) {
148                     structure = structures.get(i);
149 
150                     JournalStructureLocalServiceUtil.checkNewLine(
151                         structure.getGroupId(), structure.getStructureId());
152                 }
153             }
154         }
155 
156         List<JournalTemplate> templates =
157             JournalTemplateLocalServiceUtil.getTemplates(
158                 DEFAULT_GROUP_ID, 0, 1);
159 
160         if (templates.size() == 1) {
161             JournalTemplate template = templates.get(0);
162 
163             String xsl = template.getXsl();
164 
165             if ((xsl != null) && (xsl.indexOf("\\n") != -1)) {
166                 templates = JournalTemplateLocalServiceUtil.getTemplates(
167                     DEFAULT_GROUP_ID);
168 
169                 for (int i = 0; i < templates.size(); i++) {
170                     template = templates.get(i);
171 
172                     JournalTemplateLocalServiceUtil.checkNewLine(
173                         template.getGroupId(), template.getTemplateId());
174                 }
175             }
176         }
177     }
178 
179     protected void verifyJournal() throws Exception {
180 
181         // Oracle new line
182 
183         verifyOracleNewLine();
184 
185         // Structures
186 
187         List<JournalStructure> structures =
188             JournalStructureLocalServiceUtil.getStructures();
189 
190         for (JournalStructure structure : structures) {
191             ResourceLocalServiceUtil.addResources(
192                 structure.getCompanyId(), 0, 0,
193                 JournalStructure.class.getName(), structure.getId(), false,
194                 true, true);
195         }
196 
197         if (_log.isDebugEnabled()) {
198             _log.debug("Permissions verified for Journal structures");
199         }
200 
201         // Templates
202 
203         List<JournalTemplate> templates =
204             JournalTemplateLocalServiceUtil.getTemplates();
205 
206         for (JournalTemplate template : templates) {
207             ResourceLocalServiceUtil.addResources(
208                 template.getCompanyId(), 0, 0,
209                 JournalTemplate.class.getName(), template.getId(), false, true,
210                 true);
211         }
212 
213         if (_log.isDebugEnabled()) {
214             _log.debug("Permissions verified for Journal templates");
215         }
216 
217         // Articles
218 
219         List<JournalArticle> articles =
220             JournalArticleLocalServiceUtil.getArticles();
221 
222         for (JournalArticle article : articles) {
223             long groupId = article.getGroupId();
224             String articleId = article.getArticleId();
225             double version = article.getVersion();
226             //String structureId = article.getStructureId();
227 
228             if (article.getResourcePrimKey() <= 0) {
229                 article =
230                     JournalArticleLocalServiceUtil.checkArticleResourcePrimKey(
231                         groupId, articleId, version);
232             }
233 
234             ResourceLocalServiceUtil.addResources(
235                 article.getCompanyId(), 0, 0, JournalArticle.class.getName(),
236                 article.getResourcePrimKey(), false, true, true);
237 
238             try {
239                 TagsAssetLocalServiceUtil.getAsset(
240                     JournalArticle.class.getName(),
241                     article.getResourcePrimKey());
242             }
243             catch (NoSuchAssetException nsae) {
244                 try {
245                     JournalArticleLocalServiceUtil.updateTagsAsset(
246                         article.getUserId(), article, new String[0]);
247                 }
248                 catch (Exception e) {
249                     if (_log.isWarnEnabled()) {
250                         _log.warn(
251                             "Unable to update tags asset for article " +
252                                 article.getId() + ": " + e.getMessage());
253                     }
254                 }
255             }
256 
257             String content = GetterUtil.getString(article.getContent());
258 
259             String newContent = HtmlUtil.replaceMsWordCharacters(content);
260 
261             /*if (Validator.isNotNull(structureId)) {
262                 JournalStructure structure =
263                     JournalStructureLocalServiceUtil.getStructure(
264                         groupId, structureId);
265 
266                 newContent = JournalUtil.removeOldContent(
267                     newContent, structure.getXsd());
268             }*/
269 
270             if (!content.equals(newContent)) {
271                 JournalArticleLocalServiceUtil.updateContent(
272                     groupId, articleId, version, newContent);
273             }
274 
275             JournalArticleLocalServiceUtil.checkStructure(
276                 groupId, articleId, version);
277 
278             //verifyStaleJournalArticle(article);
279         }
280 
281         if (_log.isDebugEnabled()) {
282             _log.debug(
283                 "Permissions and Tags assets verified for Journal articles");
284         }
285     }
286 
287     protected void verifyStaleJournalArticle(JournalArticle article)
288         throws Exception {
289 
290         long groupId = article.getGroupId();
291         String articleId = article.getArticleId();
292         double version = article.getVersion();
293 
294         if (article.getStructureId().equals("BASIC-RSS-ITEM")) {
295             return;
296         }
297 
298         long count = getPortletPreferencesCount(articleId);
299 
300         if (count == 0) {
301             if (_log.isWarnEnabled()) {
302                 _log.warn(
303                     "Article {groupId=" + groupId + ", articleId=" +
304                         articleId + ", version=" + version +
305                             "} is not used on any layouts");
306             }
307         }
308     }
309 
310     protected long getPortletPreferencesCount(String articleId)
311         throws Exception {
312 
313         Connection con = null;
314         PreparedStatement ps = null;
315         ResultSet rs = null;
316 
317         try {
318             con = DataAccess.getConnection();
319 
320             ps = con.prepareStatement(_GET_PORTLET_PREFERENCES_COUNT);
321 
322             ps.setString(
323                 1, "%<name>article-id</name><value>" + articleId + "</value>%");
324 
325             rs = ps.executeQuery();
326 
327             while (rs.next()) {
328                 long count = rs.getLong("count_value");
329 
330                 return count;
331             }
332         }
333         finally {
334             DataAccess.cleanUp(con, ps, rs);
335         }
336 
337         return 0;
338     }
339 
340     private static final String _GET_PORTLET_PREFERENCES_COUNT =
341         "select count(*) as count_value from PortletPreferences where " +
342             "ownerId = 0 and ownerType = 3 and portletId like " +
343                 "'56_INSTANCE_%' and preferences like ?";
344 
345     private static Log _log = LogFactoryUtil.getLog(VerifyJournal.class);
346 
347 }