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