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