001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.upgrade.v6_2_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.upgrade.BaseUpgradePortletPreferences;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.LocaleUtil;
023    import com.liferay.portal.kernel.util.StringBundler;
024    import com.liferay.portal.kernel.util.StringPool;
025    import com.liferay.portal.kernel.util.StringUtil;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.model.Company;
028    import com.liferay.portal.upgrade.v6_2_0.util.JournalFeedTable;
029    import com.liferay.portal.util.PortalUtil;
030    import com.liferay.portal.util.PropsUtil;
031    import com.liferay.portlet.PortletPreferencesFactoryUtil;
032    import com.liferay.portlet.journal.util.JournalConverterManagerUtil;
033    
034    import java.sql.Connection;
035    import java.sql.PreparedStatement;
036    import java.sql.ResultSet;
037    import java.sql.SQLException;
038    import java.sql.Timestamp;
039    
040    import java.util.HashMap;
041    import java.util.Locale;
042    import java.util.Map;
043    
044    import javax.portlet.PortletPreferences;
045    
046    /**
047     * @author Brian Wing Shun Chan
048     * @author Marcellus Tavares
049     * @author Juan Fern??ndez
050     * @author Bruno Basto
051     */
052    public class UpgradeJournal extends BaseUpgradePortletPreferences {
053    
054            protected void addDDMStructure(
055                            String uuid_, long ddmStructureId, long groupId, long companyId,
056                            long userId, String userName, Timestamp createDate,
057                            Timestamp modifiedDate, long parentDDMStructureId, long classNameId,
058                            String ddmStructureKey, String name, String description, String xsd,
059                            String storageType, int type)
060                    throws Exception {
061    
062                    Connection con = null;
063                    PreparedStatement ps = null;
064    
065                    try {
066                            con = DataAccess.getUpgradeOptimizedConnection();
067    
068                            StringBundler sb = new StringBundler(6);
069    
070                            sb.append("insert into DDMStructure (uuid_, structureId, ");
071                            sb.append("groupId, companyId, userId, userName, createDate, ");
072                            sb.append("modifiedDate, parentStructureId, classNameId, ");
073                            sb.append("structureKey, name, description, xsd, storageType, ");
074                            sb.append("type_) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ");
075                            sb.append("?, ?, ?)");
076    
077                            String sql = sb.toString();
078    
079                            ps = con.prepareStatement(sql);
080    
081                            ps.setString(1, uuid_);
082                            ps.setLong(2, ddmStructureId);
083                            ps.setLong(3, groupId);
084                            ps.setLong(4, companyId);
085                            ps.setLong(5, userId);
086                            ps.setString(6, userName);
087                            ps.setTimestamp(7, createDate);
088                            ps.setTimestamp(8, modifiedDate);
089                            ps.setLong(9, parentDDMStructureId);
090                            ps.setLong(10, classNameId);
091                            ps.setString(11, ddmStructureKey);
092                            ps.setString(12, name);
093                            ps.setString(13, description);
094                            ps.setString(
095                                    14,
096                                    JournalConverterManagerUtil.getDDMXSD(
097                                            xsd, getDefaultLocale(companyId)));
098                            ps.setString(15, storageType);
099                            ps.setInt(16, type);
100    
101                            ps.executeUpdate();
102                    }
103                    catch (Exception e) {
104                            _log.error(
105                                    "Unable to upgrade dynamic data mapping structure with UUID " +
106                                            uuid_);
107    
108                            throw e;
109                    }
110                    finally {
111                            DataAccess.cleanUp(con, ps);
112                    }
113            }
114    
115            protected void addDDMStructure(
116                            String uuid_, long ddmStructureId, long groupId, long companyId,
117                            long userId, String userName, Timestamp createDate,
118                            Timestamp modifiedDate, String parentStructureId,
119                            String ddmStructureKey, String name, String description, String xsd)
120                    throws Exception {
121    
122                    long parentDDMStructureId = 0;
123    
124                    if (Validator.isNotNull(parentStructureId)) {
125                            parentDDMStructureId = updateStructure(parentStructureId);
126                    }
127    
128                    long insertedDDMStructureId = getDDMStructureId(
129                            groupId, ddmStructureKey, false);
130    
131                    if (insertedDDMStructureId == 0) {
132                            addDDMStructure(
133                                    uuid_, ddmStructureId, groupId, companyId, userId, userName,
134                                    createDate, modifiedDate, parentDDMStructureId,
135                                    PortalUtil.getClassNameId(
136                                            "com.liferay.portlet.journal.model.JournalArticle"),
137                                    ddmStructureKey, name, description, xsd,
138                                    PropsUtil.get("journal.article.storage.type"),
139                                    _DDM_STRUCTURE_TYPE_DEFAULT);
140                    }
141            }
142    
143            protected void addDDMTemplate(
144                            String uuid_, long ddmTemplateId, long groupId, long companyId,
145                            long userId, String userName, Timestamp createDate,
146                            Timestamp modifiedDate, long classNameId, long classPK,
147                            String templateKey, String name, String description, String type,
148                            String mode, String language, String script, boolean cacheable,
149                            boolean smallImage, long smallImageId, String smallImageURL)
150                    throws Exception {
151    
152                    Connection con = null;
153                    PreparedStatement ps = null;
154    
155                    try {
156                            con = DataAccess.getUpgradeOptimizedConnection();
157    
158                            StringBundler sb = new StringBundler(6);
159    
160                            sb.append("insert into DDMTemplate (uuid_, templateId, groupId, ");
161                            sb.append("companyId, userId, userName, createDate, modifiedDate,");
162                            sb.append("classNameId, classPK , templateKey, name, description,");
163                            sb.append("type_, mode_, language, script, cacheable, smallImage,");
164                            sb.append("smallImageId, smallImageURL) values (?, ?, ?, ?, ?, ?,");
165                            sb.append("?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
166    
167                            String sql = sb.toString();
168    
169                            ps = con.prepareStatement(sql);
170    
171                            ps.setString(1, uuid_);
172                            ps.setLong(2, ddmTemplateId);
173                            ps.setLong(3, groupId);
174                            ps.setLong(4, companyId);
175                            ps.setLong(5, userId);
176                            ps.setString(6, userName);
177                            ps.setTimestamp(7, createDate);
178                            ps.setTimestamp(8, modifiedDate);
179                            ps.setLong(9, classNameId);
180                            ps.setLong(10, classPK);
181                            ps.setString(11, templateKey);
182                            ps.setString(12, name);
183                            ps.setString(13, description);
184                            ps.setString(14, type);
185                            ps.setString(15, mode);
186                            ps.setString(16, language);
187                            ps.setString(17, script);
188                            ps.setBoolean(18, cacheable);
189                            ps.setBoolean(19, smallImage);
190                            ps.setLong(20, smallImageId);
191                            ps.setString(21, smallImageURL);
192    
193                            ps.executeUpdate();
194                    }
195                    catch (Exception e) {
196                            _log.error(
197                                    "Unable to upgrade dynamic data mapping template with UUID " +
198                                            uuid_);
199    
200                            throw e;
201                    }
202                    finally {
203                            DataAccess.cleanUp(con, ps);
204                    }
205            }
206    
207            @Override
208            protected void doUpgrade() throws Exception {
209                    try {
210                            runSQL(
211                                    "alter_column_name JournalFeed feedType feedFormat " +
212                                            "VARCHAR(75) null");
213                    }
214                    catch (SQLException sqle) {
215                            upgradeTable(
216                                    JournalFeedTable.TABLE_NAME, JournalFeedTable.TABLE_COLUMNS,
217                                    JournalFeedTable.TABLE_SQL_CREATE,
218                                    JournalFeedTable.TABLE_SQL_ADD_INDEXES);
219                    }
220    
221                    updateStructures();
222                    updateTemplates();
223    
224                    updateAssetEntryClassTypeId();
225    
226                    super.doUpgrade();
227            }
228    
229            protected long getCompanyGroupId(long companyId) throws Exception {
230                    Connection con = null;
231                    PreparedStatement ps = null;
232                    ResultSet rs = null;
233    
234                    try {
235                            con = DataAccess.getUpgradeOptimizedConnection();
236    
237                            ps = con.prepareStatement(
238                                    "select groupId from Group_ where classNameId = ? and " +
239                                            "classPK = ?");
240    
241                            ps.setLong(1, PortalUtil.getClassNameId(Company.class.getName()));
242                            ps.setLong(2, companyId);
243    
244                            rs = ps.executeQuery();
245    
246                            if (rs.next()) {
247                                    return rs.getLong("groupId");
248                            }
249    
250                            return 0;
251                    }
252                    finally {
253                            DataAccess.cleanUp(con, ps, rs);
254                    }
255            }
256    
257            protected long getDDMStructureClassNameId() {
258                    return PortalUtil.getClassNameId(
259                            "com.liferay.portlet.dynamicdatamapping.DDMStructure");
260            }
261    
262            protected long getDDMStructureId(
263                    long groupId, long companyGroupId, String structureId) {
264    
265                    return getDDMStructureId(groupId, companyGroupId, structureId, true);
266            }
267    
268            protected long getDDMStructureId(
269                    long groupId, long companyGroupId, String structureId, boolean warn) {
270    
271                    if (Validator.isNull(structureId)) {
272                            return 0;
273                    }
274    
275                    Long ddmStructureId = _ddmStructureIds.get(groupId + "#" + structureId);
276    
277                    if ((ddmStructureId == null) && (companyGroupId != 0)) {
278                            ddmStructureId = _ddmStructureIds.get(
279                                    companyGroupId + "#" + structureId);
280                    }
281    
282                    if (ddmStructureId != null) {
283                            return ddmStructureId;
284                    }
285    
286                    if (warn && _log.isWarnEnabled()) {
287                            StringBundler sb = new StringBundler();
288    
289                            sb.append("Unable to get the DDM structure ID for group ");
290                            sb.append(groupId);
291    
292                            if (companyGroupId != 0) {
293                                    sb.append(" or global group");
294                            }
295    
296                            sb.append(" and journal structure ID ");
297                            sb.append(structureId);
298    
299                            _log.warn(sb.toString());
300                    }
301    
302                    return 0;
303            }
304    
305            protected long getDDMStructureId(
306                    long groupId, String structureId, boolean warn) {
307    
308                    return getDDMStructureId(groupId, 0, structureId, warn);
309            }
310    
311            protected Locale getDefaultLocale(long companyId) throws Exception {
312                    Connection con = null;
313                    PreparedStatement ps = null;
314                    ResultSet rs = null;
315    
316                    try {
317                            con = DataAccess.getUpgradeOptimizedConnection();
318    
319                            ps = con.prepareStatement(
320                                    "select languageId from User_ where companyId = ? and " +
321                                            "defaultUser = ?");
322    
323                            ps.setLong(1, companyId);
324                            ps.setBoolean(2, true);
325    
326                            rs = ps.executeQuery();
327    
328                            if (rs.next()) {
329                                    String languageId = rs.getString("languageId");
330    
331                                    return LocaleUtil.fromLanguageId(languageId);
332                            }
333                    }
334                    finally {
335                            DataAccess.cleanUp(con, ps, rs);
336                    }
337    
338                    return LocaleUtil.getSiteDefault();
339            }
340    
341            @Override
342            protected String[] getPortletIds() {
343                    return new String[] {
344                            "56_INSTANCE_%", "62_INSTANCE_%", "101_INSTANCE_%"
345                    };
346            }
347    
348            protected void updateAssetEntryClassTypeId() throws Exception {
349                    Connection con = null;
350                    PreparedStatement ps = null;
351                    ResultSet rs = null;
352    
353                    try {
354                            con = DataAccess.getUpgradeOptimizedConnection();
355    
356                            ps = con.prepareStatement(
357                                    "select companyId, groupId, resourcePrimKey, structureId " +
358                                            "from JournalArticle where structureId != ''");
359    
360                            rs = ps.executeQuery();
361    
362                            while (rs.next()) {
363                                    long groupId = rs.getLong("groupId");
364                                    long companyId = rs.getLong("companyId");
365                                    long resourcePrimKey = rs.getLong("resourcePrimKey");
366                                    String structureId = rs.getString("structureId");
367    
368                                    long ddmStructureId = getDDMStructureId(
369                                            groupId, getCompanyGroupId(companyId), structureId);
370    
371                                    runSQL(
372                                            "update AssetEntry set classTypeId = " +
373                                                    ddmStructureId + " where classPK = " + resourcePrimKey);
374                            }
375                    }
376                    finally {
377                            DataAccess.cleanUp(con, ps, rs);
378                    }
379            }
380    
381            protected void updatePreferencesClassPKs(
382                            PortletPreferences preferences, String key)
383                    throws Exception {
384    
385                    String[] oldValues = preferences.getValues(key, null);
386    
387                    if (oldValues == null) {
388                            return;
389                    }
390    
391                    String[] newValues = new String[oldValues.length];
392    
393                    for (int i = 0; i < oldValues.length; i++) {
394                            String oldValue = oldValues[i];
395    
396                            String newValue = oldValue;
397    
398                            String[] oldPrimaryKeys = StringUtil.split(oldValue);
399    
400                            for (String oldPrimaryKey : oldPrimaryKeys) {
401                                    if (!Validator.isNumber(oldPrimaryKey)) {
402                                            break;
403                                    }
404    
405                                    Long newPrimaryKey = _ddmStructurePKs.get(
406                                            GetterUtil.getLong(oldPrimaryKey));
407    
408                                    if (Validator.isNotNull(newPrimaryKey)) {
409                                            newValue = StringUtil.replace(
410                                                    newValue, oldPrimaryKey, String.valueOf(newPrimaryKey));
411                                    }
412                            }
413    
414                            newValues[i] = newValue;
415                    }
416    
417                    preferences.setValues(key, newValues);
418            }
419    
420            protected void updateResourcePermission(
421                            long companyId, String oldClassName, String newClassName,
422                            long oldPrimKey, long newPrimKey)
423                    throws Exception {
424    
425                    StringBundler sb = new StringBundler(11);
426    
427                    sb.append("update ResourcePermission set name = '");
428                    sb.append(newClassName);
429                    sb.append("', primKey = '");
430                    sb.append(newPrimKey);
431                    sb.append("' where companyId = ");
432                    sb.append(companyId);
433                    sb.append(" and name = '");
434                    sb.append(oldClassName);
435                    sb.append("' and primKey = '");
436                    sb.append(oldPrimKey);
437                    sb.append("'");
438    
439                    runSQL(sb.toString());
440            }
441    
442            protected long updateStructure(ResultSet rs) throws Exception {
443                    String uuid_ = rs.getString("uuid_");
444                    long id_ = rs.getLong("id_");
445                    long groupId = rs.getLong("groupId");
446                    long companyId = rs.getLong("companyId");
447                    long userId = rs.getLong("userId");
448                    String userName = rs.getString("userName");
449                    Timestamp createDate = rs.getTimestamp("createDate");
450                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
451                    String structureId = rs.getString("structureId");
452                    String parentStructureId = rs.getString("parentStructureId");
453                    String name = rs.getString("name");
454                    String description = rs.getString("description");
455                    String xsd = rs.getString("xsd");
456    
457                    Long ddmStructureId = _ddmStructureIds.get(groupId + "#" + structureId);
458    
459                    if (ddmStructureId != null) {
460                            return ddmStructureId;
461                    }
462    
463                    ddmStructureId = increment();
464    
465                    addDDMStructure(
466                            uuid_, ddmStructureId, groupId, companyId, userId, userName,
467                            createDate, modifiedDate, parentStructureId, structureId, name,
468                            description, xsd);
469    
470                    updateResourcePermission(
471                            companyId, "com.liferay.portlet.journal.model.JournalStructure",
472                            "com.liferay.portlet.dynamicdatamapping.DDMStructure", id_,
473                            ddmStructureId);
474    
475                    _ddmStructureIds.put(groupId + "#" + structureId, ddmStructureId);
476                    _ddmStructurePKs.put(id_, ddmStructureId);
477    
478                    return ddmStructureId;
479            }
480    
481            protected long updateStructure(String structureId) throws Exception {
482                    Connection con = null;
483                    PreparedStatement ps = null;
484                    ResultSet rs = null;
485    
486                    try {
487                            con = DataAccess.getUpgradeOptimizedConnection();
488    
489                            ps = con.prepareStatement(
490                                    "select * from JournalStructure where structureId = ?");
491    
492                            ps.setString(1, structureId);
493    
494                            rs = ps.executeQuery();
495    
496                            if (rs.next()) {
497                                    return updateStructure(rs);
498                            }
499    
500                            return 0;
501                    }
502                    catch (Exception e) {
503                            _log.error(
504                                    "Unable to update journal structure with structure ID " +
505                                            structureId);
506    
507                            throw e;
508                    }
509                    finally {
510                            DataAccess.cleanUp(con, ps, rs);
511                    }
512            }
513    
514            protected void updateStructures() throws Exception {
515                    Connection con = null;
516                    PreparedStatement ps = null;
517                    ResultSet rs = null;
518    
519                    try {
520                            con = DataAccess.getUpgradeOptimizedConnection();
521    
522                            ps = con.prepareStatement("select * from JournalStructure");
523    
524                            rs = ps.executeQuery();
525    
526                            while (rs.next()) {
527                                    updateStructure(rs);
528                            }
529                    }
530                    finally {
531                            DataAccess.cleanUp(con, ps, rs);
532                    }
533    
534                    runSQL("drop table JournalStructure");
535            }
536    
537            protected void updateTemplates() throws Exception {
538                    Connection con = null;
539                    PreparedStatement ps = null;
540                    ResultSet rs = null;
541    
542                    try {
543                            con = DataAccess.getUpgradeOptimizedConnection();
544    
545                            ps = con.prepareStatement("select * from JournalTemplate");
546    
547                            rs = ps.executeQuery();
548    
549                            while (rs.next()) {
550                                    String uuid_ = rs.getString("uuid_");
551                                    long id_ = rs.getLong("id_");
552                                    long groupId = rs.getLong("groupId");
553                                    long companyId = rs.getLong("companyId");
554                                    long userId = rs.getLong("userId");
555                                    String userName = rs.getString("userName");
556                                    Timestamp createDate = rs.getTimestamp("createDate");
557                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
558                                    String templateId = rs.getString("templateId");
559                                    String structureId = rs.getString("structureId");
560                                    String name = rs.getString("name");
561                                    String description = rs.getString("description");
562                                    String language = rs.getString("langType");
563                                    String script = rs.getString("xsl");
564                                    boolean cacheable = rs.getBoolean("cacheable");
565                                    boolean smallImage = rs.getBoolean("smallImage");
566                                    long smallImageId = rs.getLong("smallImageId");
567                                    String smallImageURL = rs.getString("smallImageURL");
568    
569                                    long ddmTemplateId = increment();
570    
571                                    long classNameId = getDDMStructureClassNameId();
572    
573                                    long classPK = getDDMStructureId(
574                                            groupId, getCompanyGroupId(companyId), structureId);
575    
576                                    addDDMTemplate(
577                                            uuid_, ddmTemplateId, groupId, companyId, userId, userName,
578                                            createDate, modifiedDate, classNameId, classPK, templateId,
579                                            name, description, _DDM_TEMPLATE_TYPE_DISPLAY,
580                                            _DDM_TEMPLATE_MODE_CREATE, language, script, cacheable,
581                                            smallImage, smallImageId, smallImageURL);
582    
583                                    updateResourcePermission(
584                                            companyId,
585                                            "com.liferay.portlet.journal.model.JournalTemplate",
586                                            "com.liferay.portlet.dynamicdatamapping.DDMTemplate", id_,
587                                            ddmTemplateId);
588                            }
589                    }
590                    finally {
591                            DataAccess.cleanUp(con, ps, rs);
592                    }
593    
594                    runSQL("drop table JournalTemplate");
595            }
596    
597            @Override
598            protected String upgradePreferences(
599                            long companyId, long ownerId, int ownerType, long plid,
600                            String portletId, String xml)
601                    throws Exception {
602    
603                    PortletPreferences preferences = PortletPreferencesFactoryUtil.fromXML(
604                            companyId, ownerId, ownerType, plid, portletId, xml);
605    
606                    if (portletId.startsWith(_PORTLET_ID_ASSET_PUBLISHER)) {
607                            updatePreferencesClassPKs(
608                                    preferences, "anyClassTypeJournalArticleAssetRendererFactory");
609                            updatePreferencesClassPKs(preferences, "classTypeIds");
610                            updatePreferencesClassPKs(
611                                    preferences, "classTypeIdsJournalArticleAssetRendererFactory");
612                    }
613                    else if (portletId.startsWith(_PORTLET_ID_JOURNAL_CONTENT)) {
614                            String templateId = preferences.getValue(
615                                    "templateId", StringPool.BLANK);
616    
617                            if (Validator.isNotNull(templateId)) {
618                                    preferences.reset("templateId");
619    
620                                    preferences.setValue("ddmTemplateKey", templateId);
621                            }
622                    }
623                    else if (portletId.startsWith(_PORTLET_ID_JOURNAL_CONTENT_LIST)) {
624                            String structureId = preferences.getValue(
625                                    "structureId", StringPool.BLANK);
626    
627                            if (Validator.isNotNull(structureId)) {
628                                    preferences.reset("structureId");
629    
630                                    preferences.setValue("ddmStructureKey", structureId);
631                            }
632                    }
633    
634                    return PortletPreferencesFactoryUtil.toXML(preferences);
635            }
636    
637            private static final int _DDM_STRUCTURE_TYPE_DEFAULT = 0;
638    
639            private static final String _DDM_TEMPLATE_MODE_CREATE = "create";
640    
641            private static final String _DDM_TEMPLATE_TYPE_DISPLAY = "display";
642    
643            private static final String _PORTLET_ID_ASSET_PUBLISHER = "101";
644    
645            private static final String _PORTLET_ID_JOURNAL_CONTENT = "56";
646    
647            private static final String _PORTLET_ID_JOURNAL_CONTENT_LIST = "62";
648    
649            private static final Log _log = LogFactoryUtil.getLog(UpgradeJournal.class);
650    
651            private final Map<String, Long> _ddmStructureIds = new HashMap<>();
652            private final Map<Long, Long> _ddmStructurePKs = new HashMap<>();
653    
654    }