001
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.FriendlyURLNormalizerUtil;
026 import com.liferay.portal.kernel.util.GetterUtil;
027 import com.liferay.portal.kernel.util.HtmlUtil;
028 import com.liferay.portal.kernel.util.StringPool;
029 import com.liferay.portal.kernel.util.Validator;
030 import com.liferay.portal.kernel.workflow.WorkflowConstants;
031 import com.liferay.portal.service.ResourceLocalServiceUtil;
032 import com.liferay.portlet.PortletPreferencesFactoryUtil;
033 import com.liferay.portlet.asset.model.AssetEntry;
034 import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
035 import com.liferay.portlet.journal.NoSuchStructureException;
036 import com.liferay.portlet.journal.model.JournalArticle;
037 import com.liferay.portlet.journal.model.JournalArticleConstants;
038 import com.liferay.portlet.journal.model.JournalContentSearch;
039 import com.liferay.portlet.journal.model.JournalFolder;
040 import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
041 import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
042 import com.liferay.portlet.journal.service.JournalFolderLocalServiceUtil;
043 import com.liferay.portlet.journal.service.persistence.JournalArticleActionableDynamicQuery;
044
045 import java.sql.Connection;
046 import java.sql.PreparedStatement;
047 import java.sql.ResultSet;
048
049 import java.util.List;
050 import java.util.regex.Pattern;
051
052 import javax.portlet.PortletPreferences;
053
054
058 public class VerifyJournal extends VerifyProcess {
059
060 public static final long DEFAULT_GROUP_ID = 14;
061
062 public static final int NUM_OF_ARTICLES = 5;
063
064 @Override
065 protected void doVerify() throws Exception {
066 updateFolderAssets();
067 verifyOracleNewLine();
068 verifyPermissionsAndAssets();
069 verifySearch();
070 verifyURLTitle();
071 }
072
073 protected void updateFolderAssets() throws Exception {
074 List<JournalFolder> folders =
075 JournalFolderLocalServiceUtil.getNoAssetFolders();
076
077 if (_log.isDebugEnabled()) {
078 _log.debug(
079 "Processing " + folders.size() + " folders with no asset");
080 }
081
082 for (JournalFolder folder : folders) {
083 try {
084 JournalFolderLocalServiceUtil.updateAsset(
085 folder.getUserId(), folder, null, null, null);
086 }
087 catch (Exception e) {
088 if (_log.isWarnEnabled()) {
089 _log.warn(
090 "Unable to update asset for folder " +
091 folder.getFolderId() + ": " + e.getMessage());
092 }
093 }
094 }
095
096 if (_log.isDebugEnabled()) {
097 _log.debug("Assets verified for folders");
098 }
099 }
100
101 protected void updateURLTitle(
102 long groupId, String articleId, String urlTitle)
103 throws Exception {
104
105 String normalizedURLTitle = FriendlyURLNormalizerUtil.normalize(
106 urlTitle, _friendlyURLPattern);
107
108 if (urlTitle.equals(normalizedURLTitle)) {
109 return;
110 }
111
112 normalizedURLTitle = JournalArticleLocalServiceUtil.getUniqueUrlTitle(
113 groupId, articleId, normalizedURLTitle);
114
115 Connection con = null;
116 PreparedStatement ps = null;
117
118 try {
119 con = DataAccess.getUpgradeOptimizedConnection();
120
121 ps = con.prepareStatement(
122 "update JournalArticle set urlTitle = ? where urlTitle = ?");
123
124 ps.setString(1, normalizedURLTitle);
125 ps.setString(2, urlTitle);
126
127 ps.executeUpdate();
128 }
129 finally {
130 DataAccess.cleanUp(con, ps);
131 }
132 }
133
134 protected void verifyContentSearch(long groupId, String portletId)
135 throws Exception {
136
137 Connection con = null;
138 PreparedStatement ps = null;
139 ResultSet rs = null;
140
141 try {
142 con = DataAccess.getUpgradeOptimizedConnection();
143
144 ps = con.prepareStatement(
145 "select preferences from PortletPreferences inner join " +
146 "Layout on PortletPreferences.plid = Layout.plid where " +
147 "groupId = ? and portletId = ?");
148
149 ps.setLong(1, groupId);
150 ps.setString(2, portletId);
151
152 rs = ps.executeQuery();
153
154 while (rs.next()) {
155 String xml = rs.getString("preferences");
156
157 PortletPreferences portletPreferences =
158 PortletPreferencesFactoryUtil.fromDefaultXML(xml);
159
160 String articleId = portletPreferences.getValue(
161 "articleId", null);
162
163 List<JournalContentSearch> contentSearches =
164 JournalContentSearchLocalServiceUtil.
165 getArticleContentSearches(groupId, articleId);
166
167 if (contentSearches.isEmpty()) {
168 continue;
169 }
170
171 JournalContentSearch contentSearch = contentSearches.get(0);
172
173 JournalContentSearchLocalServiceUtil.updateContentSearch(
174 contentSearch.getGroupId(), contentSearch.isPrivateLayout(),
175 contentSearch.getLayoutId(), contentSearch.getPortletId(),
176 articleId, true);
177 }
178 }
179 finally {
180 DataAccess.cleanUp(con, ps, rs);
181 }
182 }
183
184 protected void verifyOracleNewLine() throws Exception {
185 DB db = DBFactoryUtil.getDB();
186
187 String dbType = db.getType();
188
189 if (!dbType.equals(DB.TYPE_ORACLE)) {
190 return;
191 }
192
193
194
195
196
197
198
199 boolean checkNewLine = false;
200
201 List<JournalArticle> articles =
202 JournalArticleLocalServiceUtil.getArticles(
203 DEFAULT_GROUP_ID, 0, NUM_OF_ARTICLES);
204
205 for (JournalArticle article : articles) {
206 String content = article.getContent();
207
208 if ((content != null) && content.contains("\\n")) {
209 articles = JournalArticleLocalServiceUtil.getArticles(
210 DEFAULT_GROUP_ID);
211
212 for (int j = 0; j < articles.size(); j++) {
213 article = articles.get(j);
214
215 JournalArticleLocalServiceUtil.checkNewLine(
216 article.getGroupId(), article.getArticleId(),
217 article.getVersion());
218 }
219
220 checkNewLine = true;
221
222 break;
223 }
224 }
225
226
227
228 if (!checkNewLine) {
229 if (_log.isInfoEnabled()) {
230 _log.info("Do not fix oracle new line");
231 }
232
233 return;
234 }
235 else {
236 if (_log.isInfoEnabled()) {
237 _log.info("Fix oracle new line");
238 }
239 }
240 }
241
242 protected void verifyPermissionsAndAssets() throws Exception {
243 ActionableDynamicQuery actionableDynamicQuery =
244 new JournalArticleActionableDynamicQuery() {
245
246 @Override
247 protected void performAction(Object object)
248 throws PortalException, SystemException {
249
250 JournalArticle article = (JournalArticle)object;
251
252 long groupId = article.getGroupId();
253 String articleId = article.getArticleId();
254 double version = article.getVersion();
255 String structureId = article.getStructureId();
256
257 if (article.getResourcePrimKey() <= 0) {
258 article =
259 JournalArticleLocalServiceUtil.
260 checkArticleResourcePrimKey(
261 groupId, articleId, version);
262 }
263
264 ResourceLocalServiceUtil.addResources(
265 article.getCompanyId(), 0, 0,
266 JournalArticle.class.getName(),
267 article.getResourcePrimKey(), false, false, false);
268
269 AssetEntry assetEntry = AssetEntryLocalServiceUtil.fetchEntry(
270 JournalArticle.class.getName(),
271 article.getResourcePrimKey());
272
273 if (assetEntry == null) {
274 try {
275 JournalArticleLocalServiceUtil.updateAsset(
276 article.getUserId(), article, null, null, null);
277 }
278 catch (Exception e) {
279 if (_log.isWarnEnabled()) {
280 _log.warn(
281 "Unable to update asset for article " +
282 article.getId() + ": " + e.getMessage());
283 }
284 }
285 }
286 else if ((article.getStatus() ==
287 WorkflowConstants.STATUS_DRAFT) &&
288 (article.getVersion() ==
289 JournalArticleConstants.VERSION_DEFAULT)) {
290
291 AssetEntryLocalServiceUtil.updateEntry(
292 assetEntry.getClassName(), assetEntry.getClassPK(),
293 null, assetEntry.isVisible());
294 }
295
296 String content = GetterUtil.getString(article.getContent());
297
298 String newContent = HtmlUtil.replaceMsWordCharacters(content);
299
300 if (Validator.isNotNull(structureId)) {
301
307 }
308
309 if (!content.equals(newContent)) {
310 JournalArticleLocalServiceUtil.updateContent(
311 groupId, articleId, version, newContent);
312 }
313
314 try {
315 JournalArticleLocalServiceUtil.checkStructure(
316 groupId, articleId, version);
317 }
318 catch (NoSuchStructureException nsse) {
319 if (_log.isWarnEnabled()) {
320 _log.warn(
321 "Removing reference to missing structure for " +
322 "article " + article.getId());
323 }
324
325 article.setStructureId(StringPool.BLANK);
326 article.setTemplateId(StringPool.BLANK);
327
328 JournalArticleLocalServiceUtil.updateJournalArticle(
329 article);
330 }
331 }
332
333 };
334
335 actionableDynamicQuery.performActions();
336
337 if (_log.isDebugEnabled()) {
338 _log.debug("Permissions and assets verified for articles");
339 }
340 }
341
342 protected void verifySearch() throws Exception {
343 Connection con = null;
344 PreparedStatement ps = null;
345 ResultSet rs = null;
346
347 try {
348 con = DataAccess.getUpgradeOptimizedConnection();
349
350 ps = con.prepareStatement(
351 "select groupId, portletId from JournalContentSearch group " +
352 "by groupId, portletId having count(groupId) > 1 and " +
353 "count(portletId) > 1");
354
355 rs = ps.executeQuery();
356
357 while (rs.next()) {
358 long groupId = rs.getLong("groupId");
359 String portletId = rs.getString("portletId");
360
361 verifyContentSearch(groupId, portletId);
362 }
363 }
364 finally {
365 DataAccess.cleanUp(con, ps, rs);
366 }
367 }
368
369 protected void verifyURLTitle() throws Exception {
370 Connection con = null;
371 PreparedStatement ps = null;
372 ResultSet rs = null;
373
374 try {
375 con = DataAccess.getUpgradeOptimizedConnection();
376
377 ps = con.prepareStatement(
378 "select distinct groupId, articleId, urlTitle from " +
379 "JournalArticle");
380
381 rs = ps.executeQuery();
382
383 while (rs.next()) {
384 long groupId = rs.getLong("groupId");
385 String articleId = rs.getString("articleId");
386 String urlTitle = rs.getString("urlTitle");
387
388 updateURLTitle(groupId, articleId, urlTitle);
389 }
390 }
391 finally {
392 DataAccess.cleanUp(con, ps, rs);
393 }
394 }
395
396 private static Log _log = LogFactoryUtil.getLog(VerifyJournal.class);
397
398 private static Pattern _friendlyURLPattern = Pattern.compile("[^a-z0-9_-]");
399
400 }