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.LocalizationUtil;
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.util.Validator;
028    import com.liferay.portal.upgrade.v6_2_0.util.JournalFeedTable;
029    import com.liferay.portal.util.PortalUtil;
030    import com.liferay.portal.util.PortletKeys;
031    import com.liferay.portal.util.PropsValues;
032    import com.liferay.portlet.PortletPreferencesFactoryUtil;
033    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
034    import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
035    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
036    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
037    import com.liferay.portlet.journal.model.JournalArticle;
038    import com.liferay.portlet.journal.util.JournalConverterUtil;
039    
040    import java.sql.Connection;
041    import java.sql.PreparedStatement;
042    import java.sql.ResultSet;
043    import java.sql.SQLException;
044    import java.sql.Timestamp;
045    
046    import java.util.HashMap;
047    import java.util.Locale;
048    import java.util.Map;
049    
050    import javax.portlet.PortletPreferences;
051    
052    /**
053     * @author Brian Wing Shun Chan
054     * @author Marcellus Tavares
055     * @author Juan Fern??ndez
056     * @author Bruno Basto
057     */
058    public class UpgradeJournal extends BaseUpgradePortletPreferences {
059    
060            protected void addDDMStructure(
061                            String uuid_, long ddmStructureId, long groupId, long companyId,
062                            long userId, String userName, Timestamp createDate,
063                            Timestamp modifiedDate, long parentDDMStructureId, long classNameId,
064                            String ddmStructureKey, String name, String description, String xsd,
065                            String storageType, int type)
066                    throws Exception {
067    
068                    Connection con = null;
069                    PreparedStatement ps = null;
070    
071                    try {
072                            con = DataAccess.getUpgradeOptimizedConnection();
073    
074                            StringBundler sb = new StringBundler(6);
075    
076                            sb.append("insert into DDMStructure (uuid_, structureId, ");
077                            sb.append("groupId, companyId, userId, userName, createDate, ");
078                            sb.append("modifiedDate, parentStructureId, classNameId, ");
079                            sb.append("structureKey, name, description, xsd, storageType, ");
080                            sb.append("type_) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ");
081                            sb.append("?, ?, ?)");
082    
083                            String sql = sb.toString();
084    
085                            ps = con.prepareStatement(sql);
086    
087                            ps.setString(1, uuid_);
088                            ps.setLong(2, ddmStructureId);
089                            ps.setLong(3, groupId);
090                            ps.setLong(4, companyId);
091                            ps.setLong(5, userId);
092                            ps.setString(6, userName);
093                            ps.setTimestamp(7, createDate);
094                            ps.setTimestamp(8, modifiedDate);
095                            ps.setLong(9, parentDDMStructureId);
096                            ps.setLong(10, classNameId);
097                            ps.setString(11, ddmStructureKey);
098                            ps.setString(12, name);
099                            ps.setString(13, description);
100                            ps.setString(
101                                    14,
102                                    JournalConverterUtil.getDDMXSD(xsd, getDefaultLocale(name)));
103                            ps.setString(15, storageType);
104                            ps.setInt(16, type);
105    
106                            ps.executeUpdate();
107                    }
108                    catch (Exception e) {
109                            _log.error(
110                                    "Unable to upgrade dynamic data mapping structure with UUID " +
111                                            uuid_);
112    
113                            throw e;
114                    }
115                    finally {
116                            DataAccess.cleanUp(con, ps);
117                    }
118            }
119    
120            protected void addDDMStructure(
121                            String uuid_, long ddmStructureId, long groupId, long companyId,
122                            long userId, String userName, Timestamp createDate,
123                            Timestamp modifiedDate, String parentStructureId,
124                            String ddmStructureKey, String name, String description, String xsd)
125                    throws Exception {
126    
127                    long parentDDMStructureId = 0;
128    
129                    if (Validator.isNotNull(parentStructureId)) {
130                            parentDDMStructureId = updateStructure(parentStructureId);
131                    }
132    
133                    long insertedDDMStructureId = getDDMStructureId(
134                            groupId, ddmStructureKey, false);
135    
136                    if (insertedDDMStructureId == 0) {
137                            addDDMStructure(
138                                    uuid_, ddmStructureId, groupId, companyId, userId, userName,
139                                    createDate, modifiedDate, parentDDMStructureId,
140                                    PortalUtil.getClassNameId(JournalArticle.class.getName()),
141                                    ddmStructureKey, name, description, xsd,
142                                    PropsValues.JOURNAL_ARTICLE_STORAGE_TYPE,
143                                    DDMStructureConstants.TYPE_DEFAULT);
144                    }
145            }
146    
147            protected void addDDMTemplate(
148                            String uuid_, long ddmTemplateId, long groupId, long companyId,
149                            long userId, String userName, Timestamp createDate,
150                            Timestamp modifiedDate, long classNameId, long classPK,
151                            String templateKey, String name, String description, String type,
152                            String mode, String language, String script, boolean cacheable,
153                            boolean smallImage, long smallImageId, String smallImageURL)
154                    throws Exception {
155    
156                    Connection con = null;
157                    PreparedStatement ps = null;
158    
159                    try {
160                            con = DataAccess.getUpgradeOptimizedConnection();
161    
162                            StringBundler sb = new StringBundler(6);
163    
164                            sb.append("insert into DDMTemplate (uuid_, templateId, groupId, ");
165                            sb.append("companyId, userId, userName, createDate, modifiedDate,");
166                            sb.append("classNameId, classPK , templateKey, name, description,");
167                            sb.append("type_, mode_, language, script, cacheable, smallImage,");
168                            sb.append("smallImageId, smallImageURL) values (?, ?, ?, ?, ?, ?,");
169                            sb.append("?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
170    
171                            String sql = sb.toString();
172    
173                            ps = con.prepareStatement(sql);
174    
175                            ps.setString(1, uuid_);
176                            ps.setLong(2, ddmTemplateId);
177                            ps.setLong(3, groupId);
178                            ps.setLong(4, companyId);
179                            ps.setLong(5, userId);
180                            ps.setString(6, userName);
181                            ps.setTimestamp(7, createDate);
182                            ps.setTimestamp(8, modifiedDate);
183                            ps.setLong(9, classNameId);
184                            ps.setLong(10, classPK);
185                            ps.setString(11, templateKey);
186                            ps.setString(12, name);
187                            ps.setString(13, description);
188                            ps.setString(14, type);
189                            ps.setString(15, mode);
190                            ps.setString(16, language);
191                            ps.setString(17, script);
192                            ps.setBoolean(18, cacheable);
193                            ps.setBoolean(19, smallImage);
194                            ps.setLong(20, smallImageId);
195                            ps.setString(21, smallImageURL);
196    
197                            ps.executeUpdate();
198                    }
199                    catch (Exception e) {
200                            _log.error(
201                                    "Unable to upgrade dynamic data mapping template with UUID " +
202                                            uuid_);
203    
204                            throw e;
205                    }
206                    finally {
207                            DataAccess.cleanUp(con, ps);
208                    }
209            }
210    
211            @Override
212            protected void doUpgrade() throws Exception {
213                    try {
214                            runSQL(
215                                    "alter_column_name JournalFeed feedType feedFormat " +
216                                            "VARCHAR(75) null");
217                    }
218                    catch (SQLException sqle) {
219                            upgradeTable(
220                                    JournalFeedTable.TABLE_NAME, JournalFeedTable.TABLE_COLUMNS,
221                                    JournalFeedTable.TABLE_SQL_CREATE,
222                                    JournalFeedTable.TABLE_SQL_ADD_INDEXES);
223                    }
224    
225                    updateStructures();
226                    updateTemplates();
227    
228                    super.doUpgrade();
229            }
230    
231            protected long getDDMStructureId(long groupId, String structureId) {
232                    return getDDMStructureId(groupId, structureId, true);
233            }
234    
235            protected long getDDMStructureId(
236                    long groupId, String structureId, boolean warn) {
237    
238                    if (Validator.isNull(structureId)) {
239                            return 0;
240                    }
241    
242                    Long ddmStructureId = _ddmStructureIds.get(groupId + "#" + structureId);
243    
244                    if (ddmStructureId == null) {
245                            if (warn) {
246                                    if (_log.isWarnEnabled()) {
247                                            _log.warn(
248                                                    "Unable to get the DDM structure ID for group " +
249                                                            groupId + " and journal structure ID " +
250                                                                    structureId);
251                                    }
252                            }
253    
254                            return 0;
255                    }
256    
257                    return ddmStructureId;
258            }
259    
260            protected Locale getDefaultLocale(String xml) {
261                    String defaultLanguageId = LocalizationUtil.getDefaultLanguageId(xml);
262    
263                    return LocaleUtil.fromLanguageId(defaultLanguageId);
264            }
265    
266            @Override
267            protected String[] getPortletIds() {
268                    return new String[] {
269                            "56_INSTANCE_%", "62_INSTANCE_%", "101_INSTANCE_%"
270                    };
271            }
272    
273            protected void updatePreferencesClassPKs(
274                            PortletPreferences preferences, String key)
275                    throws Exception {
276    
277                    String[] oldValues = preferences.getValues(key, null);
278    
279                    if (oldValues == null) {
280                            return;
281                    }
282    
283                    String[] newValues = new String[oldValues.length];
284    
285                    for (int i = 0; i < oldValues.length; i++) {
286                            String oldValue = oldValues[i];
287    
288                            String newValue = oldValue;
289    
290                            String[] oldPrimaryKeys = StringUtil.split(oldValue);
291    
292                            for (String oldPrimaryKey : oldPrimaryKeys) {
293                                    if (!Validator.isNumber(oldPrimaryKey)) {
294                                            break;
295                                    }
296    
297                                    Long newPrimaryKey = _ddmStructurePKs.get(
298                                            GetterUtil.getLong(oldPrimaryKey));
299    
300                                    if (Validator.isNotNull(newPrimaryKey)) {
301                                            newValue = StringUtil.replace(
302                                                    newValue, oldPrimaryKey, String.valueOf(newPrimaryKey));
303                                    }
304                            }
305    
306                            newValues[i] = newValue;
307                    }
308    
309                    preferences.setValues(key, newValues);
310            }
311    
312            protected void updateResourcePermission(
313                            long companyId, String oldClassName, String newClassName,
314                            long oldPrimKey, long newPrimKey)
315                    throws Exception {
316    
317                    StringBundler sb = new StringBundler(11);
318    
319                    sb.append("update ResourcePermission set name = '");
320                    sb.append(newClassName);
321                    sb.append("', primKey = '");
322                    sb.append(newPrimKey);
323                    sb.append("' where companyId = ");
324                    sb.append(companyId);
325                    sb.append(" and name = '");
326                    sb.append(oldClassName);
327                    sb.append("' and primKey = '");
328                    sb.append(oldPrimKey);
329                    sb.append("'");
330    
331                    runSQL(sb.toString());
332            }
333    
334            protected long updateStructure(ResultSet rs) throws Exception {
335                    String uuid_ = rs.getString("uuid_");
336                    long id_ = rs.getLong("id_");
337                    long groupId = rs.getLong("groupId");
338                    long companyId = rs.getLong("companyId");
339                    long userId = rs.getLong("userId");
340                    String userName = rs.getString("userName");
341                    Timestamp createDate = rs.getTimestamp("createDate");
342                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
343                    String structureId = rs.getString("structureId");
344                    String parentStructureId = rs.getString("parentStructureId");
345                    String name = rs.getString("name");
346                    String description = rs.getString("description");
347                    String xsd = rs.getString("xsd");
348    
349                    Long ddmStructureId = _ddmStructureIds.get(groupId + "#" + structureId);
350    
351                    if (ddmStructureId != null) {
352                            return ddmStructureId;
353                    }
354    
355                    ddmStructureId = increment();
356    
357                    addDDMStructure(
358                            uuid_, ddmStructureId, groupId, companyId, userId, userName,
359                            createDate, modifiedDate, parentStructureId, structureId, name,
360                            description, xsd);
361    
362                    updateResourcePermission(
363                            companyId, "com.liferay.portlet.journal.model.JournalStructure",
364                            DDMStructure.class.getName(), id_, ddmStructureId);
365    
366                    _ddmStructureIds.put(groupId + "#" + structureId, ddmStructureId);
367                    _ddmStructurePKs.put(id_, ddmStructureId);
368    
369                    return 0;
370            }
371    
372            protected long updateStructure(String structureId) throws Exception {
373                    Connection con = null;
374                    PreparedStatement ps = null;
375                    ResultSet rs = null;
376    
377                    try {
378                            con = DataAccess.getUpgradeOptimizedConnection();
379    
380                            ps = con.prepareStatement(
381                                    "select * from JournalStructure where structureId = ?");
382    
383                            ps.setString(1, structureId);
384    
385                            rs = ps.executeQuery();
386    
387                            if (rs.next()) {
388                                    return updateStructure(rs);
389                            }
390    
391                            return 0;
392                    }
393                    catch (Exception e) {
394                            _log.error(
395                                    "Unable to update journal structure with structure ID " +
396                                            structureId);
397    
398                            throw e;
399                    }
400                    finally {
401                            DataAccess.cleanUp(con, ps, rs);
402                    }
403            }
404    
405            protected void updateStructures() throws Exception {
406                    Connection con = null;
407                    PreparedStatement ps = null;
408                    ResultSet rs = null;
409    
410                    try {
411                            con = DataAccess.getUpgradeOptimizedConnection();
412    
413                            ps = con.prepareStatement("select * from JournalStructure");
414    
415                            rs = ps.executeQuery();
416    
417                            while (rs.next()) {
418                                    updateStructure(rs);
419                            }
420                    }
421                    finally {
422                            DataAccess.cleanUp(con, ps, rs);
423                    }
424    
425                    runSQL("drop table JournalStructure");
426            }
427    
428            protected void updateTemplates() throws Exception {
429                    Connection con = null;
430                    PreparedStatement ps = null;
431                    ResultSet rs = null;
432    
433                    try {
434                            con = DataAccess.getUpgradeOptimizedConnection();
435    
436                            ps = con.prepareStatement("select * from JournalTemplate");
437    
438                            rs = ps.executeQuery();
439    
440                            while (rs.next()) {
441                                    String uuid_ = rs.getString("uuid_");
442                                    long id_ = rs.getLong("id_");
443                                    long groupId = rs.getLong("groupId");
444                                    long companyId = rs.getLong("companyId");
445                                    long userId = rs.getLong("userId");
446                                    String userName = rs.getString("userName");
447                                    Timestamp createDate = rs.getTimestamp("createDate");
448                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
449                                    String templateId = rs.getString("templateId");
450                                    String structureId = rs.getString("structureId");
451                                    String name = rs.getString("name");
452                                    String description = rs.getString("description");
453                                    String language = rs.getString("langType");
454                                    String script = rs.getString("xsl");
455                                    boolean cacheable = rs.getBoolean("cacheable");
456                                    boolean smallImage = rs.getBoolean("smallImage");
457                                    long smallImageId = rs.getLong("smallImageId");
458                                    String smallImageURL = rs.getString("smallImageURL");
459    
460                                    long ddmTemplateId = increment();
461    
462                                    long classNameId = PortalUtil.getClassNameId(
463                                            DDMStructure.class.getName());
464    
465                                    long classPK = getDDMStructureId(groupId, structureId);
466    
467                                    addDDMTemplate(
468                                            uuid_, ddmTemplateId, groupId, companyId, userId, userName,
469                                            createDate, modifiedDate, classNameId, classPK, templateId,
470                                            name, description,
471                                            DDMTemplateConstants.TEMPLATE_TYPE_DISPLAY,
472                                            DDMTemplateConstants.TEMPLATE_MODE_CREATE, language, script,
473                                            cacheable, smallImage, smallImageId, smallImageURL);
474    
475                                    updateResourcePermission(
476                                            companyId,
477                                            "com.liferay.portlet.journal.model.JournalTemplate",
478                                            DDMTemplate.class.getName(), id_, ddmTemplateId);
479                            }
480                    }
481                    finally {
482                            DataAccess.cleanUp(con, ps, rs);
483                    }
484    
485                    runSQL("drop table JournalTemplate");
486            }
487    
488            @Override
489            protected String upgradePreferences(
490                            long companyId, long ownerId, int ownerType, long plid,
491                            String portletId, String xml)
492                    throws Exception {
493    
494                    PortletPreferences preferences = PortletPreferencesFactoryUtil.fromXML(
495                            companyId, ownerId, ownerType, plid, portletId, xml);
496    
497                    if (portletId.startsWith(PortletKeys.ASSET_PUBLISHER)) {
498                            updatePreferencesClassPKs(
499                                    preferences, "anyClassTypeJournalArticleAssetRendererFactory");
500                            updatePreferencesClassPKs(preferences, "classTypeIds");
501                            updatePreferencesClassPKs(
502                                    preferences, "classTypeIdsJournalArticleAssetRendererFactory");
503                    }
504                    else if (portletId.startsWith(PortletKeys.JOURNAL_CONTENT)) {
505                            String templateId = preferences.getValue(
506                                    "templateId", StringPool.BLANK);
507    
508                            if (Validator.isNotNull(templateId)) {
509                                    preferences.reset("templateId");
510    
511                                    preferences.setValue("ddmTemplateKey", templateId);
512                            }
513                    }
514                    else if (portletId.startsWith(PortletKeys.JOURNAL_CONTENT_LIST)) {
515                            String structureId = preferences.getValue(
516                                    "structureId", StringPool.BLANK);
517    
518                            if (Validator.isNotNull(structureId)) {
519                                    preferences.reset("structureId");
520    
521                                    preferences.setValue("ddmStructureKey", structureId);
522                            }
523                    }
524    
525                    return PortletPreferencesFactoryUtil.toXML(preferences);
526            }
527    
528            private static Log _log = LogFactoryUtil.getLog(UpgradeJournal.class);
529    
530            private Map<String, Long> _ddmStructureIds = new HashMap<String, Long>();
531            private Map<Long, Long> _ddmStructurePKs = new HashMap<Long, Long>();
532    
533    }