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