001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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                    updateAssetEntryClassTypeId();
231    
232                    super.doUpgrade();
233            }
234    
235            protected long getDDMStructureId(long groupId, String structureId) {
236                    return getDDMStructureId(groupId, structureId, true);
237            }
238    
239            protected long getDDMStructureId(
240                    long groupId, String structureId, boolean warn) {
241    
242                    if (Validator.isNull(structureId)) {
243                            return 0;
244                    }
245    
246                    Long ddmStructureId = _ddmStructureIds.get(groupId + "#" + structureId);
247    
248                    if (ddmStructureId == null) {
249                            if (warn) {
250                                    if (_log.isWarnEnabled()) {
251                                            _log.warn(
252                                                    "Unable to get the DDM structure ID for group " +
253                                                            groupId + " and journal structure ID " +
254                                                                    structureId);
255                                    }
256                            }
257    
258                            return 0;
259                    }
260    
261                    return ddmStructureId;
262            }
263    
264            protected Locale getDefaultLocale(String xml) {
265                    String defaultLanguageId = LocalizationUtil.getDefaultLanguageId(xml);
266    
267                    return LocaleUtil.fromLanguageId(defaultLanguageId);
268            }
269    
270            @Override
271            protected String[] getPortletIds() {
272                    return new String[] {
273                            "56_INSTANCE_%", "62_INSTANCE_%", "101_INSTANCE_%"
274                    };
275            }
276    
277            protected void updateAssetEntryClassTypeId() throws Exception {
278                    Connection con = null;
279                    PreparedStatement ps = null;
280                    ResultSet rs = null;
281    
282                    try {
283                            con = DataAccess.getUpgradeOptimizedConnection();
284    
285                            ps = con.prepareStatement(
286                                    "select groupId, resourcePrimKey, structureId from " +
287                                            "JournalArticle where structureId != ''");
288    
289                            rs = ps.executeQuery();
290    
291                            while (rs.next()) {
292                                    long groupId = rs.getLong("groupId");
293                                    long resourcePrimKey = rs.getLong("resourcePrimKey");
294                                    String structureId = rs.getString("structureId");
295    
296                                    long ddmStructureId = getDDMStructureId(groupId, structureId);
297    
298                                    runSQL(
299                                            "update AssetEntry set classTypeId = " +
300                                                    ddmStructureId + " where classPK = " + resourcePrimKey);
301                            }
302                    }
303                    finally {
304                            DataAccess.cleanUp(con, ps, rs);
305                    }
306            }
307    
308            protected void updatePreferencesClassPKs(
309                            PortletPreferences preferences, String key)
310                    throws Exception {
311    
312                    String[] oldValues = preferences.getValues(key, null);
313    
314                    if (oldValues == null) {
315                            return;
316                    }
317    
318                    String[] newValues = new String[oldValues.length];
319    
320                    for (int i = 0; i < oldValues.length; i++) {
321                            String oldValue = oldValues[i];
322    
323                            String newValue = oldValue;
324    
325                            String[] oldPrimaryKeys = StringUtil.split(oldValue);
326    
327                            for (String oldPrimaryKey : oldPrimaryKeys) {
328                                    if (!Validator.isNumber(oldPrimaryKey)) {
329                                            break;
330                                    }
331    
332                                    Long newPrimaryKey = _ddmStructurePKs.get(
333                                            GetterUtil.getLong(oldPrimaryKey));
334    
335                                    if (Validator.isNotNull(newPrimaryKey)) {
336                                            newValue = StringUtil.replace(
337                                                    newValue, oldPrimaryKey, String.valueOf(newPrimaryKey));
338                                    }
339                            }
340    
341                            newValues[i] = newValue;
342                    }
343    
344                    preferences.setValues(key, newValues);
345            }
346    
347            protected void updateResourcePermission(
348                            long companyId, String oldClassName, String newClassName,
349                            long oldPrimKey, long newPrimKey)
350                    throws Exception {
351    
352                    StringBundler sb = new StringBundler(11);
353    
354                    sb.append("update ResourcePermission set name = '");
355                    sb.append(newClassName);
356                    sb.append("', primKey = '");
357                    sb.append(newPrimKey);
358                    sb.append("' where companyId = ");
359                    sb.append(companyId);
360                    sb.append(" and name = '");
361                    sb.append(oldClassName);
362                    sb.append("' and primKey = '");
363                    sb.append(oldPrimKey);
364                    sb.append("'");
365    
366                    runSQL(sb.toString());
367            }
368    
369            protected long updateStructure(String structureId) throws Exception {
370                    Connection con = null;
371                    PreparedStatement ps = null;
372                    ResultSet rs = null;
373    
374                    try {
375                            con = DataAccess.getUpgradeOptimizedConnection();
376    
377                            ps = con.prepareStatement(
378                                    "select * from JournalStructure where structureId = ?");
379    
380                            ps.setString(1, structureId);
381    
382                            rs = ps.executeQuery();
383    
384                            if (rs.next()) {
385                                    String uuid_ = rs.getString("uuid_");
386                                    long id_ = rs.getLong("id_");
387                                    long groupId = rs.getLong("groupId");
388                                    long companyId = rs.getLong("companyId");
389                                    long userId = rs.getLong("userId");
390                                    String userName = rs.getString("userName");
391                                    Timestamp createDate = rs.getTimestamp("createDate");
392                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
393                                    String parentStructureId = rs.getString("parentStructureId");
394                                    String name = rs.getString("name");
395                                    String description = rs.getString("description");
396                                    String xsd = rs.getString("xsd");
397    
398                                    Long ddmStructureId = _ddmStructureIds.get(
399                                            groupId + "#" + structureId);
400    
401                                    if (ddmStructureId != null) {
402                                            return ddmStructureId;
403                                    }
404    
405                                    ddmStructureId = increment();
406    
407                                    addDDMStructure(
408                                            uuid_, ddmStructureId, groupId, companyId, userId, userName,
409                                            createDate, modifiedDate, parentStructureId, structureId,
410                                            name, description, xsd);
411    
412                                    updateResourcePermission(
413                                            companyId, JournalStructure.class.getName(),
414                                            DDMStructure.class.getName(), id_, ddmStructureId);
415    
416                                    _ddmStructureIds.put(
417                                            groupId + "#" + structureId, ddmStructureId);
418    
419                                    return ddmStructureId;
420                            }
421    
422                            return 0;
423                    }
424                    catch (Exception e) {
425                            _log.error(
426                                    "Unable to update journal structure with structure ID " +
427                                            structureId);
428    
429                            throw e;
430                    }
431                    finally {
432                            DataAccess.cleanUp(con, ps, rs);
433                    }
434            }
435    
436            protected void updateStructures() throws Exception {
437                    Connection con = null;
438                    PreparedStatement ps = null;
439                    ResultSet rs = null;
440    
441                    try {
442                            con = DataAccess.getUpgradeOptimizedConnection();
443    
444                            ps = con.prepareStatement("select * from JournalStructure");
445    
446                            rs = ps.executeQuery();
447    
448                            while (rs.next()) {
449                                    String uuid_ = rs.getString("uuid_");
450                                    long id_ = rs.getLong("id_");
451                                    long groupId = rs.getLong("groupId");
452                                    long companyId = rs.getLong("companyId");
453                                    long userId = rs.getLong("userId");
454                                    String userName = rs.getString("userName");
455                                    Timestamp createDate = rs.getTimestamp("createDate");
456                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
457                                    String structureId = rs.getString("structureId");
458                                    String parentStructureId = rs.getString("parentStructureId");
459                                    String name = rs.getString("name");
460                                    String description = rs.getString("description");
461                                    String xsd = rs.getString("xsd");
462    
463                                    long ddmStructureId = increment();
464    
465                                    addDDMStructure(
466                                            uuid_, ddmStructureId, groupId, companyId, userId, userName,
467                                            createDate, modifiedDate, parentStructureId, structureId,
468                                            name, description, xsd);
469    
470                                    updateResourcePermission(
471                                            companyId, JournalStructure.class.getName(),
472                                            DDMStructure.class.getName(), id_, ddmStructureId);
473    
474                                    if (_ddmStructureIds.get(groupId + "#" + structureId) == null) {
475                                            _ddmStructureIds.put(
476                                                    groupId + "#" + structureId, ddmStructureId);
477                                    }
478    
479                                    _ddmStructurePKs.put(id_, ddmStructureId);
480                            }
481                    }
482                    finally {
483                            DataAccess.cleanUp(con, ps, rs);
484                    }
485    
486                    runSQL("drop table JournalStructure");
487            }
488    
489            protected void updateTemplates() throws Exception {
490                    Connection con = null;
491                    PreparedStatement ps = null;
492                    ResultSet rs = null;
493    
494                    try {
495                            con = DataAccess.getUpgradeOptimizedConnection();
496    
497                            ps = con.prepareStatement("select * from JournalTemplate");
498    
499                            rs = ps.executeQuery();
500    
501                            while (rs.next()) {
502                                    String uuid_ = rs.getString("uuid_");
503                                    long id_ = rs.getLong("id_");
504                                    long groupId = rs.getLong("groupId");
505                                    long companyId = rs.getLong("companyId");
506                                    long userId = rs.getLong("userId");
507                                    String userName = rs.getString("userName");
508                                    Timestamp createDate = rs.getTimestamp("createDate");
509                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
510                                    String templateId = rs.getString("templateId");
511                                    String structureId = rs.getString("structureId");
512                                    String name = rs.getString("name");
513                                    String description = rs.getString("description");
514                                    String language = rs.getString("langType");
515                                    String script = rs.getString("xsl");
516                                    boolean cacheable = rs.getBoolean("cacheable");
517                                    boolean smallImage = rs.getBoolean("smallImage");
518                                    long smallImageId = rs.getLong("smallImageId");
519                                    String smallImageURL = rs.getString("smallImageURL");
520    
521                                    long ddmTemplateId = increment();
522    
523                                    long classNameId = PortalUtil.getClassNameId(
524                                            DDMStructure.class.getName());
525    
526                                    long classPK = getDDMStructureId(groupId, structureId);
527    
528                                    addDDMTemplate(
529                                            uuid_, ddmTemplateId, groupId, companyId, userId, userName,
530                                            createDate, modifiedDate, classNameId, classPK, templateId,
531                                            name, description,
532                                            DDMTemplateConstants.TEMPLATE_TYPE_DISPLAY,
533                                            DDMTemplateConstants.TEMPLATE_MODE_CREATE, language, script,
534                                            cacheable, smallImage, smallImageId, smallImageURL);
535    
536                                    updateResourcePermission(
537                                            companyId, JournalTemplate.class.getName(),
538                                            DDMTemplate.class.getName(), id_, ddmTemplateId);
539                            }
540                    }
541                    finally {
542                            DataAccess.cleanUp(con, ps, rs);
543                    }
544    
545                    runSQL("drop table JournalTemplate");
546            }
547    
548            @Override
549            protected String upgradePreferences(
550                            long companyId, long ownerId, int ownerType, long plid,
551                            String portletId, String xml)
552                    throws Exception {
553    
554                    PortletPreferences preferences = PortletPreferencesFactoryUtil.fromXML(
555                            companyId, ownerId, ownerType, plid, portletId, xml);
556    
557                    if (portletId.startsWith(PortletKeys.ASSET_PUBLISHER)) {
558                            updatePreferencesClassPKs(
559                                    preferences, "anyClassTypeJournalArticleAssetRendererFactory");
560                            updatePreferencesClassPKs(preferences, "classTypeIds");
561                            updatePreferencesClassPKs(
562                                    preferences, "classTypeIdsJournalArticleAssetRendererFactory");
563                    }
564                    else if (portletId.startsWith(PortletKeys.JOURNAL_CONTENT)) {
565                            String templateId = preferences.getValue(
566                                    "templateId", StringPool.BLANK);
567    
568                            if (Validator.isNotNull(templateId)) {
569                                    preferences.reset("templateId");
570    
571                                    preferences.setValue("ddmTemplateKey", templateId);
572                            }
573                    }
574                    else if (portletId.startsWith(PortletKeys.JOURNAL_CONTENT_LIST)) {
575                            String structureId = preferences.getValue(
576                                    "structureId", StringPool.BLANK);
577    
578                            if (Validator.isNotNull(structureId)) {
579                                    preferences.reset("structureId");
580    
581                                    preferences.setValue("ddmStructureKey", structureId);
582                            }
583                    }
584    
585                    return PortletPreferencesFactoryUtil.toXML(preferences);
586            }
587    
588            private static Log _log = LogFactoryUtil.getLog(UpgradeJournal.class);
589    
590            private Map<String, Long> _ddmStructureIds = new HashMap<String, Long>();
591            private Map<Long, Long> _ddmStructurePKs = new HashMap<Long, Long>();
592    
593    }