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.util.PortalUtil;
039    import com.liferay.portal.util.PropsValues;
040    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
041    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
042    import com.liferay.portlet.documentlibrary.model.DLFolder;
043    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
044    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
045    import com.liferay.portlet.documentlibrary.util.ImageProcessorUtil;
046    
047    import java.io.IOException;
048    import java.io.InputStream;
049    
050    import java.sql.Connection;
051    import java.sql.DatabaseMetaData;
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                    Connection con = null;
337                    PreparedStatement ps = null;
338                    ResultSet rs = null;
339    
340                    try {
341                            con = DataAccess.getUpgradeOptimizedConnection();
342    
343                            DatabaseMetaData databaseMetaData = con.getMetaData();
344    
345                            boolean supportsBatchUpdates =
346                                    databaseMetaData.supportsBatchUpdates();
347    
348                            ps = con.prepareStatement(
349                                    "select companyId, scope, primKey, roleId from " +
350                                            "ResourcePermission where name = ?");
351    
352                            ps.setString(1, igResourceName);
353    
354                            rs = ps.executeQuery();
355    
356                            ps = con.prepareStatement(
357                                    "delete from ResourcePermission where name = ? and " +
358                                            "companyId = ? and scope = ? and primKey = ? and " +
359                                                    "roleId = ?");
360    
361                            int count = 0;
362    
363                            while (rs.next()) {
364                                    ps.setString(1, dlResourceName);
365                                    ps.setLong(2, rs.getLong("companyId"));
366                                    ps.setInt(3, rs.getInt("scope"));
367                                    ps.setString(4, rs.getString("primKey"));
368                                    ps.setLong(5, rs.getLong("roleId"));
369    
370                                    if (supportsBatchUpdates) {
371                                            ps.addBatch();
372    
373                                            if (count == PropsValues.HIBERNATE_JDBC_BATCH_SIZE) {
374                                                    ps.executeBatch();
375    
376                                                    count = 0;
377                                            }
378                                            else {
379                                                    count++;
380                                            }
381                                    }
382                                    else {
383                                            ps.executeUpdate();
384                                    }
385                            }
386    
387                            if (supportsBatchUpdates && (count > 0)) {
388                                    ps.executeBatch();
389                            }
390                    }
391                    finally {
392                            DataAccess.cleanUp(con, ps, rs);
393                    }
394            }
395    
396            @Override
397            protected void doUpgrade() throws Exception {
398                    addIGImageDLFileEntryType();
399                    updateIGFolderEntries();
400                    updateIGImageEntries();
401                    updateIGFolderPermissions();
402                    updateIGImagePermissions();
403    
404                    migrateImageFiles();
405    
406                    UpgradeDocumentLibrary upgradeDocumentLibrary =
407                            new UpgradeDocumentLibrary();
408    
409                    upgradeDocumentLibrary.updateSyncs();
410            }
411    
412            protected long getBitwiseValue(
413                    Map<String, Long> bitwiseValues, List<String> actionIds) {
414    
415                    long bitwiseValue = 0;
416    
417                    for (String actionId : actionIds) {
418                            Long actionIdBitwiseValue = bitwiseValues.get(actionId);
419    
420                            if (actionIdBitwiseValue == null) {
421                                    continue;
422                            }
423    
424                            bitwiseValue |= actionIdBitwiseValue;
425                    }
426    
427                    return bitwiseValue;
428            }
429    
430            protected Map<String, Long> getBitwiseValues(String name) throws Exception {
431                    Connection con = null;
432                    PreparedStatement ps = null;
433                    ResultSet rs = null;
434    
435                    try {
436                            con = DataAccess.getUpgradeOptimizedConnection();
437    
438                            ps = con.prepareStatement(
439                                    "select actionId, bitwiseValue from ResourceAction " +
440                                            "where name = ?");
441    
442                            ps.setString(1, name);
443    
444                            rs = ps.executeQuery();
445    
446                            Map<String, Long> bitwiseValues = new HashMap<>();
447    
448                            while (rs.next()) {
449                                    String actionId = rs.getString("actionId");
450                                    long bitwiseValue = rs.getLong("bitwiseValue");
451    
452                                    bitwiseValues.put(actionId, bitwiseValue);
453                            }
454    
455                            return bitwiseValues;
456                    }
457                    finally {
458                            DataAccess.cleanUp(con, ps, rs);
459                    }
460            }
461    
462            protected long getCompanyGroupId(long companyId) throws Exception {
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 groupId from Group_ where classNameId = ? and " +
472                                            "classPK = ?");
473    
474                            ps.setLong(1, PortalUtil.getClassNameId(Company.class.getName()));
475                            ps.setLong(2, companyId);
476    
477                            rs = ps.executeQuery();
478    
479                            if (rs.next()) {
480                                    return rs.getLong("groupId");
481                            }
482    
483                            return 0;
484                    }
485                    finally {
486                            DataAccess.cleanUp(con, ps, rs);
487                    }
488            }
489    
490            protected byte[] getDatabaseImageAsBytes(Image image) throws SQLException {
491                    Connection con = null;
492                    PreparedStatement ps = null;
493                    ResultSet rs = null;
494    
495                    try {
496                            con = DataAccess.getUpgradeOptimizedConnection();
497    
498                            ps = con.prepareStatement(
499                                    "select text_ from Image where imageId = ?");
500    
501                            ps.setLong(1, image.getImageId());
502    
503                            rs = ps.executeQuery();
504    
505                            if (rs.next()) {
506                                    String getTextObj = rs.getString("text_");
507    
508                                    return (byte[])Base64.stringToObject(getTextObj);
509                            }
510    
511                            if (_log.isWarnEnabled()) {
512                                    _log.warn(
513                                            "Image " + image.getImageId() + " is not in the database");
514                            }
515                    }
516                    finally {
517                            DataAccess.cleanUp(con, ps, rs);
518                    }
519    
520                    return new byte[0];
521            }
522    
523            protected long getDefaultUserId(long companyId) throws Exception {
524                    Connection con = null;
525                    PreparedStatement ps = null;
526                    ResultSet rs = null;
527    
528                    try {
529                            con = DataAccess.getUpgradeOptimizedConnection();
530    
531                            ps = con.prepareStatement(
532                                    "select userId from User_ where companyId = ? and " +
533                                            "defaultUser = ?");
534    
535                            ps.setLong(1, companyId);
536                            ps.setBoolean(2, true);
537    
538                            rs = ps.executeQuery();
539    
540                            if (rs.next()) {
541                                    return rs.getLong("userId");
542                            }
543    
544                            return 0;
545                    }
546                    finally {
547                            DataAccess.cleanUp(con, ps, rs);
548                    }
549            }
550    
551            protected byte[] getHookImageAsBytes(Image image)
552                    throws IOException, PortalException, SQLException {
553    
554                    InputStream is = getHookImageAsStream(image);
555    
556                    return FileUtil.getBytes(is);
557            }
558    
559            protected InputStream getHookImageAsStream(Image image)
560                    throws PortalException, SQLException {
561    
562                    InputStream is = null;
563    
564                    if (_sourceHook instanceof DatabaseHook) {
565                            byte[] bytes = getDatabaseImageAsBytes(image);
566    
567                            is = new UnsyncByteArrayInputStream(bytes);
568                    }
569                    else {
570                            is = _sourceHook.getImageAsStream(image);
571                    }
572    
573                    return is;
574            }
575    
576            protected Object[] getImage(long imageId) throws Exception {
577                    Connection con = null;
578                    PreparedStatement ps = null;
579                    ResultSet rs = null;
580    
581                    try {
582                            con = DataAccess.getUpgradeOptimizedConnection();
583    
584                            ps = con.prepareStatement(
585                                    "select type_, size_ from Image where imageId = " + imageId);
586    
587                            rs = ps.executeQuery();
588    
589                            if (rs.next()) {
590                                    String type = rs.getString("type_");
591                                    long size = rs.getInt("size_");
592    
593                                    return new Object[] {type, size};
594                            }
595    
596                            return null;
597                    }
598                    finally {
599                            DataAccess.cleanUp(con, ps, rs);
600                    }
601            }
602    
603            protected List<String> getResourceActionIds(
604                    Map<String, Long> bitwiseValues, long actionIdsLong) {
605    
606                    List<String> actionIds = new ArrayList<>();
607    
608                    for (String actionId : bitwiseValues.keySet()) {
609                            long bitwiseValue = bitwiseValues.get(actionId);
610    
611                            if ((actionIdsLong & bitwiseValue) == bitwiseValue) {
612                                    actionIds.add(actionId);
613                            }
614                    }
615    
616                    return actionIds;
617            }
618    
619            protected void migrateFile(
620                            long repositoryId, long companyId, String name, Image image)
621                    throws Exception {
622    
623                    byte[] bytes = getHookImageAsBytes(image);
624    
625                    if (name == null) {
626                            name = image.getImageId() + StringPool.PERIOD + image.getType();
627                    }
628    
629                    if (DLStoreUtil.hasFile(companyId, repositoryId, name)) {
630                            DLStoreUtil.deleteFile(companyId, repositoryId, name);
631                    }
632    
633                    DLStoreUtil.addFile(companyId, repositoryId, name, false, bytes);
634            }
635    
636            protected void migrateImage(long imageId) throws Exception {
637                    Image image = ImageLocalServiceUtil.getImage(imageId);
638    
639                    try {
640                            migrateFile(0, 0, null, image);
641                    }
642                    catch (Exception e) {
643                            if (_log.isWarnEnabled()) {
644                                    _log.warn("Ignoring exception for image " + imageId, e);
645                            }
646    
647                            return;
648                    }
649    
650                    _sourceHook.deleteImage(image);
651            }
652    
653            protected void migrateImage(
654                            long fileEntryId, long companyId, long groupId, long folderId,
655                            String name, long smallImageId, long largeImageId,
656                            long custom1ImageId, long custom2ImageId)
657                    throws Exception {
658    
659                    Image largeImage = null;
660    
661                    if (largeImageId != 0) {
662                            largeImage = ImageLocalServiceUtil.getImage(largeImageId);
663    
664                            long repositoryId = DLFolderConstants.getDataRepositoryId(
665                                    groupId, folderId);
666    
667                            try {
668                                    migrateFile(repositoryId, companyId, name, largeImage);
669                            }
670                            catch (Exception e) {
671                                    if (_log.isWarnEnabled()) {
672                                            _log.warn(
673                                                    "Ignoring exception for image " + largeImageId, e);
674                                    }
675                            }
676                    }
677    
678                    long thumbnailImageId = 0;
679    
680                    if (smallImageId != 0) {
681                            thumbnailImageId = smallImageId;
682                    }
683                    else if (custom1ImageId != 0) {
684                            thumbnailImageId = custom1ImageId;
685                    }
686                    else if (custom2ImageId != 0) {
687                            thumbnailImageId = custom2ImageId;
688                    }
689    
690                    Image thumbnailImage = null;
691    
692                    if (thumbnailImageId != 0) {
693                            thumbnailImage = ImageLocalServiceUtil.getImage(thumbnailImageId);
694    
695                            Connection con = null;
696                            PreparedStatement ps = null;
697                            ResultSet rs = null;
698    
699                            try {
700                                    con = DataAccess.getUpgradeOptimizedConnection();
701    
702                                    ps = con.prepareStatement(
703                                            "select max(fileVersionId) from DLFileVersion where " +
704                                                    "fileEntryId = " + fileEntryId);
705    
706                                    rs = ps.executeQuery();
707    
708                                    if (rs.next()) {
709                                            long fileVersionId = rs.getLong(1);
710    
711                                            InputStream is = getHookImageAsStream(thumbnailImage);
712    
713                                            ImageProcessorUtil.storeThumbnail(
714                                                    companyId, groupId, fileEntryId, fileVersionId,
715                                                    custom1ImageId, custom2ImageId, is,
716                                                    thumbnailImage.getType());
717                                    }
718                            }
719                            catch (Exception e) {
720                                    if (_log.isWarnEnabled()) {
721                                            _log.warn(
722                                                    "Ignoring exception for image " + thumbnailImageId, e);
723                                    }
724                            }
725                            finally {
726                                    DataAccess.cleanUp(con, ps, rs);
727                            }
728                    }
729    
730                    if (largeImageId != 0) {
731                            _sourceHook.deleteImage(largeImage);
732    
733                            runSQL("delete from Image where imageId = " + largeImageId);
734                    }
735    
736                    if ((largeImageId != thumbnailImageId) && (thumbnailImageId != 0)) {
737                            _sourceHook.deleteImage(thumbnailImage);
738    
739                            runSQL("delete from Image where imageId = " + thumbnailImageId);
740                    }
741            }
742    
743            protected void migrateImageFiles() throws Exception {
744                    Connection con = null;
745                    PreparedStatement ps = null;
746                    ResultSet rs = null;
747    
748                    try {
749                            con = DataAccess.getUpgradeOptimizedConnection();
750    
751                            StringBundler sb = new StringBundler(8);
752    
753                            sb.append("select fileEntryId, companyId, groupId, folderId, ");
754                            sb.append("name, smallImageId, largeImageId, custom1ImageId, ");
755                            sb.append("custom2ImageId from DLFileEntry where ((smallImageId ");
756                            sb.append("is not null) and (smallImageId != 0)) or ");
757                            sb.append("((largeImageId is not null) and (largeImageId != 0)) ");
758                            sb.append("or ((custom1ImageId is not null) and (custom1ImageId ");
759                            sb.append("!= 0)) or ((custom2ImageId is not null) and ");
760                            sb.append("(custom2ImageId != 0))");
761    
762                            ps = con.prepareStatement(sb.toString());
763    
764                            rs = ps.executeQuery();
765    
766                            while (rs.next()) {
767                                    long fileEntryId = rs.getLong("fileEntryId");
768                                    long companyId = rs.getLong("companyId");
769                                    long groupId = rs.getLong("groupId");
770                                    long folderId = rs.getLong("folderId");
771                                    String name = rs.getString("name");
772                                    long smallImageId = rs.getLong("smallImageId");
773                                    long largeImageId = rs.getLong("largeImageId");
774                                    long custom1ImageId = rs.getLong("custom1ImageId");
775                                    long custom2ImageId = rs.getLong("custom2ImageId");
776    
777                                    migrateImage(
778                                            fileEntryId, companyId, groupId, folderId, name,
779                                            smallImageId, largeImageId, custom1ImageId, custom2ImageId);
780                            }
781                    }
782                    finally {
783                            DataAccess.cleanUp(con, ps, rs);
784                    }
785    
786                    if (_sourceHookClassName.equals(DLHook.class.getName())) {
787                            return;
788                    }
789    
790                    try {
791                            con = DataAccess.getUpgradeOptimizedConnection();
792    
793                            ps = con.prepareStatement("select imageId from Image");
794    
795                            rs = ps.executeQuery();
796    
797                            while (rs.next()) {
798                                    long imageId = rs.getLong("imageId");
799    
800                                    migrateImage(imageId);
801                            }
802                    }
803                    finally {
804                            DataAccess.cleanUp(con, ps, rs);
805                    }
806    
807                    if (_sourceHookClassName.equals(DatabaseHook.class.getName())) {
808                            runSQL("update Image set text_ = ''");
809                    }
810            }
811    
812            protected void updateIGFolderEntries() throws Exception {
813                    Connection con = null;
814                    PreparedStatement ps = null;
815                    ResultSet rs = null;
816    
817                    try {
818                            con = DataAccess.getUpgradeOptimizedConnection();
819    
820                            ps = con.prepareStatement(
821                                    "select * from IGFolder order by folderId asc");
822    
823                            rs = ps.executeQuery();
824    
825                            Map<Long, Long> folderIds = new HashMap<>();
826    
827                            while (rs.next()) {
828                                    String uuid = rs.getString("uuid_");
829                                    long folderId = rs.getLong("folderId");
830                                    long groupId = rs.getLong("groupId");
831                                    long companyId = rs.getLong("companyId");
832                                    long userId = rs.getLong("userId");
833                                    String userName = rs.getString("userName");
834                                    Timestamp createDate = rs.getTimestamp("createDate");
835                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
836                                    long parentFolderId = rs.getLong("parentFolderId");
837                                    String name = rs.getString("name");
838                                    String description = rs.getString("description");
839    
840                                    if (folderIds.containsKey(parentFolderId)) {
841                                            parentFolderId = folderIds.get(parentFolderId);
842                                    }
843    
844                                    boolean update = updateIGImageFolderId(
845                                            groupId, name, parentFolderId, folderId, folderIds);
846    
847                                    if (!update) {
848                                            addDLFolderEntry(
849                                                    uuid, folderId, groupId, companyId, userId, userName,
850                                                    createDate, modifiedDate, groupId, parentFolderId, name,
851                                                    description, modifiedDate);
852                                    }
853                            }
854    
855                            runSQL("drop table IGFolder");
856                    }
857                    finally {
858                            DataAccess.cleanUp(con, ps, rs);
859                    }
860            }
861    
862            protected void updateIGFolderPermissions() throws Exception {
863                    deleteConflictingIGPermissions(
864                            _IG_FOLDER_CLASS_NAME, DLFolder.class.getName());
865    
866                    updateIGtoDLPermissions(
867                            _IG_FOLDER_CLASS_NAME, DLFolder.class.getName());
868            }
869    
870            protected void updateIGImageEntries() throws Exception {
871                    Connection con = null;
872                    PreparedStatement ps = null;
873                    ResultSet rs = null;
874    
875                    try {
876                            con = DataAccess.getUpgradeOptimizedConnection();
877    
878                            ps = con.prepareStatement(
879                                    "select fileEntryTypeId, companyId from DLFileEntryType " +
880                                            "where name = ?");
881    
882                            ps.setString(1, DLFileEntryTypeConstants.NAME_IG_IMAGE);
883    
884                            rs = ps.executeQuery();
885    
886                            boolean hasIGImageFileEntryType = false;
887    
888                            while (rs.next()) {
889                                    long fileEntryTypeId = rs.getLong("fileEntryTypeId");
890                                    long companyId = rs.getLong("companyId");
891    
892                                    updateIGImageEntries(companyId, fileEntryTypeId);
893    
894                                    hasIGImageFileEntryType = true;
895                            }
896    
897                            if (!hasIGImageFileEntryType) {
898                                    updateIGImageEntries(0, 0);
899                            }
900    
901                            runSQL("drop table IGImage");
902                    }
903                    finally {
904                            DataAccess.cleanUp(con, ps, rs);
905                    }
906            }
907    
908            protected void updateIGImageEntries(long companyId, long fileEntryTypeId)
909                    throws Exception {
910    
911                    Connection con = null;
912                    PreparedStatement ps = null;
913                    ResultSet rs = null;
914    
915                    try {
916                            con = DataAccess.getUpgradeOptimizedConnection();
917    
918                            String sql = "select * from IGImage";
919    
920                            if (companyId != 0) {
921                                    sql = "select * from IGImage where companyId = ?";
922                            }
923    
924                            ps = con.prepareStatement(sql);
925    
926                            if (companyId != 0) {
927                                    ps.setLong(1, companyId);
928                            }
929    
930                            rs = ps.executeQuery();
931    
932                            while (rs.next()) {
933                                    String uuid = rs.getString("uuid_");
934                                    long imageId = rs.getLong("imageId");
935                                    long groupId = rs.getLong("groupId");
936                                    companyId = rs.getLong("companyId");
937                                    long userId = rs.getLong("userId");
938                                    String userName = rs.getString("userName");
939                                    Timestamp createDate = rs.getTimestamp("createDate");
940                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
941                                    long folderId = rs.getLong("folderId");
942                                    String title = rs.getString("name");
943                                    String description = rs.getString("description");
944                                    long smallImageId = rs.getLong("smallImageId");
945                                    long largeImageId = rs.getLong("largeImageId");
946                                    long custom1ImageId = rs.getLong("custom1ImageId");
947                                    long custom2ImageId = rs.getLong("custom2ImageId");
948    
949                                    Object[] image = getImage(largeImageId);
950    
951                                    if (image == null) {
952                                            continue;
953                                    }
954    
955                                    String extension = (String)image[0];
956    
957                                    String mimeType = MimeTypesUtil.getExtensionContentType(
958                                            extension);
959    
960                                    String name = String.valueOf(
961                                            increment(DLFileEntry.class.getName()));
962    
963                                    long size = (Long)image[1];
964    
965                                    try {
966                                            addDLFileEntry(
967                                                    uuid, imageId, groupId, companyId, userId, userName,
968                                                    userId, userName, createDate, modifiedDate, groupId,
969                                                    folderId, name, extension, mimeType, title, description,
970                                                    StringPool.BLANK, fileEntryTypeId, "1.0", size, 0,
971                                                    smallImageId, largeImageId, custom1ImageId,
972                                                    custom2ImageId);
973                                    }
974                                    catch (Exception e) {
975                                            title = title.concat(StringPool.SPACE).concat(
976                                                    String.valueOf(imageId));
977    
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    
987                                    addDLFileVersion(
988                                            increment(), groupId, companyId, userId, userName,
989                                            createDate, groupId, folderId, imageId, extension, mimeType,
990                                            title, description, StringPool.BLANK, StringPool.BLANK,
991                                            fileEntryTypeId, "1.0", size, 0, userId, userName,
992                                            modifiedDate);
993                            }
994                    }
995                    finally {
996                            DataAccess.cleanUp(con, ps, rs);
997                    }
998            }
999    
1000            protected boolean updateIGImageFolderId(
1001                            long groupId, String name, long parentFolderId, long folderId,
1002                            Map<Long, Long> folderIds)
1003                    throws Exception {
1004    
1005                    Connection con = null;
1006                    PreparedStatement ps = null;
1007                    ResultSet rs = null;
1008    
1009                    try {
1010                            con = DataAccess.getUpgradeOptimizedConnection();
1011    
1012                            ps = con.prepareStatement(
1013                                    "select folderId from DLFolder where groupId = " + groupId +
1014                                            " and parentFolderId = " + parentFolderId +
1015                                                    " and name = ?");
1016    
1017                            ps.setString(1, name);
1018    
1019                            rs = ps.executeQuery();
1020    
1021                            if (rs.next()) {
1022                                    long newFolderId = rs.getLong("folderId");
1023    
1024                                    runSQL(
1025                                            "update IGImage set folderId = " + newFolderId +
1026                                                    " where folderId = " + folderId);
1027    
1028                                    folderIds.put(folderId, newFolderId);
1029    
1030                                    return true;
1031                            }
1032                    }
1033                    finally {
1034                            DataAccess.cleanUp(con, ps, rs);
1035                    }
1036    
1037                    return false;
1038            }
1039    
1040            protected void updateIGImagePermissions() throws Exception {
1041                    deleteConflictingIGPermissions(
1042                            _IG_IMAGE_CLASS_NAME, DLFileEntry.class.getName());
1043    
1044                    updateIGtoDLPermissions(
1045                            _IG_IMAGE_CLASS_NAME, DLFileEntry.class.getName());
1046            }
1047    
1048            protected void updateIGtoDLPermissions(
1049                            String igResourceName, String dlResourceName)
1050                    throws Exception {
1051    
1052                    Map<String, Long> igBitwiseValues = getBitwiseValues(igResourceName);
1053    
1054                    if (igBitwiseValues.isEmpty()) {
1055                            if (_log.isWarnEnabled()) {
1056                                    _log.warn(
1057                                            "Resource actions do not exist for " + igResourceName);
1058                            }
1059    
1060                            return;
1061                    }
1062    
1063                    Map<String, Long> dlBitwiseValues = getBitwiseValues(dlResourceName);
1064    
1065                    if (dlBitwiseValues.isEmpty()) {
1066                            if (_log.isWarnEnabled()) {
1067                                    _log.warn(
1068                                            "Resource actions do not exist for " + dlResourceName);
1069                            }
1070    
1071                            return;
1072                    }
1073    
1074                    // The size of igBitwiseValues is based on the number of actions defined
1075                    // in resource actions which was 7 and 4 for IGFolder and IGImage
1076                    // respectively. This means the loop will execute at most 2^7 (128)
1077                    // times. If we were to check before update, we would still have to
1078                    // perform 128 queries, so we may as well just update 128 times even if
1079                    // no candidates exist for a given value.
1080    
1081                    for (int i = 0; i < Math.pow(2, igBitwiseValues.size()); i++) {
1082                            List<String> igActionIds = getResourceActionIds(igBitwiseValues, i);
1083    
1084                            if (igResourceName.equals(_IG_FOLDER_CLASS_NAME)) {
1085                                    Collections.replaceAll(
1086                                            igActionIds, "ADD_IMAGE", "ADD_DOCUMENT");
1087                            }
1088    
1089                            long dlActionIdsLong = getBitwiseValue(
1090                                    dlBitwiseValues, igActionIds);
1091    
1092                            runSQL(
1093                                    "update ResourcePermission set name = '" + dlResourceName +
1094                                            "', actionIds = " + dlActionIdsLong + " where name = '" +
1095                                                    igResourceName + "'" + " and actionIds = " + i);
1096                    }
1097            }
1098    
1099            private static final String _IG_FOLDER_CLASS_NAME =
1100                    "com.liferay.portlet.imagegallery.model.IGFolder";
1101    
1102            private static final String _IG_IMAGE_CLASS_NAME =
1103                    "com.liferay.portlet.imagegallery.model.IGImage";
1104    
1105            private static final Log _log = LogFactoryUtil.getLog(
1106                    UpgradeImageGallery.class);
1107    
1108            private final Hook _sourceHook;
1109            private final String _sourceHookClassName;
1110    
1111    }