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