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