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.v7_0_0;
016    
017    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
018    import com.liferay.portal.kernel.language.LanguageUtil;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
022    import com.liferay.portal.kernel.upgrade.util.UpgradeProcessUtil;
023    import com.liferay.portal.kernel.util.FileUtil;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.LocaleUtil;
026    import com.liferay.portal.kernel.util.LocalizationUtil;
027    import com.liferay.portal.kernel.util.StringPool;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.model.Company;
030    import com.liferay.portal.repository.liferayrepository.LiferayRepository;
031    import com.liferay.portal.repository.portletrepository.PortletRepository;
032    import com.liferay.portal.upgrade.v7_0_0.util.DLFolderTable;
033    import com.liferay.portal.util.PortalUtil;
034    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
035    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
036    import com.liferay.portlet.documentlibrary.util.DLUtil;
037    
038    import java.sql.Connection;
039    import java.sql.PreparedStatement;
040    import java.sql.ResultSet;
041    import java.sql.SQLException;
042    
043    import java.util.HashMap;
044    import java.util.Locale;
045    import java.util.Map;
046    
047    /**
048     * @author Michael Young
049     */
050    public class UpgradeDocumentLibrary extends UpgradeProcess {
051    
052            protected void addDDMStructureLink(
053                            long ddmStructureLinkId, long classNameId, long classPK,
054                            long ddmStructureId)
055                    throws Exception {
056    
057                    Connection con = null;
058                    PreparedStatement ps = null;
059    
060                    try {
061                            con = DataAccess.getUpgradeOptimizedConnection();
062    
063                            ps = con.prepareStatement(
064                                    "insert into DDMStructureLink (structureLinkId, classNameId, " +
065                                            "classPK, structureId) values (?, ?, ?, ?)");
066    
067                            ps.setLong(1, ddmStructureLinkId);
068                            ps.setLong(2, classNameId);
069                            ps.setLong(3, classPK);
070                            ps.setLong(4, ddmStructureId);
071    
072                            ps.executeUpdate();
073                    }
074                    catch (Exception e) {
075                            _log.error(
076                                    "Unable to add dynamic data mapping structure link " +
077                                            "for file entry type " + classPK);
078    
079                            throw e;
080                    }
081                    finally {
082                            DataAccess.cleanUp(con, ps);
083                    }
084            }
085    
086            @Override
087            protected void doUpgrade() throws Exception {
088    
089                    // DLFileEntry
090    
091                    updateFileEntryFileNames();
092    
093                    // DLFileEntryType
094    
095                    updateFileEntryTypeNamesAndDescriptions();
096    
097                    updateFileEntryTypeDDMStructureLinks();
098    
099                    // DLFileVersion
100    
101                    updateFileVersionFileNames();
102    
103                    // DLFolder
104    
105                    try {
106                            runSQL("alter_column_type DLFolder name VARCHAR(255) null");
107                    }
108                    catch (SQLException sqle) {
109                            upgradeTable(
110                                    DLFolderTable.TABLE_NAME, DLFolderTable.TABLE_COLUMNS,
111                                    DLFolderTable.TABLE_SQL_CREATE,
112                                    DLFolderTable.TABLE_SQL_ADD_INDEXES);
113                    }
114    
115                    updateRepositoryClassNameIds();
116            }
117    
118            protected boolean hasFileEntry(long groupId, long folderId, String fileName)
119                    throws Exception {
120    
121                    Connection con = null;
122                    PreparedStatement ps = null;
123                    ResultSet rs = null;
124    
125                    try {
126                            con = DataAccess.getUpgradeOptimizedConnection();
127    
128                            ps = con.prepareStatement(
129                                    "select count(*) from DLFileEntry where groupId = ? and " +
130                                            "folderId = ? and fileName = ?");
131    
132                            ps.setLong(1, groupId);
133                            ps.setLong(2, folderId);
134                            ps.setString(3, fileName);
135    
136                            rs = ps.executeQuery();
137    
138                            while (rs.next()) {
139                                    int count = rs.getInt(1);
140    
141                                    if (count > 0) {
142                                            return true;
143                                    }
144                            }
145    
146                            return false;
147                    }
148                    finally {
149                            DataAccess.cleanUp(con, ps, rs);
150                    }
151            }
152    
153            protected void updateFileEntryFileName(long fileEntryId, String fileName)
154                    throws Exception {
155    
156                    Connection con = null;
157                    PreparedStatement ps = null;
158    
159                    try {
160                            con = DataAccess.getUpgradeOptimizedConnection();
161    
162                            ps = con.prepareStatement(
163                                    "update DLFileEntry set fileName = ? where fileEntryId = ?");
164    
165                            ps.setString(1, fileName);
166                            ps.setLong(2, fileEntryId);
167    
168                            ps.executeUpdate();
169                    }
170                    finally {
171                            DataAccess.cleanUp(con, ps);
172                    }
173            }
174    
175            protected void updateFileEntryFileNames() throws Exception {
176                    runSQL("alter table DLFileEntry add fileName VARCHAR(255) null");
177    
178                    Connection con = null;
179                    PreparedStatement ps = null;
180                    ResultSet rs = null;
181    
182                    try {
183                            con = DataAccess.getUpgradeOptimizedConnection();
184    
185                            ps = con.prepareStatement(
186                                    "select fileEntryId, groupId, folderId, extension, title, " +
187                                            "version from DLFileEntry");
188    
189                            rs = ps.executeQuery();
190    
191                            while (rs.next()) {
192                                    long fileEntryId = rs.getLong("fileEntryId");
193                                    long groupId = rs.getLong("groupId");
194                                    long folderId = rs.getLong("folderId");
195                                    String extension = GetterUtil.getString(
196                                            rs.getString("extension"));
197                                    String title = GetterUtil.getString(rs.getString("title"));
198                                    String version = rs.getString("version");
199    
200                                    String uniqueFileName = DLUtil.getSanitizedFileName(
201                                            title, extension);
202    
203                                    String titleExtension = StringPool.BLANK;
204                                    String titleWithoutExtension = title;
205    
206                                    if (title.endsWith(StringPool.PERIOD + extension)) {
207                                            titleExtension = extension;
208                                            titleWithoutExtension = FileUtil.stripExtension(title);
209                                    }
210    
211                                    String uniqueTitle = StringPool.BLANK;
212    
213                                    for (int i = 1;; i++) {
214                                            if (!hasFileEntry(groupId, folderId, uniqueFileName)) {
215                                                    break;
216                                            }
217    
218                                            uniqueTitle =
219                                                    titleWithoutExtension + StringPool.UNDERLINE +
220                                                            String.valueOf(i);
221    
222                                            if (Validator.isNotNull(titleExtension)) {
223                                                    uniqueTitle += StringPool.PERIOD.concat(titleExtension);
224                                            }
225    
226                                            uniqueFileName = DLUtil.getSanitizedFileName(
227                                                    uniqueTitle, extension);
228                                    }
229    
230                                    updateFileEntryFileName(fileEntryId, uniqueFileName);
231    
232                                    if (Validator.isNotNull(uniqueTitle)) {
233                                            updateFileEntryTitle(fileEntryId, uniqueTitle, version);
234                                    }
235                            }
236                    }
237                    finally {
238                            DataAccess.cleanUp(con, ps, rs);
239                    }
240            }
241    
242            protected void updateFileEntryTitle(
243                            long fileEntryId, String title, String version)
244                    throws Exception {
245    
246                    Connection con = null;
247                    PreparedStatement ps = null;
248    
249                    try {
250                            con = DataAccess.getUpgradeOptimizedConnection();
251    
252                            ps = con.prepareStatement(
253                                    "update DLFileEntry set title = ? where fileEntryId = ?");
254    
255                            ps.setString(1, title);
256                            ps.setLong(2, fileEntryId);
257    
258                            ps.executeUpdate();
259    
260                            ps = con.prepareStatement(
261                                    "update DLFileVersion set title = ? where fileEntryId = " +
262                                            "? and version = ?");
263    
264                            ps.setString(1, title);
265                            ps.setLong(2, fileEntryId);
266                            ps.setString(3, version);
267    
268                            ps.executeUpdate();
269                    }
270                    finally {
271                            DataAccess.cleanUp(con, ps);
272                    }
273            }
274    
275            protected void updateFileEntryTypeDDMStructureLinks() throws Exception {
276                    Connection con = null;
277                    PreparedStatement ps = null;
278                    ResultSet rs = null;
279    
280                    try {
281                            con = DataAccess.getUpgradeOptimizedConnection();
282    
283                            ps = con.prepareStatement(
284                                    "select * from DLFileEntryTypes_DDMStructures");
285    
286                            rs = ps.executeQuery();
287    
288                            long classNameId = PortalUtil.getClassNameId(DLFileEntryType.class);
289    
290                            while (rs.next()) {
291                                    long structureId = rs.getLong("structureId");
292                                    long fileEntryTypeId = rs.getLong("fileEntryTypeId");
293    
294                                    addDDMStructureLink(
295                                            increment(), classNameId, fileEntryTypeId, structureId);
296                            }
297                    }
298                    finally {
299                            DataAccess.cleanUp(con, ps, rs);
300                    }
301    
302                    runSQL("drop table DLFileEntryTypes_DDMStructures");
303            }
304    
305            protected void updateFileEntryTypeNamesAndDescriptions() throws Exception {
306                    Connection con = null;
307                    PreparedStatement ps = null;
308                    ResultSet rs = null;
309    
310                    try {
311                            con = DataAccess.getUpgradeOptimizedConnection();
312    
313                            ps = con.prepareStatement(
314                                    "select companyId, groupId from Group_ where classNameId = ?");
315    
316                            long classNameId = PortalUtil.getClassNameId(Company.class);
317    
318                            ps.setLong(1, classNameId);
319    
320                            rs = ps.executeQuery();
321    
322                            while (rs.next()) {
323                                    long companyId = rs.getLong(1);
324                                    long groupId = rs.getLong(2);
325    
326                                    updateFileEntryTypeNamesAndDescriptions(companyId, groupId);
327                            }
328                    }
329                    finally {
330                            DataAccess.cleanUp(con, ps, rs);
331                    }
332            }
333    
334            protected void updateFileEntryTypeNamesAndDescriptions(
335                            long companyId, long groupId)
336                    throws Exception {
337    
338                    Map<String, String> nameLanguageKeys = new HashMap<>();
339    
340                    nameLanguageKeys.put(
341                            DLFileEntryTypeConstants.NAME_CONTRACT,
342                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_KEY_CONTRACT);
343                    nameLanguageKeys.put(
344                            DLFileEntryTypeConstants.NAME_MARKETING_BANNER,
345                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_KEY_MARKETING_BANNER);
346                    nameLanguageKeys.put(
347                            DLFileEntryTypeConstants.NAME_ONLINE_TRAINING,
348                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_KEY_ONLINE_TRAINING);
349                    nameLanguageKeys.put(
350                            DLFileEntryTypeConstants.NAME_SALES_PRESENTATION,
351                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_KEY_SALES_PRESENTATION);
352    
353                    for (Map.Entry<String, String> nameAndKey :
354                                    nameLanguageKeys.entrySet()) {
355    
356                            String dlFileEntryTypeKey = nameAndKey.getValue();
357                            String nameLanguageKey = nameAndKey.getKey();
358    
359                            updateFileEntryTypeNamesAndDescriptions(
360                                    companyId, groupId, dlFileEntryTypeKey, nameLanguageKey);
361                    }
362            }
363    
364            protected void updateFileEntryTypeNamesAndDescriptions(
365                            long companyId, long groupId, String dlFileEntryTypeKey,
366                            String nameLanguageKey)
367                    throws Exception {
368    
369                    Connection con = null;
370                    PreparedStatement ps = null;
371                    ResultSet rs = null;
372    
373                    try {
374                            con = DataAccess.getUpgradeOptimizedConnection();
375    
376                            ps = con.prepareStatement(
377                                    "select fileEntryTypeId, name, description from " +
378                                            "DLFileEntryType where groupId = ? and fileEntryTypeKey " +
379                                                    "= ?");
380    
381                            ps.setLong(1, groupId);
382                            ps.setString(2, dlFileEntryTypeKey);
383    
384                            rs = ps.executeQuery();
385    
386                            if (!rs.next()) {
387                                    return;
388                            }
389    
390                            long fileEntryTypeId = rs.getLong(1);
391                            String name = rs.getString(2);
392                            String description = rs.getString(3);
393    
394                            if (rs.next()) {
395                                    throw new IllegalStateException(
396                                            String.format(
397                                                    "Found more than one row in table DLFileEntryType " +
398                                                            "with groupId %s and fileEntryTypeKey %s",
399                                                    groupId, dlFileEntryTypeKey));
400                            }
401    
402                            updateFileEntryTypeNamesAndDescriptions(
403                                    companyId, fileEntryTypeId, nameLanguageKey, name, description);
404                    }
405                    finally {
406                            DataAccess.cleanUp(con, ps, rs);
407                    }
408            }
409    
410            protected void updateFileEntryTypeNamesAndDescriptions(
411                            long companyId, long dlFileEntryTypeId, String nameLanguageKey,
412                            String nameXML, String descriptionXML)
413                    throws Exception {
414    
415                    boolean update = false;
416    
417                    Locale defaultLocale = LocaleUtil.fromLanguageId(
418                            UpgradeProcessUtil.getDefaultLanguageId(companyId));
419    
420                    String defaultValue = LanguageUtil.get(defaultLocale, nameLanguageKey);
421    
422                    Map<Locale, String> nameMap = LocalizationUtil.getLocalizationMap(
423                            nameXML);
424                    Map<Locale, String> descriptionMap =
425                            LocalizationUtil.getLocalizationMap(descriptionXML);
426    
427                    for (Locale locale : LanguageUtil.getSupportedLocales()) {
428                            String value = LanguageUtil.get(locale, nameLanguageKey);
429    
430                            if (!locale.equals(defaultLocale) && value.equals(defaultValue)) {
431                                    continue;
432                            }
433    
434                            String description = descriptionMap.get(locale);
435    
436                            if (description == null) {
437                                    descriptionMap.put(locale, value);
438    
439                                    update = true;
440                            }
441    
442                            String name = nameMap.get(locale);
443    
444                            if (name == null) {
445                                    nameMap.put(locale, value);
446    
447                                    update = true;
448                            }
449                    }
450    
451                    if (update) {
452                            updateFileEntryTypeNamesAndDescriptions(
453                                    dlFileEntryTypeId, nameXML, descriptionXML, nameMap,
454                                    descriptionMap, defaultLocale);
455                    }
456            }
457    
458            protected void updateFileEntryTypeNamesAndDescriptions(
459                            long fileEntryTypeId, String nameXML, String descriptionXML,
460                            Map<Locale, String> nameMap, Map<Locale, String> descriptionMap,
461                            Locale defaultLocale)
462                    throws Exception {
463    
464                    Connection con = null;
465                    PreparedStatement ps = null;
466    
467                    try {
468                            con = DataAccess.getUpgradeOptimizedConnection();
469    
470                            ps = con.prepareStatement(
471                                    "update DLFileEntryType set name = ?, description = ? where " +
472                                            "fileEntryTypeId = ?");
473    
474                            String languageId = LanguageUtil.getLanguageId(defaultLocale);
475    
476                            nameXML = LocalizationUtil.updateLocalization(
477                                    nameMap, nameXML, "Name", languageId);
478                            descriptionXML = LocalizationUtil.updateLocalization(
479                                    descriptionMap, descriptionXML, "Description", languageId);
480    
481                            ps.setString(1, nameXML);
482                            ps.setString(2, descriptionXML);
483                            ps.setLong(3, fileEntryTypeId);
484    
485                            int rowCount = ps.executeUpdate();
486    
487                            if (rowCount != 1) {
488                                    throw new IllegalStateException(
489                                            String.format(
490                                                    "Updated %s rows in table DLFileEntryType with " +
491                                                            "fileEntryTypeId %s",
492                                                    rowCount, fileEntryTypeId));
493                            }
494                    }
495                    finally {
496                            DataAccess.cleanUp(con, ps);
497                    }
498            }
499    
500            protected void updateFileVersionFileName(
501                            long fileVersionId, String fileName)
502                    throws Exception {
503    
504                    Connection con = null;
505                    PreparedStatement ps = null;
506    
507                    try {
508                            con = DataAccess.getUpgradeOptimizedConnection();
509    
510                            ps = con.prepareStatement(
511                                    "update DLFileVersion set fileName = ? where " +
512                                            "fileVersionId = ?");
513    
514                            ps.setString(1, fileName);
515                            ps.setLong(2, fileVersionId);
516    
517                            ps.executeUpdate();
518                    }
519                    finally {
520                            DataAccess.cleanUp(con, ps);
521                    }
522            }
523    
524            protected void updateFileVersionFileNames() throws Exception {
525                    runSQL("alter table DLFileVersion add fileName VARCHAR(255) null");
526    
527                    Connection con = null;
528                    PreparedStatement ps = null;
529                    ResultSet rs = null;
530    
531                    try {
532                            con = DataAccess.getUpgradeOptimizedConnection();
533    
534                            ps = con.prepareStatement(
535                                    "select fileVersionId, extension, title from DLFileVersion");
536    
537                            rs = ps.executeQuery();
538    
539                            while (rs.next()) {
540                                    long fileVersionId = rs.getLong("fileVersionId");
541                                    String extension = GetterUtil.getString(
542                                            rs.getString("extension"));
543                                    String title = GetterUtil.getString(rs.getString("title"));
544    
545                                    String fileName = DLUtil.getSanitizedFileName(title, extension);
546    
547                                    updateFileVersionFileName(fileVersionId, fileName);
548                            }
549                    }
550                    finally {
551                            DataAccess.cleanUp(con, ps, rs);
552                    }
553            }
554    
555            protected void updateRepositoryClassNameIds() throws Exception {
556                    long liferayRepositoryClassNameId = PortalUtil.getClassNameId(
557                            LiferayRepository.class);
558                    long portletRepositoryClassNameId = PortalUtil.getClassNameId(
559                            PortletRepository.class);
560    
561                    Connection con = null;
562                    PreparedStatement ps = null;
563    
564                    try {
565                            con = DataAccess.getUpgradeOptimizedConnection();
566    
567                            ps = con.prepareStatement(
568                                    "update Repository set classNameId = ? where classNameId = ?");
569    
570                            ps.setLong(1, portletRepositoryClassNameId);
571                            ps.setLong(2, liferayRepositoryClassNameId);
572    
573                            ps.executeUpdate();
574                    }
575                    finally {
576                            DataAccess.cleanUp(con, ps);
577                    }
578            }
579    
580            private static final Log _log = LogFactoryUtil.getLog(
581                    UpgradeDocumentLibrary.class);
582    
583    }