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