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(9);
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 List<String> getResourceActionIds(
583                    Map<String, Long> bitwiseValues, long actionIdsLong) {
584    
585                    List<String> actionIds = new ArrayList<>();
586    
587                    for (String actionId : bitwiseValues.keySet()) {
588                            long bitwiseValue = bitwiseValues.get(actionId);
589    
590                            if ((actionIdsLong & bitwiseValue) == bitwiseValue) {
591                                    actionIds.add(actionId);
592                            }
593                    }
594    
595                    return actionIds;
596            }
597    
598            protected void migrateFile(
599                            long repositoryId, long companyId, String name, Image image)
600                    throws Exception {
601    
602                    byte[] bytes = getHookImageAsBytes(image);
603    
604                    if (name == null) {
605                            name = image.getImageId() + StringPool.PERIOD + image.getType();
606                    }
607    
608                    if (DLStoreUtil.hasFile(companyId, repositoryId, name)) {
609                            DLStoreUtil.deleteFile(companyId, repositoryId, name);
610                    }
611    
612                    DLStoreUtil.addFile(companyId, repositoryId, name, false, bytes);
613            }
614    
615            protected void migrateImage(long imageId) throws Exception {
616                    Image image = getImage(imageId);
617    
618                    try {
619                            migrateFile(0, 0, null, image);
620                    }
621                    catch (Exception e) {
622                            if (_log.isWarnEnabled()) {
623                                    _log.warn("Ignoring exception for image " + imageId, e);
624                            }
625    
626                            return;
627                    }
628    
629                    _sourceHook.deleteImage(image);
630            }
631    
632            protected void migrateImage(
633                            long fileEntryId, long companyId, long groupId, long folderId,
634                            String name, long smallImageId, long largeImageId,
635                            long custom1ImageId, long custom2ImageId)
636                    throws Exception {
637    
638                    Image largeImage = null;
639    
640                    if (largeImageId != 0) {
641                            largeImage = getImage(largeImageId);
642    
643                            long repositoryId = DLFolderConstants.getDataRepositoryId(
644                                    groupId, folderId);
645    
646                            try {
647                                    migrateFile(repositoryId, companyId, name, largeImage);
648                            }
649                            catch (Exception e) {
650                                    if (_log.isWarnEnabled()) {
651                                            _log.warn(
652                                                    "Ignoring exception for image " + largeImageId, e);
653                                    }
654                            }
655                    }
656    
657                    long thumbnailImageId = 0;
658    
659                    if (smallImageId != 0) {
660                            thumbnailImageId = smallImageId;
661                    }
662                    else if (custom1ImageId != 0) {
663                            thumbnailImageId = custom1ImageId;
664                    }
665                    else if (custom2ImageId != 0) {
666                            thumbnailImageId = custom2ImageId;
667                    }
668    
669                    Image thumbnailImage = null;
670    
671                    if (thumbnailImageId != 0) {
672                            thumbnailImage = getImage(thumbnailImageId);
673    
674                            Connection con = null;
675                            PreparedStatement ps = null;
676                            ResultSet rs = null;
677    
678                            try {
679                                    con = DataAccess.getUpgradeOptimizedConnection();
680    
681                                    ps = con.prepareStatement(
682                                            "select max(fileVersionId) from DLFileVersion where " +
683                                                    "fileEntryId = " + fileEntryId);
684    
685                                    rs = ps.executeQuery();
686    
687                                    if (rs.next()) {
688                                            long fileVersionId = rs.getLong(1);
689    
690                                            InputStream is = getHookImageAsStream(thumbnailImage);
691    
692                                            ImageProcessorUtil.storeThumbnail(
693                                                    companyId, groupId, fileEntryId, fileVersionId,
694                                                    custom1ImageId, custom2ImageId, is,
695                                                    thumbnailImage.getType());
696                                    }
697                            }
698                            catch (Exception e) {
699                                    if (_log.isWarnEnabled()) {
700                                            _log.warn(
701                                                    "Ignoring exception for image " + thumbnailImageId, e);
702                                    }
703                            }
704                            finally {
705                                    DataAccess.cleanUp(con, ps, rs);
706                            }
707                    }
708    
709                    if (largeImageId != 0) {
710                            _sourceHook.deleteImage(largeImage);
711    
712                            runSQL("delete from Image where imageId = " + largeImageId);
713                    }
714    
715                    if ((largeImageId != thumbnailImageId) && (thumbnailImageId != 0)) {
716                            _sourceHook.deleteImage(thumbnailImage);
717    
718                            runSQL("delete from Image where imageId = " + thumbnailImageId);
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 updateIGFolderEntries() throws Exception {
792                    Connection con = null;
793                    PreparedStatement ps = null;
794                    ResultSet rs = null;
795    
796                    try {
797                            con = DataAccess.getUpgradeOptimizedConnection();
798    
799                            ps = con.prepareStatement(
800                                    "select * from IGFolder order by folderId asc");
801    
802                            rs = ps.executeQuery();
803    
804                            Map<Long, Long> folderIds = new HashMap<>();
805    
806                            while (rs.next()) {
807                                    String uuid = rs.getString("uuid_");
808                                    long folderId = rs.getLong("folderId");
809                                    long groupId = rs.getLong("groupId");
810                                    long companyId = rs.getLong("companyId");
811                                    long userId = rs.getLong("userId");
812                                    String userName = rs.getString("userName");
813                                    Timestamp createDate = rs.getTimestamp("createDate");
814                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
815                                    long parentFolderId = rs.getLong("parentFolderId");
816                                    String name = rs.getString("name");
817                                    String description = rs.getString("description");
818    
819                                    if (folderIds.containsKey(parentFolderId)) {
820                                            parentFolderId = folderIds.get(parentFolderId);
821                                    }
822    
823                                    boolean update = updateIGImageFolderId(
824                                            groupId, name, parentFolderId, folderId, folderIds);
825    
826                                    if (!update) {
827                                            addDLFolderEntry(
828                                                    uuid, folderId, groupId, companyId, userId, userName,
829                                                    createDate, modifiedDate, groupId, parentFolderId, name,
830                                                    description, modifiedDate);
831                                    }
832                            }
833    
834                            runSQL("drop table IGFolder");
835                    }
836                    finally {
837                            DataAccess.cleanUp(con, ps, rs);
838                    }
839            }
840    
841            protected void updateIGFolderPermissions() throws Exception {
842                    deleteConflictingIGPermissions(
843                            _IG_FOLDER_CLASS_NAME, DLFolder.class.getName());
844    
845                    updateIGtoDLPermissions(
846                            _IG_FOLDER_CLASS_NAME, DLFolder.class.getName());
847            }
848    
849            protected void updateIGImageEntries() throws Exception {
850                    Connection con = null;
851                    PreparedStatement ps = null;
852                    ResultSet rs = null;
853    
854                    try {
855                            con = DataAccess.getUpgradeOptimizedConnection();
856    
857                            ps = con.prepareStatement(
858                                    "select fileEntryTypeId, companyId from DLFileEntryType " +
859                                            "where name = ?");
860    
861                            ps.setString(1, DLFileEntryTypeConstants.NAME_IG_IMAGE);
862    
863                            rs = ps.executeQuery();
864    
865                            boolean hasIGImageFileEntryType = false;
866    
867                            while (rs.next()) {
868                                    long fileEntryTypeId = rs.getLong("fileEntryTypeId");
869                                    long companyId = rs.getLong("companyId");
870    
871                                    updateIGImageEntries(companyId, fileEntryTypeId);
872    
873                                    hasIGImageFileEntryType = true;
874                            }
875    
876                            if (!hasIGImageFileEntryType) {
877                                    updateIGImageEntries(0, 0);
878                            }
879    
880                            runSQL("drop table IGImage");
881                    }
882                    finally {
883                            DataAccess.cleanUp(con, ps, rs);
884                    }
885            }
886    
887            protected void updateIGImageEntries(long companyId, long fileEntryTypeId)
888                    throws Exception {
889    
890                    Connection con = null;
891                    PreparedStatement ps = null;
892                    ResultSet rs = null;
893    
894                    try {
895                            con = DataAccess.getUpgradeOptimizedConnection();
896    
897                            String sql = "select * from IGImage";
898    
899                            if (companyId != 0) {
900                                    sql = "select * from IGImage where companyId = ?";
901                            }
902    
903                            ps = con.prepareStatement(sql);
904    
905                            if (companyId != 0) {
906                                    ps.setLong(1, companyId);
907                            }
908    
909                            rs = ps.executeQuery();
910    
911                            while (rs.next()) {
912                                    String uuid = rs.getString("uuid_");
913                                    long imageId = rs.getLong("imageId");
914                                    long groupId = rs.getLong("groupId");
915                                    companyId = rs.getLong("companyId");
916                                    long userId = rs.getLong("userId");
917                                    String userName = rs.getString("userName");
918                                    Timestamp createDate = rs.getTimestamp("createDate");
919                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
920                                    long folderId = rs.getLong("folderId");
921                                    String title = rs.getString("name");
922                                    String description = rs.getString("description");
923                                    long smallImageId = rs.getLong("smallImageId");
924                                    long largeImageId = rs.getLong("largeImageId");
925                                    long custom1ImageId = rs.getLong("custom1ImageId");
926                                    long custom2ImageId = rs.getLong("custom2ImageId");
927    
928                                    Image image = getImage(largeImageId);
929    
930                                    if (image == null) {
931                                            continue;
932                                    }
933    
934                                    String extension = image.getType();
935    
936                                    String mimeType = MimeTypesUtil.getExtensionContentType(
937                                            extension);
938    
939                                    String name = String.valueOf(
940                                            increment(DLFileEntry.class.getName()));
941    
942                                    long size = image.getSize();
943    
944                                    try {
945                                            addDLFileEntry(
946                                                    uuid, imageId, groupId, companyId, userId, userName,
947                                                    userId, userName, createDate, modifiedDate, groupId,
948                                                    folderId, name, extension, mimeType, title, description,
949                                                    StringPool.BLANK, fileEntryTypeId, "1.0", size, 0,
950                                                    smallImageId, largeImageId, custom1ImageId,
951                                                    custom2ImageId);
952                                    }
953                                    catch (Exception e) {
954                                            title = title.concat(StringPool.SPACE).concat(
955                                                    String.valueOf(imageId));
956    
957                                            addDLFileEntry(
958                                                    uuid, imageId, groupId, companyId, userId, userName,
959                                                    userId, userName, createDate, modifiedDate, groupId,
960                                                    folderId, name, extension, mimeType, title, description,
961                                                    StringPool.BLANK, fileEntryTypeId, "1.0", size, 0,
962                                                    smallImageId, largeImageId, custom1ImageId,
963                                                    custom2ImageId);
964                                    }
965    
966                                    addDLFileVersion(
967                                            increment(), groupId, companyId, userId, userName,
968                                            createDate, groupId, folderId, imageId, extension, mimeType,
969                                            title, description, StringPool.BLANK, StringPool.BLANK,
970                                            fileEntryTypeId, "1.0", size, 0, userId, userName,
971                                            modifiedDate);
972                            }
973                    }
974                    finally {
975                            DataAccess.cleanUp(con, ps, rs);
976                    }
977            }
978    
979            protected boolean updateIGImageFolderId(
980                            long groupId, String name, long parentFolderId, long folderId,
981                            Map<Long, Long> folderIds)
982                    throws Exception {
983    
984                    Connection con = null;
985                    PreparedStatement ps = null;
986                    ResultSet rs = null;
987    
988                    try {
989                            con = DataAccess.getUpgradeOptimizedConnection();
990    
991                            ps = con.prepareStatement(
992                                    "select folderId from DLFolder where groupId = " + groupId +
993                                            " and parentFolderId = " + parentFolderId +
994                                                    " and name = ?");
995    
996                            ps.setString(1, name);
997    
998                            rs = ps.executeQuery();
999    
1000                            if (rs.next()) {
1001                                    long newFolderId = rs.getLong("folderId");
1002    
1003                                    runSQL(
1004                                            "update IGImage set folderId = " + newFolderId +
1005                                                    " where folderId = " + folderId);
1006    
1007                                    folderIds.put(folderId, newFolderId);
1008    
1009                                    return true;
1010                            }
1011                    }
1012                    finally {
1013                            DataAccess.cleanUp(con, ps, rs);
1014                    }
1015    
1016                    return false;
1017            }
1018    
1019            protected void updateIGImagePermissions() throws Exception {
1020                    deleteConflictingIGPermissions(
1021                            _IG_IMAGE_CLASS_NAME, DLFileEntry.class.getName());
1022    
1023                    updateIGtoDLPermissions(
1024                            _IG_IMAGE_CLASS_NAME, DLFileEntry.class.getName());
1025            }
1026    
1027            protected void updateIGtoDLPermissions(
1028                            String igResourceName, String dlResourceName)
1029                    throws Exception {
1030    
1031                    Map<String, Long> igBitwiseValues = getBitwiseValues(igResourceName);
1032    
1033                    if (igBitwiseValues.isEmpty()) {
1034                            if (_log.isWarnEnabled()) {
1035                                    _log.warn(
1036                                            "Resource actions do not exist for " + igResourceName);
1037                            }
1038    
1039                            return;
1040                    }
1041    
1042                    Map<String, Long> dlBitwiseValues = getBitwiseValues(dlResourceName);
1043    
1044                    if (dlBitwiseValues.isEmpty()) {
1045                            if (_log.isWarnEnabled()) {
1046                                    _log.warn(
1047                                            "Resource actions do not exist for " + dlResourceName);
1048                            }
1049    
1050                            return;
1051                    }
1052    
1053                    // The size of igBitwiseValues is based on the number of actions defined
1054                    // in resource actions which was 7 and 4 for IGFolder and IGImage
1055                    // respectively. This means the loop will execute at most 2^7 (128)
1056                    // times. If we were to check before update, we would still have to
1057                    // perform 128 queries, so we may as well just update 128 times even if
1058                    // no candidates exist for a given value.
1059    
1060                    for (int i = 0; i < Math.pow(2, igBitwiseValues.size()); i++) {
1061                            List<String> igActionIds = getResourceActionIds(igBitwiseValues, i);
1062    
1063                            if (igResourceName.equals(_IG_FOLDER_CLASS_NAME)) {
1064                                    Collections.replaceAll(
1065                                            igActionIds, "ADD_IMAGE", "ADD_DOCUMENT");
1066                            }
1067    
1068                            long dlActionIdsLong = getBitwiseValue(
1069                                    dlBitwiseValues, igActionIds);
1070    
1071                            runSQL(
1072                                    "update ResourcePermission set name = '" + dlResourceName +
1073                                            "', actionIds = " + dlActionIdsLong + " where name = '" +
1074                                                    igResourceName + "'" + " and actionIds = " + i);
1075                    }
1076            }
1077    
1078            private static final String _IG_FOLDER_CLASS_NAME =
1079                    "com.liferay.portlet.imagegallery.model.IGFolder";
1080    
1081            private static final String _IG_IMAGE_CLASS_NAME =
1082                    "com.liferay.portlet.imagegallery.model.IGImage";
1083    
1084            private static final Log _log = LogFactoryUtil.getLog(
1085                    UpgradeImageGallery.class);
1086    
1087            private final Hook _sourceHook;
1088            private final String _sourceHookClassName;
1089    
1090    }