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