001
014
015 package com.liferay.portal.upgrade.v7_0_0;
016
017 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.template.TemplateConstants;
021 import com.liferay.portal.kernel.upgrade.util.UpgradeProcessUtil;
022 import com.liferay.portal.kernel.util.GetterUtil;
023 import com.liferay.portal.kernel.util.LocaleUtil;
024 import com.liferay.portal.kernel.util.StringBundler;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.kernel.util.StringUtil;
027 import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
028 import com.liferay.portal.kernel.workflow.WorkflowConstants;
029 import com.liferay.portal.kernel.xml.Document;
030 import com.liferay.portal.kernel.xml.DocumentException;
031 import com.liferay.portal.kernel.xml.Element;
032 import com.liferay.portal.kernel.xml.SAXReaderUtil;
033 import com.liferay.portal.model.RoleConstants;
034 import com.liferay.portal.security.permission.ActionKeys;
035 import com.liferay.portal.upgrade.v7_0_0.util.JournalArticleTable;
036 import com.liferay.portal.util.PortalUtil;
037 import com.liferay.portlet.dynamicdatamapping.io.DDMFormJSONDeserializerUtil;
038 import com.liferay.portlet.dynamicdatamapping.io.DDMFormXSDDeserializerUtil;
039 import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
040 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
041 import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
042 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
043 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
044 import com.liferay.portlet.dynamicdatamapping.storage.StorageType;
045 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
046 import com.liferay.portlet.journal.model.JournalArticle;
047 import com.liferay.util.ContentUtil;
048
049 import java.sql.Connection;
050 import java.sql.PreparedStatement;
051 import java.sql.ResultSet;
052 import java.sql.SQLException;
053 import java.sql.Timestamp;
054
055 import java.util.ArrayList;
056 import java.util.List;
057 import java.util.Locale;
058 import java.util.Map;
059
060
064 public class UpgradeJournal extends UpgradeBaseJournal {
065
066 protected String addBasicWebContentStructureAndTemplate(long companyId)
067 throws Exception {
068
069 long groupId = getCompanyGroupId(companyId);
070
071 String defaultLanguageId = UpgradeProcessUtil.getDefaultLanguageId(
072 companyId);
073
074 Locale defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);
075
076 List<Element> structureElements = getDDMStructures(defaultLocale);
077
078 Element structureElement = structureElements.get(0);
079
080 String name = structureElement.elementText("name");
081
082 String description = structureElement.elementText("description");
083
084 String localizedName = localize(groupId, name, defaultLanguageId);
085 String localizedDescription = localize(
086 groupId, description, defaultLanguageId);
087
088 Element structureElementRootElement = structureElement.element("root");
089
090 String xsd = structureElementRootElement.asXML();
091
092 if (hasDDMStructure(groupId, name) > 0) {
093 return name;
094 }
095
096 String ddmStructureUUID = PortalUUIDUtil.generate();
097
098 DDMForm ddmForm = DDMFormXSDDeserializerUtil.deserialize(xsd);
099
100 long ddmStructureId = addDDMStructure(
101 ddmStructureUUID, increment(), groupId, companyId, name,
102 localizedName, localizedDescription, toJSON(ddmForm),
103 StorageType.JSON.toString());
104
105 String ddmTemplateUUID = PortalUUIDUtil.generate();
106
107 Element templateElement = structureElement.element("template");
108
109 String fileName = templateElement.elementText("file-name");
110 boolean cacheable = GetterUtil.getBoolean(
111 templateElement.elementText("cacheable"));
112
113 addDDMTemplate(
114 ddmTemplateUUID, increment(), groupId, companyId, ddmStructureId,
115 name, localizedName, localizedDescription, getContent(fileName),
116 cacheable);
117
118 long stagingGroupId = getStagingGroupId(groupId);
119
120 if (stagingGroupId > 0) {
121 ddmStructureId = addDDMStructure(
122 ddmStructureUUID, increment(), stagingGroupId, companyId, name,
123 localizedName, localizedDescription, toJSON(ddmForm),
124 StorageType.JSON.toString());
125
126 addDDMTemplate(
127 ddmTemplateUUID, increment(), stagingGroupId, companyId,
128 ddmStructureId, name, localizedName, localizedDescription,
129 getContent(fileName), cacheable);
130 }
131
132 return name;
133 }
134
135 protected long addDDMStructure(
136 String uuid, long ddmStructureId, long groupId, long companyId,
137 String ddmStructureKey, String localizedName,
138 String localizedDescription, String definition, String storageType)
139 throws Exception {
140
141 Timestamp now = new Timestamp(System.currentTimeMillis());
142
143 Connection con = null;
144 PreparedStatement ps = null;
145
146 try {
147 con = DataAccess.getUpgradeOptimizedConnection();
148
149 StringBundler sb = new StringBundler(6);
150
151 sb.append("insert into DDMStructure (uuid_, structureId, ");
152 sb.append("groupId, companyId, userId, userName, createDate, ");
153 sb.append("modifiedDate, parentStructureId, classNameId, ");
154 sb.append("structureKey, version, name, description, definition, ");
155 sb.append("storageType, type_) values (?, ?, ?, ?, ?, ?, ?, ?, ");
156 sb.append("?, ?, ?, ?, ?, ?, ?, ?, ?)");
157
158 String sql = sb.toString();
159
160 ps = con.prepareStatement(sql);
161
162 ps.setString(1, uuid);
163 ps.setLong(2, ddmStructureId);
164 ps.setLong(3, groupId);
165 ps.setLong(4, companyId);
166 ps.setLong(5, getDefaultUserId(companyId));
167 ps.setString(6, StringPool.BLANK);
168 ps.setTimestamp(7, now);
169 ps.setTimestamp(8, now);
170 ps.setLong(9, DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID);
171 ps.setLong(10, PortalUtil.getClassNameId(JournalArticle.class));
172 ps.setString(11, ddmStructureKey);
173 ps.setString(12, DDMStructureConstants.VERSION_DEFAULT);
174 ps.setString(13, localizedName);
175 ps.setString(14, localizedDescription);
176 ps.setString(15, definition);
177 ps.setString(16, storageType);
178 ps.setInt(17, DDMStructureConstants.TYPE_DEFAULT);
179
180 ps.executeUpdate();
181
182 long ddmStructureVersionId = increment();
183
184 addStructureVersion(
185 ddmStructureVersionId, groupId, companyId,
186 getDefaultUserId(companyId), StringPool.BLANK, now,
187 ddmStructureId,
188 DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID,
189 localizedName, localizedDescription, definition, storageType,
190 DDMStructureConstants.TYPE_DEFAULT,
191 WorkflowConstants.STATUS_APPROVED, getDefaultUserId(companyId),
192 StringPool.BLANK, now);
193
194 String ddmStructureLayoutDefinition =
195 getDefaultDDMFormLayoutDefinition(definition);
196
197 addStructureLayout(
198 PortalUUIDUtil.generate(), increment(), groupId, companyId,
199 getDefaultUserId(companyId), StringPool.BLANK, now, now,
200 ddmStructureVersionId, ddmStructureLayoutDefinition);
201
202 Map<String, Long> bitwiseValues = getBitwiseValues(
203 DDMStructure.class.getName());
204
205 List<String> actionIds = new ArrayList<>();
206
207 actionIds.add(ActionKeys.VIEW);
208
209 long bitwiseValue = getBitwiseValue(bitwiseValues, actionIds);
210
211 addResourcePermission(
212 companyId, DDMStructure.class.getName(), ddmStructureId,
213 getRoleId(companyId, RoleConstants.GUEST), bitwiseValue);
214 addResourcePermission(
215 companyId, DDMStructure.class.getName(), ddmStructureId,
216 getRoleId(companyId, RoleConstants.SITE_MEMBER), bitwiseValue);
217 }
218 catch (Exception e) {
219 _log.error("Unable to create the basic web content structure");
220
221 throw e;
222 }
223 finally {
224 DataAccess.cleanUp(con, ps);
225 }
226
227 return ddmStructureId;
228 }
229
230 protected long addDDMTemplate(
231 String uuid, long ddmTemplateId, long groupId, long companyId,
232 long ddmStructureId, String templateKey, String localizedName,
233 String localizedDescription, String script, boolean cacheable)
234 throws Exception {
235
236 Timestamp now = new Timestamp(System.currentTimeMillis());
237
238 Connection con = null;
239 PreparedStatement ps = null;
240
241 try {
242 con = DataAccess.getUpgradeOptimizedConnection();
243
244 StringBundler sb = new StringBundler(7);
245
246 sb.append("insert into DDMTemplate (uuid_, templateId, groupId, ");
247 sb.append("companyId, userId, userName, createDate, modifiedDate,");
248 sb.append("classNameId, classPK, templateKey, version, name, ");
249 sb.append("description, type_, mode_, language, script, ");
250 sb.append("cacheable, smallImage, smallImageId, smallImageURL) ");
251 sb.append("values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ");
252 sb.append("?, ?, ?, ?, ?, ?, ?)");
253
254 String sql = sb.toString();
255
256 ps = con.prepareStatement(sql);
257
258 ps.setString(1, uuid);
259 ps.setLong(2, ddmTemplateId);
260 ps.setLong(3, groupId);
261 ps.setLong(4, companyId);
262 ps.setLong(5, getDefaultUserId(companyId));
263 ps.setString(6, StringPool.BLANK);
264 ps.setTimestamp(7, now);
265 ps.setTimestamp(8, now);
266 ps.setLong(9, PortalUtil.getClassNameId(DDMStructure.class));
267 ps.setLong(10, ddmStructureId);
268 ps.setString(11, templateKey);
269 ps.setString(12, DDMTemplateConstants.VERSION_DEFAULT);
270 ps.setString(13, localizedName);
271 ps.setString(14, localizedDescription);
272 ps.setString(15, DDMTemplateConstants.TEMPLATE_TYPE_DISPLAY);
273 ps.setString(16, DDMTemplateConstants.TEMPLATE_MODE_CREATE);
274 ps.setString(17, TemplateConstants.LANG_TYPE_FTL);
275 ps.setString(18, script);
276 ps.setBoolean(19, cacheable);
277 ps.setBoolean(20, false);
278 ps.setLong(21, 0);
279 ps.setString(22, StringPool.BLANK);
280
281 ps.executeUpdate();
282
283 addTemplateVersion(
284 increment(), groupId, companyId, getDefaultUserId(companyId),
285 StringPool.BLANK, now,
286 PortalUtil.getClassNameId(DDMStructure.class), ddmStructureId,
287 ddmTemplateId, localizedName, localizedDescription,
288 TemplateConstants.LANG_TYPE_FTL, script,
289 WorkflowConstants.STATUS_APPROVED, getDefaultUserId(companyId),
290 StringPool.BLANK, now);
291
292 Map<String, Long> bitwiseValues = getBitwiseValues(
293 DDMTemplate.class.getName());
294
295 List<String> actionIds = new ArrayList<>();
296
297 actionIds.add(ActionKeys.VIEW);
298
299 long bitwiseValue = getBitwiseValue(bitwiseValues, actionIds);
300
301 addResourcePermission(
302 companyId, DDMTemplate.class.getName(), ddmTemplateId,
303 getRoleId(companyId, RoleConstants.GUEST), bitwiseValue);
304 addResourcePermission(
305 companyId, DDMTemplate.class.getName(), ddmTemplateId,
306 getRoleId(companyId, RoleConstants.SITE_MEMBER), bitwiseValue);
307 }
308 catch (Exception e) {
309 _log.error("Unable to create the basic web content template");
310
311 throw e;
312 }
313 finally {
314 DataAccess.cleanUp(con, ps);
315 }
316
317 return ddmTemplateId;
318 }
319
320 protected void addDDMTemplateLink(
321 long classNameId, long classPK, long templateId)
322 throws Exception {
323
324 Connection con = null;
325 PreparedStatement ps = null;
326
327 try {
328 con = DataAccess.getUpgradeOptimizedConnection();
329
330 ps = con.prepareStatement(
331 "insert into DDMTemplateLink (templateLinkId, classNameId, " +
332 "classPK, templateId) values (?, ?, ?, ?)");
333
334 ps.setLong(1, increment());
335 ps.setLong(2, classNameId);
336 ps.setLong(3, classPK);
337 ps.setLong(4, templateId);
338
339 ps.executeUpdate();
340 }
341 catch (Exception e) {
342 _log.error("Unable to create template link for journal article");
343
344 throw e;
345 }
346 finally {
347 DataAccess.cleanUp(con, ps);
348 }
349 }
350
351 protected void addDDMTemplateLinks() throws Exception {
352 long classNameId = PortalUtil.getClassNameId(DDMStructure.class);
353
354 Connection con = null;
355 PreparedStatement ps = null;
356 ResultSet rs = null;
357
358 try {
359 con = DataAccess.getUpgradeOptimizedConnection();
360
361 StringBundler sb = new StringBundler(6);
362
363 sb.append("select DDMTemplate.templateId, JournalArticle.id_ ");
364 sb.append("from JournalArticle inner join DDMTemplate on (");
365 sb.append("DDMTemplate.groupId = JournalArticle.groupId and ");
366 sb.append("DDMTemplate.templateKey = ");
367 sb.append("JournalArticle.ddmTemplateKey and ");
368 sb.append("JournalArticle.classNameId != ?)");
369
370 ps = con.prepareStatement(sb.toString());
371
372 ps.setLong(1, classNameId);
373
374 rs = ps.executeQuery();
375
376 while (rs.next()) {
377 long templateId = rs.getLong("templateId");
378 long id_ = rs.getLong("id_");
379
380 addDDMTemplateLink(classNameId, id_, templateId);
381 }
382 }
383 finally {
384 DataAccess.cleanUp(con, ps, rs);
385 }
386 }
387
388 protected String convertStaticContentToDynamic(String content)
389 throws Exception {
390
391 Document document = SAXReaderUtil.read(content);
392
393 Document newDocument = SAXReaderUtil.createDocument();
394
395 Element rootElement = document.getRootElement();
396
397 String availableLocales = rootElement.attributeValue(
398 "available-locales");
399 String defaultLocale = rootElement.attributeValue("default-locale");
400
401 Element newRootElement = SAXReaderUtil.createElement("root");
402
403 newRootElement.addAttribute("available-locales", availableLocales);
404 newRootElement.addAttribute("default-locale", defaultLocale);
405
406 newDocument.add(newRootElement);
407
408 Element dynamicElementElement = SAXReaderUtil.createElement(
409 "dynamic-element");
410
411 dynamicElementElement.addAttribute("name", "content");
412 dynamicElementElement.addAttribute("type", "text_area");
413 dynamicElementElement.addAttribute("index-type", "keyword");
414 dynamicElementElement.addAttribute("index", String.valueOf(0));
415
416 newRootElement.add(dynamicElementElement);
417
418 List<Element> staticContentElements = rootElement.elements(
419 "static-content");
420
421 for (Element staticContentElement : staticContentElements) {
422 String languageId = staticContentElement.attributeValue(
423 "language-id");
424 String text = staticContentElement.getText();
425
426 Element dynamicContentElement = SAXReaderUtil.createElement(
427 "dynamic-content");
428
429 dynamicContentElement.addAttribute("language-id", languageId);
430 dynamicContentElement.addCDATA(text);
431
432 dynamicElementElement.add(dynamicContentElement);
433 }
434
435 return DDMXMLUtil.formatXML(newDocument);
436 }
437
438 @Override
439 protected void doUpgrade() throws Exception {
440 try {
441 runSQL(
442 "alter_column_name JournalArticle structureId " +
443 "DDMStructureKey VARCHAR(75) null");
444
445 runSQL(
446 "alter_column_name JournalArticle templateId DDMTemplateKey " +
447 "VARCHAR(75) null");
448
449 runSQL("alter_column_type JournalArticle description TEXT null");
450
451 runSQL(
452 "alter_column_name JournalFeed structureId DDMStructureKey " +
453 "TEXT null");
454
455 runSQL(
456 "alter_column_name JournalFeed templateId DDMTemplateKey " +
457 "TEXT null");
458
459 runSQL(
460 "alter_column_name JournalFeed rendererTemplateId " +
461 "DDMRendererTemplateKey TEXT null");
462 }
463 catch (SQLException sqle) {
464 upgradeTable(
465 JournalArticleTable.TABLE_NAME,
466 JournalArticleTable.TABLE_COLUMNS,
467 JournalArticleTable.TABLE_SQL_CREATE,
468 JournalArticleTable.TABLE_SQL_ADD_INDEXES);
469 }
470
471 updateBasicWebContentStructure();
472
473 addDDMTemplateLinks();
474 }
475
476 protected String getContent(String fileName) {
477 return ContentUtil.get(
478 "com/liferay/portal/events/dependencies/" + fileName);
479 }
480
481 protected List<Element> getDDMStructures(Locale locale)
482 throws DocumentException {
483
484 String xml = getContent("basic-web-content-structure.xml");
485
486 xml = StringUtil.replace(xml, "[$LOCALE_DEFAULT$]", locale.toString());
487
488 Document document = SAXReaderUtil.read(xml);
489
490 Element rootElement = document.getRootElement();
491
492 return rootElement.elements("structure");
493 }
494
495 protected String getDefaultDDMFormLayoutDefinition(String definition)
496 throws Exception {
497
498 DDMForm ddmForm = DDMFormJSONDeserializerUtil.deserialize(definition);
499
500 return getDefaultDDMFormLayoutDefinition(ddmForm);
501 }
502
503 protected long getStagingGroupId(long groupId) throws Exception {
504 Connection con = null;
505 PreparedStatement ps = null;
506 ResultSet rs = null;
507
508 try {
509 con = DataAccess.getUpgradeOptimizedConnection();
510
511 ps = con.prepareStatement(
512 "select groupId from Group_ where liveGroupId = ?");
513
514 ps.setLong(1, groupId);
515
516 rs = ps.executeQuery();
517
518 if (rs.next()) {
519 return rs.getLong("groupId");
520 }
521
522 return 0;
523 }
524 finally {
525 DataAccess.cleanUp(con, ps, rs);
526 }
527 }
528
529 protected int hasDDMStructure(long groupId, String ddmStructureKey)
530 throws Exception {
531
532 Connection con = null;
533 PreparedStatement ps = null;
534 ResultSet rs = null;
535
536 try {
537 con = DataAccess.getUpgradeOptimizedConnection();
538
539 ps = con.prepareStatement(
540 "select count(*) from DDMStructure where groupId = ? and " +
541 "classNameId = ? and structureKey = ?");
542
543 ps.setLong(1, groupId);
544 ps.setLong(
545 2, PortalUtil.getClassNameId(JournalArticle.class.getName()));
546 ps.setString(3, ddmStructureKey);
547
548 rs = ps.executeQuery();
549
550 if (rs.next()) {
551 int count = rs.getInt(1);
552
553 return count;
554 }
555
556 return 0;
557 }
558 finally {
559 DataAccess.cleanUp(con, ps, rs);
560 }
561 }
562
563 protected void updateBasicWebContentStructure() throws Exception {
564 Connection con = null;
565 PreparedStatement ps = null;
566 ResultSet rs = null;
567
568 try {
569 con = DataAccess.getUpgradeOptimizedConnection();
570
571 ps = con.prepareStatement("select companyId from Company");
572
573 rs = ps.executeQuery();
574
575 while (rs.next()) {
576 long companyId = rs.getLong("companyId");
577
578 updateJournalArticles(companyId);
579 }
580 }
581 finally {
582 DataAccess.cleanUp(con, ps, rs);
583 }
584 }
585
586 protected void updateJournalArticle(
587 long id_, String ddmStructureKey, String ddmTemplateKey,
588 String content)
589 throws Exception {
590
591 Connection con = null;
592 PreparedStatement ps = null;
593
594 try {
595 con = DataAccess.getUpgradeOptimizedConnection();
596
597 ps = con.prepareStatement(
598 "update JournalArticle set ddmStructureKey = ?, " +
599 "ddmTemplateKey = ?, content = ? where id_ = ?");
600
601 ps.setString(1, ddmStructureKey);
602 ps.setString(2, ddmTemplateKey);
603 ps.setString(3, convertStaticContentToDynamic(content));
604 ps.setLong(4, id_);
605
606 ps.executeUpdate();
607 }
608 finally {
609 DataAccess.cleanUp(con, ps);
610 }
611 }
612
613 protected void updateJournalArticles(long companyId) throws Exception {
614 Connection con = null;
615 PreparedStatement ps = null;
616 ResultSet rs = null;
617
618 try {
619 con = DataAccess.getUpgradeOptimizedConnection();
620
621 ps = con.prepareStatement(
622 "select id_, content from JournalArticle where companyId = " +
623 companyId + " and ddmStructureKey is null or " +
624 "ddmStructureKey like ''");
625
626 String name = addBasicWebContentStructureAndTemplate(companyId);
627
628 rs = ps.executeQuery();
629
630 while (rs.next()) {
631 long id_ = rs.getLong("id_");
632 String content = rs.getString("content");
633
634 updateJournalArticle(id_, name, name, content);
635 }
636 }
637 finally {
638 DataAccess.cleanUp(con, ps, rs);
639 }
640 }
641
642 private static final Log _log = LogFactoryUtil.getLog(UpgradeJournal.class);
643
644 }