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