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