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