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