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