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