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.v6_1_0;
016    
017    import com.liferay.document.library.kernel.model.DLFileEntryTypeConstants;
018    import com.liferay.document.library.kernel.model.DLFolderConstants;
019    import com.liferay.document.library.kernel.store.DLStoreUtil;
020    import com.liferay.document.library.kernel.util.ImageProcessorUtil;
021    import com.liferay.portal.image.DLHook;
022    import com.liferay.portal.image.DatabaseHook;
023    import com.liferay.portal.image.FileSystemHook;
024    import com.liferay.portal.kernel.dao.jdbc.AutoBatchPreparedStatementUtil;
025    import com.liferay.portal.kernel.exception.PortalException;
026    import com.liferay.portal.kernel.image.Hook;
027    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
028    import com.liferay.portal.kernel.log.Log;
029    import com.liferay.portal.kernel.log.LogFactoryUtil;
030    import com.liferay.portal.kernel.model.Image;
031    import com.liferay.portal.kernel.service.ImageLocalServiceUtil;
032    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
033    import com.liferay.portal.kernel.util.Base64;
034    import com.liferay.portal.kernel.util.ClassLoaderUtil;
035    import com.liferay.portal.kernel.util.FileUtil;
036    import com.liferay.portal.kernel.util.LoggingTimer;
037    import com.liferay.portal.kernel.util.MimeTypesUtil;
038    import com.liferay.portal.kernel.util.PortalUtil;
039    import com.liferay.portal.kernel.util.StringBundler;
040    import com.liferay.portal.kernel.util.StringPool;
041    import com.liferay.portal.kernel.util.Validator;
042    import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
043    import com.liferay.portal.upgrade.v6_1_0.util.UpdateSyncUtil;
044    import com.liferay.portal.util.PropsValues;
045    
046    import java.io.IOException;
047    import java.io.InputStream;
048    
049    import java.sql.PreparedStatement;
050    import java.sql.ResultSet;
051    import java.sql.SQLException;
052    import java.sql.Timestamp;
053    
054    import java.util.ArrayList;
055    import java.util.Collections;
056    import java.util.HashMap;
057    import java.util.List;
058    import java.util.Map;
059    
060    /**
061     * @author Sergio Gonz??lez
062     * @author Miguel Pastor
063     * @author Vilmos Papp
064     */
065    public class UpgradeImageGallery extends UpgradeProcess {
066    
067            public UpgradeImageGallery() throws Exception {
068                    ClassLoader classLoader = ClassLoaderUtil.getPortalClassLoader();
069    
070                    if (Validator.isNotNull(PropsValues.IMAGE_HOOK_IMPL)) {
071                            _sourceHookClassName = PropsValues.IMAGE_HOOK_IMPL;
072                    }
073                    else {
074                            _sourceHookClassName = FileSystemHook.class.getName();
075                    }
076    
077                    Class<?> clazz = classLoader.loadClass(_sourceHookClassName);
078    
079                    _sourceHook = (Hook)clazz.newInstance();
080            }
081    
082            protected void addDLFileEntry(
083                            String uuid, long fileEntryId, long groupId, long companyId,
084                            long userId, String userName, long versionUserId,
085                            String versionUserName, Timestamp createDate,
086                            Timestamp modifiedDate, long repositoryId, long folderId,
087                            String name, String extension, String mimeType, String title,
088                            String description, String extraSettings, long fileEntryTypeId,
089                            String version, long size, int readCount, long smallImageId,
090                            long largeImageId, long custom1ImageId, long custom2ImageId)
091                    throws Exception {
092    
093                    StringBundler sb = new StringBundler(8);
094    
095                    sb.append("insert into DLFileEntry (uuid_, fileEntryId, groupId, ");
096                    sb.append("companyId, userId, userName, versionUserId, ");
097                    sb.append("versionUserName, createDate, modifiedDate, repositoryId, ");
098                    sb.append("folderId, name, extension, mimeType, title, description, ");
099                    sb.append("extraSettings, fileEntryTypeId, version, size_, ");
100                    sb.append("readCount, smallImageId, largeImageId, custom1ImageId, ");
101                    sb.append("custom2ImageId) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ");
102                    sb.append("?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
103    
104                    try (PreparedStatement ps = connection.prepareStatement(
105                                    sb.toString())) {
106    
107                            ps.setString(1, uuid);
108                            ps.setLong(2, fileEntryId);
109                            ps.setLong(3, groupId);
110                            ps.setLong(4, companyId);
111                            ps.setLong(5, userId);
112                            ps.setString(6, userName);
113                            ps.setLong(7, versionUserId);
114                            ps.setString(8, versionUserName);
115                            ps.setTimestamp(9, createDate);
116                            ps.setTimestamp(10, modifiedDate);
117                            ps.setLong(11, repositoryId);
118                            ps.setLong(12, folderId);
119                            ps.setString(13, name);
120                            ps.setString(14, extension);
121                            ps.setString(15, mimeType);
122                            ps.setString(16, title);
123                            ps.setString(17, description);
124                            ps.setString(18, extraSettings);
125                            ps.setLong(19, fileEntryTypeId);
126                            ps.setString(20, version);
127                            ps.setLong(21, size);
128                            ps.setInt(22, readCount);
129                            ps.setLong(23, smallImageId);
130                            ps.setLong(24, largeImageId);
131                            ps.setLong(25, custom1ImageId);
132                            ps.setLong(26, custom2ImageId);
133    
134                            ps.executeUpdate();
135                    }
136            }
137    
138            protected void addDLFileVersion(
139                            long fileVersionId, long groupId, long companyId, long userId,
140                            String userName, Timestamp createDate, long repositoryId,
141                            long folderId, long fileEntryId, String extension, String mimeType,
142                            String title, String description, String changeLog,
143                            String extraSettings, long fileEntryTypeId, String version,
144                            long size, int status, long statusByUserId, String statusByUserName,
145                            Timestamp statusDate)
146                    throws Exception {
147    
148                    StringBundler sb = new StringBundler(7);
149    
150                    sb.append("insert into DLFileVersion (fileVersionId, groupId, ");
151                    sb.append("companyId, userId, userName, createDate, modifiedDate, ");
152                    sb.append("repositoryId, folderId, fileEntryId, extension, ");
153                    sb.append("mimeType, title, description, changeLog, extraSettings, ");
154                    sb.append("fileEntryTypeId, version, size_, status, statusByUserId, ");
155                    sb.append("statusByUserName, statusDate) values (?, ?, ?, ?, ?, ?, ");
156                    sb.append("?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
157    
158                    try (PreparedStatement ps = connection.prepareStatement(
159                                    sb.toString())) {
160    
161                            ps.setLong(1, fileVersionId);
162                            ps.setLong(2, groupId);
163                            ps.setLong(3, companyId);
164                            ps.setLong(4, userId);
165                            ps.setString(5, userName);
166                            ps.setTimestamp(6, createDate);
167                            ps.setTimestamp(7, statusDate);
168                            ps.setLong(8, repositoryId);
169                            ps.setLong(9, folderId);
170                            ps.setLong(10, fileEntryId);
171                            ps.setString(11, extension);
172                            ps.setString(12, mimeType);
173                            ps.setString(13, title);
174                            ps.setString(14, description);
175                            ps.setString(15, changeLog);
176                            ps.setString(16, extraSettings);
177                            ps.setLong(17, fileEntryTypeId);
178                            ps.setString(18, version);
179                            ps.setLong(19, size);
180                            ps.setInt(20, status);
181                            ps.setLong(21, statusByUserId);
182                            ps.setString(22, statusByUserName);
183                            ps.setTimestamp(23, statusDate);
184    
185                            ps.executeUpdate();
186                    }
187            }
188    
189            protected void addDLFolderEntry(
190                            String uuid, long folderId, long groupId, long companyId,
191                            long userId, String userName, Timestamp createDate,
192                            Timestamp modifiedDate, long repositoryId, long parentFolderId,
193                            String name, String description, Timestamp lastPostDate)
194                    throws Exception {
195    
196                    StringBundler sb = new StringBundler(5);
197    
198                    sb.append("insert into DLFolder (uuid_, folderId, groupId, ");
199                    sb.append("companyId, userId, userName, createDate, modifiedDate, ");
200                    sb.append("repositoryId, mountPoint, parentFolderId, name, ");
201                    sb.append("description, lastPostDate) values (?, ?, ?, ?, ?, ?, ?, ");
202                    sb.append("?, ?, ?, ?, ?, ?, ?)");
203    
204                    try (PreparedStatement ps = connection.prepareStatement(
205                                    sb.toString())) {
206    
207                            ps.setString(1, uuid);
208                            ps.setLong(2, folderId);
209                            ps.setLong(3, groupId);
210                            ps.setLong(4, companyId);
211                            ps.setLong(5, userId);
212                            ps.setString(6, userName);
213                            ps.setTimestamp(7, createDate);
214                            ps.setTimestamp(8, modifiedDate);
215                            ps.setLong(9, repositoryId);
216                            ps.setBoolean(10, false);
217                            ps.setLong(11, parentFolderId);
218                            ps.setString(12, name);
219                            ps.setString(13, description);
220                            ps.setTimestamp(14, lastPostDate);
221    
222                            ps.executeUpdate();
223                    }
224            }
225    
226            protected void addIGImageDLFileEntryType() throws Exception {
227                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
228                            if (!PropsValues.
229                                            DL_FILE_ENTRY_TYPE_IG_IMAGE_AUTO_CREATE_ON_UPGRADE) {
230    
231                                    return;
232                            }
233    
234                            try (PreparedStatement ps = connection.prepareStatement(
235                                            "select distinct companyId from IGImage");
236                                    ResultSet rs = ps.executeQuery()) {
237    
238                                    while (rs.next()) {
239                                            long companyId = rs.getLong("companyId");
240    
241                                            long groupId = getCompanyGroupId(companyId);
242                                            long userId = getDefaultUserId(companyId);
243                                            Timestamp now = new Timestamp(System.currentTimeMillis());
244    
245                                            addIGImageDLFileEntryType(
246                                                    groupId, companyId, userId, StringPool.BLANK, now, now);
247                                    }
248                            }
249                    }
250            }
251    
252            protected void addIGImageDLFileEntryType(
253                            long groupId, long companyId, long userId, String userName,
254                            Timestamp createDate, Timestamp modifiedDate)
255                    throws Exception {
256    
257                    StringBundler sb = new StringBundler(4);
258    
259                    sb.append("insert into DLFileEntryType (uuid_, groupId, companyId, ");
260                    sb.append("userId, userName, createDate, modifiedDate, name, ");
261                    sb.append("description, fileEntryTypeId) values (?, ?, ?, ?, ?, ?, ");
262                    sb.append("?, ?, ?, ?)");
263    
264                    try (PreparedStatement ps = connection.prepareStatement(
265                                    sb.toString())) {
266    
267                            ps.setString(1, PortalUUIDUtil.generate());
268                            ps.setLong(2, groupId);
269                            ps.setLong(3, companyId);
270                            ps.setLong(4, userId);
271                            ps.setString(5, userName);
272                            ps.setTimestamp(6, createDate);
273                            ps.setTimestamp(7, modifiedDate);
274                            ps.setString(8, DLFileEntryTypeConstants.NAME_IG_IMAGE);
275                            ps.setString(9, DLFileEntryTypeConstants.NAME_IG_IMAGE);
276                            ps.setLong(10, increment());
277    
278                            ps.executeUpdate();
279                    }
280            }
281    
282            protected void deleteConflictingIGPermissions(
283                            String igResourceName, String dlResourceName)
284                    throws Exception {
285    
286                    String selectSQL =
287                            "select companyId, scope, primKey, roleId from " +
288                                    "ResourcePermission where name = ?";
289                    String deleteSQL =
290                            "delete from ResourcePermission where name = ? and companyId = ? " +
291                                    "and scope = ? and primKey = ? and roleId = ?";
292    
293                    try (PreparedStatement ps1 = connection.prepareStatement(selectSQL);) {
294                            ps1.setString(1, igResourceName);
295    
296                            try (ResultSet rs = ps1.executeQuery();
297                                    PreparedStatement ps2 =
298                                            AutoBatchPreparedStatementUtil.autoBatch(
299                                                    connection.prepareStatement(deleteSQL))) {
300    
301                                    while (rs.next()) {
302                                            ps2.setString(1, dlResourceName);
303                                            ps2.setLong(2, rs.getLong("companyId"));
304                                            ps2.setInt(3, rs.getInt("scope"));
305                                            ps2.setString(4, rs.getString("primKey"));
306                                            ps2.setLong(5, rs.getLong("roleId"));
307    
308                                            ps2.addBatch();
309                                    }
310    
311                                    ps2.executeBatch();
312                            }
313                    }
314            }
315    
316            @Override
317            protected void doUpgrade() throws Exception {
318                    addIGImageDLFileEntryType();
319                    updateIGFolderEntries();
320                    updateIGImageEntries();
321                    updateIGFolderPermissions();
322                    updateIGImagePermissions();
323    
324                    migrateImageFiles();
325    
326                    UpdateSyncUtil.updateSyncs(connection);
327            }
328    
329            protected long getBitwiseValue(
330                    Map<String, Long> bitwiseValues, List<String> actionIds) {
331    
332                    long bitwiseValue = 0;
333    
334                    for (String actionId : actionIds) {
335                            Long actionIdBitwiseValue = bitwiseValues.get(actionId);
336    
337                            if (actionIdBitwiseValue == null) {
338                                    continue;
339                            }
340    
341                            bitwiseValue |= actionIdBitwiseValue;
342                    }
343    
344                    return bitwiseValue;
345            }
346    
347            protected Map<String, Long> getBitwiseValues(String name) throws Exception {
348                    try (PreparedStatement ps = connection.prepareStatement(
349                                    "select actionId, bitwiseValue from ResourceAction " +
350                                            "where name = ?")) {
351    
352                            ps.setString(1, name);
353    
354                            try (ResultSet rs = ps.executeQuery()) {
355                                    Map<String, Long> bitwiseValues = new HashMap<>();
356    
357                                    while (rs.next()) {
358                                            String actionId = rs.getString("actionId");
359                                            long bitwiseValue = rs.getLong("bitwiseValue");
360    
361                                            bitwiseValues.put(actionId, bitwiseValue);
362                                    }
363    
364                                    return bitwiseValues;
365                            }
366                    }
367            }
368    
369            protected long getCompanyGroupId(long companyId) throws Exception {
370                    try (PreparedStatement ps = connection.prepareStatement(
371                                    "select groupId from Group_ where classNameId = ? and " +
372                                            "classPK = ?")) {
373    
374                            ps.setLong(
375                                    1,
376                                    PortalUtil.getClassNameId("com.liferay.portal.model.Company"));
377                            ps.setLong(2, companyId);
378    
379                            try (ResultSet rs = ps.executeQuery()) {
380                                    if (rs.next()) {
381                                            return rs.getLong("groupId");
382                                    }
383    
384                                    return 0;
385                            }
386                    }
387            }
388    
389            protected byte[] getDatabaseImageAsBytes(Image image) throws SQLException {
390                    try (PreparedStatement ps = connection.prepareStatement(
391                                    "select text_ from Image where imageId = ?")) {
392    
393                            ps.setLong(1, image.getImageId());
394    
395                            try (ResultSet rs = ps.executeQuery()) {
396                                    if (rs.next()) {
397                                            String getTextObj = rs.getString("text_");
398    
399                                            return (byte[])Base64.stringToObject(getTextObj);
400                                    }
401    
402                                    if (_log.isWarnEnabled()) {
403                                            _log.warn(
404                                                    "Image " + image.getImageId() +
405                                                            " is not in the database");
406                                    }
407                            }
408                    }
409    
410                    return new byte[0];
411            }
412    
413            protected long getDefaultUserId(long companyId) throws Exception {
414                    try (PreparedStatement ps = connection.prepareStatement(
415                                    "select userId from User_ where companyId = ? and " +
416                                            "defaultUser = ?")) {
417    
418                            ps.setLong(1, companyId);
419                            ps.setBoolean(2, true);
420    
421                            try (ResultSet rs = ps.executeQuery()) {
422                                    if (rs.next()) {
423                                            return rs.getLong("userId");
424                                    }
425    
426                                    return 0;
427                            }
428                    }
429            }
430    
431            protected byte[] getHookImageAsBytes(Image image)
432                    throws IOException, PortalException, SQLException {
433    
434                    InputStream is = getHookImageAsStream(image);
435    
436                    return FileUtil.getBytes(is);
437            }
438    
439            protected InputStream getHookImageAsStream(Image image)
440                    throws PortalException, SQLException {
441    
442                    InputStream is = null;
443    
444                    if (_sourceHook instanceof DatabaseHook) {
445                            byte[] bytes = getDatabaseImageAsBytes(image);
446    
447                            is = new UnsyncByteArrayInputStream(bytes);
448                    }
449                    else {
450                            is = _sourceHook.getImageAsStream(image);
451                    }
452    
453                    return is;
454            }
455    
456            protected Image getImage(long imageId) throws Exception {
457                    try (PreparedStatement ps = connection.prepareStatement(
458                                    "select imageId, modifiedDate, type_, height, width, size_ " +
459                                            "from Image where imageId = " + imageId);
460                            ResultSet rs = ps.executeQuery()) {
461    
462                            if (rs.next()) {
463                                    Image image = ImageLocalServiceUtil.createImage(
464                                            rs.getLong("imageId"));
465    
466                                    image.setModifiedDate(rs.getTimestamp("modifiedDate"));
467                                    image.setType(rs.getString("type_"));
468                                    image.setHeight(rs.getInt("height"));
469                                    image.setWidth(rs.getInt("width"));
470                                    image.setSize(rs.getInt("size_"));
471    
472                                    return image;
473                            }
474    
475                            return null;
476                    }
477            }
478    
479            protected long getMaxFileVersionId(long fileEntryId) {
480                    try (PreparedStatement ps = connection.prepareStatement(
481                                    "select max(fileVersionId) from DLFileVersion where " +
482                                            "fileEntryId = " + fileEntryId);
483                            ResultSet rs = ps.executeQuery()) {
484    
485                            rs.next();
486    
487                            return rs.getLong(1);
488                    }
489                    catch (SQLException sqle) {
490                            if (_log.isWarnEnabled()) {
491                                    _log.warn(
492                                            "Unable to get file version for file entry " + fileEntryId,
493                                            sqle);
494                            }
495                    }
496    
497                    return 0;
498            }
499    
500            protected List<String> getResourceActionIds(
501                    Map<String, Long> bitwiseValues, long actionIdsLong) {
502    
503                    List<String> actionIds = new ArrayList<>();
504    
505                    for (Map.Entry<String, Long> entry : bitwiseValues.entrySet()) {
506                            long bitwiseValue = entry.getValue();
507    
508                            if ((actionIdsLong & bitwiseValue) == bitwiseValue) {
509                                    actionIds.add(entry.getKey());
510                            }
511                    }
512    
513                    return actionIds;
514            }
515    
516            protected void migrateFile(
517                            long repositoryId, long companyId, String name, Image image)
518                    throws Exception {
519    
520                    byte[] bytes = getHookImageAsBytes(image);
521    
522                    if (name == null) {
523                            name = image.getImageId() + StringPool.PERIOD + image.getType();
524                    }
525    
526                    if (DLStoreUtil.hasFile(companyId, repositoryId, name)) {
527                            DLStoreUtil.deleteFile(companyId, repositoryId, name);
528                    }
529    
530                    DLStoreUtil.addFile(companyId, repositoryId, name, false, bytes);
531            }
532    
533            protected void migrateImage(long imageId) throws Exception {
534                    Image image = getImage(imageId);
535    
536                    try {
537                            migrateFile(0, 0, null, image);
538                    }
539                    catch (Exception e) {
540                            if (_log.isWarnEnabled()) {
541                                    _log.warn("Ignoring exception for image " + imageId, e);
542                            }
543    
544                            return;
545                    }
546    
547                    _sourceHook.deleteImage(image);
548            }
549    
550            protected void migrateImage(
551                            long fileEntryId, long companyId, long groupId, long folderId,
552                            String name, long smallImageId, long largeImageId,
553                            long custom1ImageId, long custom2ImageId)
554                    throws Exception {
555    
556                    Image largeImage = null;
557    
558                    if (largeImageId != 0) {
559                            largeImage = getImage(largeImageId);
560    
561                            long repositoryId = DLFolderConstants.getDataRepositoryId(
562                                    groupId, folderId);
563    
564                            try {
565                                    migrateFile(repositoryId, companyId, name, largeImage);
566                            }
567                            catch (Exception e) {
568                                    if (_log.isWarnEnabled()) {
569                                            _log.warn(
570                                                    "Ignoring exception for migrating image " +
571                                                            largeImageId,
572                                                    e);
573                                    }
574                            }
575                    }
576    
577                    if ((smallImageId != 0) || (custom1ImageId != 0) ||
578                            (custom2ImageId != 0)) {
579    
580                            long fileVersionId = getMaxFileVersionId(fileEntryId);
581    
582                            if (fileVersionId != 0) {
583                                    if (smallImageId != 0) {
584                                            migrateThumbnail(
585                                                    companyId, groupId, fileEntryId, fileVersionId,
586                                                    largeImageId, smallImageId, 0, 0);
587                                    }
588    
589                                    if (custom1ImageId != 0) {
590                                            migrateThumbnail(
591                                                    companyId, groupId, fileEntryId, fileVersionId,
592                                                    largeImageId, custom1ImageId, custom1ImageId, 0);
593                                    }
594    
595                                    if (custom2ImageId != 0) {
596                                            migrateThumbnail(
597                                                    companyId, groupId, fileEntryId, fileVersionId,
598                                                    largeImageId, custom2ImageId, 0, custom2ImageId);
599                                    }
600                            }
601                    }
602    
603                    if (largeImageId != 0) {
604                            _sourceHook.deleteImage(largeImage);
605    
606                            runSQL("delete from Image where imageId = " + largeImageId);
607                    }
608            }
609    
610            protected void migrateImageFiles() throws Exception {
611                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
612                            StringBundler sb = new StringBundler(8);
613    
614                            sb.append("select fileEntryId, companyId, groupId, folderId, ");
615                            sb.append("name, smallImageId, largeImageId, custom1ImageId, ");
616                            sb.append("custom2ImageId from DLFileEntry where ((smallImageId ");
617                            sb.append("is not null) and (smallImageId != 0)) or ");
618                            sb.append("((largeImageId is not null) and (largeImageId != 0)) ");
619                            sb.append("or ((custom1ImageId is not null) and (custom1ImageId ");
620                            sb.append("!= 0)) or ((custom2ImageId is not null) and ");
621                            sb.append("(custom2ImageId != 0))");
622    
623                            try (PreparedStatement ps = connection.prepareStatement(
624                                            sb.toString());
625                                    ResultSet rs = ps.executeQuery()) {
626    
627                                    while (rs.next()) {
628                                            long fileEntryId = rs.getLong("fileEntryId");
629                                            long companyId = rs.getLong("companyId");
630                                            long groupId = rs.getLong("groupId");
631                                            long folderId = rs.getLong("folderId");
632                                            String name = rs.getString("name");
633                                            long smallImageId = rs.getLong("smallImageId");
634                                            long largeImageId = rs.getLong("largeImageId");
635                                            long custom1ImageId = rs.getLong("custom1ImageId");
636                                            long custom2ImageId = rs.getLong("custom2ImageId");
637    
638                                            migrateImage(
639                                                    fileEntryId, companyId, groupId, folderId, name,
640                                                    smallImageId, largeImageId, custom1ImageId,
641                                                    custom2ImageId);
642                                    }
643                            }
644    
645                            if (_sourceHookClassName.equals(DLHook.class.getName())) {
646                                    return;
647                            }
648    
649                            try (PreparedStatement ps = connection.prepareStatement(
650                                            "select imageId from Image");
651                                    ResultSet rs = ps.executeQuery()) {
652    
653                                    while (rs.next()) {
654                                            long imageId = rs.getLong("imageId");
655    
656                                            migrateImage(imageId);
657                                    }
658                            }
659    
660                            if (_sourceHookClassName.equals(DatabaseHook.class.getName())) {
661                                    runSQL("update Image set text_ = ''");
662                            }
663                    }
664            }
665    
666            protected void migrateThumbnail(
667                            long companyId, long groupId, long fileEntryId, long fileVersionId,
668                            long largeImageId, long thumbnailImageId, long custom1ImageId,
669                            long custom2ImageId)
670                    throws Exception {
671    
672                    Image thumbnailImage = null;
673    
674                    try {
675                            thumbnailImage = getImage(thumbnailImageId);
676    
677                            InputStream is = getHookImageAsStream(thumbnailImage);
678    
679                            ImageProcessorUtil.storeThumbnail(
680                                    companyId, groupId, fileEntryId, fileVersionId, custom1ImageId,
681                                    custom2ImageId, is, thumbnailImage.getType());
682    
683                            if (largeImageId != thumbnailImageId) {
684                                    _sourceHook.deleteImage(thumbnailImage);
685    
686                                    runSQL("delete from Image where imageId = " + thumbnailImageId);
687                            }
688                    }
689                    catch (Exception e) {
690                            if (_log.isWarnEnabled()) {
691                                    _log.warn(
692                                            "Ignoring exception for image " + thumbnailImageId, e);
693                            }
694                    }
695            }
696    
697            protected void updateIGFolderEntries() throws Exception {
698                    try (LoggingTimer loggingTimer = new LoggingTimer();
699                            PreparedStatement ps = connection.prepareStatement(
700                                    "select * from IGFolder order by folderId asc");
701                            ResultSet rs = ps.executeQuery()) {
702    
703                            Map<Long, Long> folderIds = new HashMap<>();
704    
705                            while (rs.next()) {
706                                    String uuid = rs.getString("uuid_");
707                                    long folderId = rs.getLong("folderId");
708                                    long groupId = rs.getLong("groupId");
709                                    long companyId = rs.getLong("companyId");
710                                    long userId = rs.getLong("userId");
711                                    String userName = rs.getString("userName");
712                                    Timestamp createDate = rs.getTimestamp("createDate");
713                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
714                                    long parentFolderId = rs.getLong("parentFolderId");
715                                    String name = rs.getString("name");
716                                    String description = rs.getString("description");
717    
718                                    if (folderIds.containsKey(parentFolderId)) {
719                                            parentFolderId = folderIds.get(parentFolderId);
720                                    }
721    
722                                    boolean update = updateIGImageFolderId(
723                                            groupId, name, parentFolderId, folderId, folderIds);
724    
725                                    if (!update) {
726                                            addDLFolderEntry(
727                                                    uuid, folderId, groupId, companyId, userId, userName,
728                                                    createDate, modifiedDate, groupId, parentFolderId, name,
729                                                    description, modifiedDate);
730                                    }
731                            }
732    
733                            runSQL("drop table IGFolder");
734                    }
735            }
736    
737            protected void updateIGFolderPermissions() throws Exception {
738                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
739                            deleteConflictingIGPermissions(
740                                    _IG_FOLDER_CLASS_NAME,
741                                    "com.liferay.portlet.documentlibrary.model.DLFolder");
742    
743                            updateIGtoDLPermissions(
744                                    _IG_FOLDER_CLASS_NAME,
745                                    "com.liferay.portlet.documentlibrary.model.DLFolder");
746                    }
747            }
748    
749            protected void updateIGImageEntries() throws Exception {
750                    try (LoggingTimer loggingTimer = new LoggingTimer();
751                            PreparedStatement ps = connection.prepareStatement(
752                                    "select fileEntryTypeId, companyId from DLFileEntryType " +
753                                            "where name = ?")) {
754    
755                            ps.setString(1, DLFileEntryTypeConstants.NAME_IG_IMAGE);
756    
757                            try (ResultSet rs = ps.executeQuery()) {
758                                    boolean hasIGImageFileEntryType = false;
759    
760                                    while (rs.next()) {
761                                            long fileEntryTypeId = rs.getLong("fileEntryTypeId");
762                                            long companyId = rs.getLong("companyId");
763    
764                                            updateIGImageEntries(companyId, fileEntryTypeId);
765    
766                                            hasIGImageFileEntryType = true;
767                                    }
768    
769                                    if (!hasIGImageFileEntryType) {
770                                            updateIGImageEntries(0, 0);
771                                    }
772    
773                                    runSQL("drop table IGImage");
774                            }
775                    }
776            }
777    
778            protected void updateIGImageEntries(long companyId, long fileEntryTypeId)
779                    throws Exception {
780    
781                    String sql = "select * from IGImage";
782    
783                    if (companyId != 0) {
784                            sql = "select * from IGImage where companyId = ?";
785                    }
786    
787                    try (PreparedStatement ps = connection.prepareStatement(sql)) {
788                            if (companyId != 0) {
789                                    ps.setLong(1, companyId);
790                            }
791    
792                            try (ResultSet rs = ps.executeQuery()) {
793                                    while (rs.next()) {
794                                            String uuid = rs.getString("uuid_");
795                                            long imageId = rs.getLong("imageId");
796                                            long groupId = rs.getLong("groupId");
797                                            companyId = rs.getLong("companyId");
798                                            long userId = rs.getLong("userId");
799                                            String userName = rs.getString("userName");
800                                            Timestamp createDate = rs.getTimestamp("createDate");
801                                            Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
802                                            long folderId = rs.getLong("folderId");
803                                            String title = rs.getString("name");
804                                            String description = rs.getString("description");
805                                            long smallImageId = rs.getLong("smallImageId");
806                                            long largeImageId = rs.getLong("largeImageId");
807                                            long custom1ImageId = rs.getLong("custom1ImageId");
808                                            long custom2ImageId = rs.getLong("custom2ImageId");
809    
810                                            Image image = getImage(largeImageId);
811    
812                                            if (image == null) {
813                                                    continue;
814                                            }
815    
816                                            String extension = image.getType();
817    
818                                            String mimeType = MimeTypesUtil.getExtensionContentType(
819                                                    extension);
820    
821                                            String name = String.valueOf(
822                                                    increment(
823                                                            "com.liferay.portlet.documentlibrary.model." +
824                                                                    "DLFileEntry"));
825    
826                                            long size = image.getSize();
827    
828                                            try {
829                                                    addDLFileEntry(
830                                                            uuid, imageId, groupId, companyId, userId, userName,
831                                                            userId, userName, createDate, modifiedDate, groupId,
832                                                            folderId, name, extension, mimeType, title,
833                                                            description, StringPool.BLANK, fileEntryTypeId,
834                                                            "1.0", size, 0, smallImageId, largeImageId,
835                                                            custom1ImageId, custom2ImageId);
836                                            }
837                                            catch (Exception e) {
838                                                    title = title.concat(StringPool.SPACE).concat(
839                                                            String.valueOf(imageId));
840    
841                                                    addDLFileEntry(
842                                                            uuid, imageId, groupId, companyId, userId, userName,
843                                                            userId, userName, createDate, modifiedDate, groupId,
844                                                            folderId, name, extension, mimeType, title,
845                                                            description, StringPool.BLANK, fileEntryTypeId,
846                                                            "1.0", size, 0, smallImageId, largeImageId,
847                                                            custom1ImageId, custom2ImageId);
848                                            }
849    
850                                            addDLFileVersion(
851                                                    increment(), groupId, companyId, userId, userName,
852                                                    createDate, groupId, folderId, imageId, extension,
853                                                    mimeType, title, description, StringPool.BLANK,
854                                                    StringPool.BLANK, fileEntryTypeId, "1.0", size, 0,
855                                                    userId, userName, modifiedDate);
856                                    }
857                            }
858                    }
859            }
860    
861            protected boolean updateIGImageFolderId(
862                            long groupId, String name, long parentFolderId, long folderId,
863                            Map<Long, Long> folderIds)
864                    throws Exception {
865    
866                    try (PreparedStatement ps = connection.prepareStatement(
867                                    "select folderId from DLFolder where groupId = " + groupId +
868                                            " and parentFolderId = " + parentFolderId +
869                                                    " and name = ?")) {
870    
871                            ps.setString(1, name);
872    
873                            try (ResultSet rs = ps.executeQuery()) {
874                                    if (rs.next()) {
875                                            long newFolderId = rs.getLong("folderId");
876    
877                                            runSQL(
878                                                    "update IGImage set folderId = " + newFolderId +
879                                                            " where folderId = " + folderId);
880    
881                                            folderIds.put(folderId, newFolderId);
882    
883                                            return true;
884                                    }
885                            }
886                    }
887    
888                    return false;
889            }
890    
891            protected void updateIGImagePermissions() throws Exception {
892                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
893                            deleteConflictingIGPermissions(
894                                    _IG_IMAGE_CLASS_NAME,
895                                    "com.liferay.portlet.documentlibrary.model.DLFileEntry");
896    
897                            updateIGtoDLPermissions(
898                                    _IG_IMAGE_CLASS_NAME,
899                                    "com.liferay.portlet.documentlibrary.model.DLFileEntry");
900                    }
901            }
902    
903            protected void updateIGtoDLPermissions(
904                            String igResourceName, String dlResourceName)
905                    throws Exception {
906    
907                    Map<String, Long> igBitwiseValues = getBitwiseValues(igResourceName);
908    
909                    if (igBitwiseValues.isEmpty()) {
910                            if (_log.isWarnEnabled()) {
911                                    _log.warn(
912                                            "Resource actions do not exist for " + igResourceName);
913                            }
914    
915                            return;
916                    }
917    
918                    Map<String, Long> dlBitwiseValues = getBitwiseValues(dlResourceName);
919    
920                    if (dlBitwiseValues.isEmpty()) {
921                            if (_log.isWarnEnabled()) {
922                                    _log.warn(
923                                            "Resource actions do not exist for " + dlResourceName);
924                            }
925    
926                            return;
927                    }
928    
929                    // The size of igBitwiseValues is based on the number of actions defined
930                    // in resource actions which was 7 and 4 for IGFolder and IGImage
931                    // respectively. This means the loop will execute at most 2^7 (128)
932                    // times. If we were to check before update, we would still have to
933                    // perform 128 queries, so we may as well just update 128 times even if
934                    // no candidates exist for a given value.
935    
936                    for (int i = 0; i < Math.pow(2, igBitwiseValues.size()); i++) {
937                            List<String> igActionIds = getResourceActionIds(igBitwiseValues, i);
938    
939                            if (igResourceName.equals(_IG_FOLDER_CLASS_NAME)) {
940                                    Collections.replaceAll(
941                                            igActionIds, "ADD_IMAGE", "ADD_DOCUMENT");
942                            }
943    
944                            long dlActionIdsLong = getBitwiseValue(
945                                    dlBitwiseValues, igActionIds);
946    
947                            runSQL(
948                                    "update ResourcePermission set name = '" + dlResourceName +
949                                            "', actionIds = " + dlActionIdsLong + " where name = '" +
950                                                    igResourceName + "'" + " and actionIds = " + i);
951                    }
952            }
953    
954            private static final String _IG_FOLDER_CLASS_NAME =
955                    "com.liferay.portlet.imagegallery.model.IGFolder";
956    
957            private static final String _IG_IMAGE_CLASS_NAME =
958                    "com.liferay.portlet.imagegallery.model.IGImage";
959    
960            private static final Log _log = LogFactoryUtil.getLog(
961                    UpgradeImageGallery.class);
962    
963            private final Hook _sourceHook;
964            private final String _sourceHookClassName;
965    
966    }