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.kernel.upgrade.v6_2_0;
016    
017    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
021    import com.liferay.portal.kernel.util.ArrayUtil;
022    import com.liferay.portal.kernel.util.FileUtil;
023    import com.liferay.portal.kernel.util.MimeTypesUtil;
024    import com.liferay.portal.kernel.util.StringBundler;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
027    import com.liferay.portal.model.CompanyConstants;
028    import com.liferay.portal.model.ResourceConstants;
029    import com.liferay.portal.model.ResourcePermission;
030    import com.liferay.portal.model.RoleConstants;
031    import com.liferay.portal.security.permission.ActionKeys;
032    import com.liferay.portal.util.PortalUtil;
033    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
034    import com.liferay.portlet.documentlibrary.model.DLFolder;
035    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
036    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
037    
038    import java.sql.PreparedStatement;
039    import java.sql.ResultSet;
040    import java.sql.Timestamp;
041    
042    import java.util.ArrayList;
043    import java.util.HashMap;
044    import java.util.List;
045    import java.util.Map;
046    
047    /**
048     * @author Eudaldo Alonso
049     */
050    public abstract class BaseUpgradeAttachments extends UpgradeProcess {
051    
052            protected long addDLFileEntry(
053                            long groupId, long companyId, long userId, String className,
054                            long classPK, String userName, Timestamp createDate,
055                            long repositoryId, long folderId, String name, String extension,
056                            String mimeType, String title, long size)
057                    throws Exception {
058    
059                    PreparedStatement ps = null;
060    
061                    try {
062                            long fileEntryId = increment();
063    
064                            StringBundler sb = new StringBundler(9);
065    
066                            sb.append("insert into DLFileEntry (uuid_, fileEntryId, groupId, ");
067                            sb.append("companyId, userId, userName, createDate, ");
068                            sb.append("modifiedDate, classNameId, classPK, repositoryId, ");
069                            sb.append("folderId, name, extension, mimeType, title, ");
070                            sb.append("description, extraSettings, fileEntryTypeId, version, ");
071                            sb.append("size_, readCount, smallImageId, largeImageId, ");
072                            sb.append("custom1ImageId, custom2ImageId) values (?, ?, ?, ?, ");
073                            sb.append("?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ");
074                            sb.append("?, ?, ?, ?)");
075    
076                            String sql = sb.toString();
077    
078                            ps = connection.prepareStatement(sql);
079    
080                            ps.setString(1, PortalUUIDUtil.generate());
081                            ps.setLong(2, fileEntryId);
082                            ps.setLong(3, groupId);
083                            ps.setLong(4, companyId);
084                            ps.setLong(5, userId);
085                            ps.setString(6, userName);
086                            ps.setTimestamp(7, createDate);
087                            ps.setTimestamp(8, createDate);
088                            ps.setLong(9, PortalUtil.getClassNameId(className));
089                            ps.setLong(10, classPK);
090                            ps.setLong(11, repositoryId);
091                            ps.setLong(12, folderId);
092                            ps.setString(13, name);
093                            ps.setString(14, extension);
094                            ps.setString(15, mimeType);
095                            ps.setString(16, title);
096                            ps.setString(17, StringPool.BLANK);
097                            ps.setString(18, StringPool.BLANK);
098                            ps.setLong(19, 0);
099                            ps.setString(20, "1.0");
100                            ps.setLong(21, size);
101                            ps.setInt(22, 0);
102                            ps.setLong(23, 0);
103                            ps.setLong(24, 0);
104                            ps.setLong(25, 0);
105                            ps.setLong(26, 0);
106    
107                            ps.executeUpdate();
108    
109                            Map<String, Long> bitwiseValues = getBitwiseValues(
110                                    DLFileEntry.class.getName());
111    
112                            List<String> actionIds = new ArrayList<>();
113    
114                            actionIds.add(ActionKeys.VIEW);
115    
116                            long bitwiseValue = getBitwiseValue(bitwiseValues, actionIds);
117    
118                            addResourcePermission(
119                                    companyId, DLFileEntry.class.getName(), fileEntryId,
120                                    getRoleId(companyId, RoleConstants.GUEST), bitwiseValue);
121                            addResourcePermission(
122                                    companyId, DLFileEntry.class.getName(), fileEntryId,
123                                    getRoleId(companyId, RoleConstants.SITE_MEMBER), bitwiseValue);
124    
125                            return fileEntryId;
126                    }
127                    catch (Exception e) {
128                            if (_log.isWarnEnabled()) {
129                                    _log.warn("Unable to add file entry " + name, e);
130                            }
131    
132                            return -1;
133                    }
134                    finally {
135                            DataAccess.cleanUp(ps);
136                    }
137            }
138    
139            protected void addDLFileVersion(
140                            long fileVersionId, long groupId, long companyId, long userId,
141                            String userName, Timestamp createDate, long repositoryId,
142                            long folderId, long fileEntryId, String extension, String mimeType,
143                            String title, long size)
144                    throws Exception {
145    
146                    PreparedStatement ps = null;
147    
148                    try {
149                            StringBundler sb = new StringBundler(8);
150    
151                            sb.append("insert into DLFileVersion (uuid_, fileVersionId, ");
152                            sb.append("groupId, companyId, userId, userName, createDate, ");
153                            sb.append("modifiedDate, repositoryId, folderId, fileEntryId, ");
154                            sb.append("extension, mimeType, title, description, changeLog, ");
155                            sb.append("extraSettings, fileEntryTypeId, version, size_, ");
156                            sb.append("status, statusByUserId, statusByUserName, statusDate) ");
157                            sb.append("values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ");
158                            sb.append("?, ?, ?, ?, ?, ?, ?, ?, ?)");
159    
160                            String sql = sb.toString();
161    
162                            ps = connection.prepareStatement(sql);
163    
164                            ps.setString(1, PortalUUIDUtil.generate());
165                            ps.setLong(2, fileVersionId);
166                            ps.setLong(3, groupId);
167                            ps.setLong(4, companyId);
168                            ps.setLong(5, userId);
169                            ps.setString(6, userName);
170                            ps.setTimestamp(7, createDate);
171                            ps.setTimestamp(8, createDate);
172                            ps.setLong(9, repositoryId);
173                            ps.setLong(10, folderId);
174                            ps.setLong(11, fileEntryId);
175                            ps.setString(12, extension);
176                            ps.setString(13, mimeType);
177                            ps.setString(14, title);
178                            ps.setString(15, StringPool.BLANK);
179                            ps.setString(16, StringPool.BLANK);
180                            ps.setString(17, StringPool.BLANK);
181                            ps.setLong(18, 0);
182                            ps.setString(19, "1.0");
183                            ps.setLong(20, size);
184                            ps.setInt(21, 0);
185                            ps.setLong(22, userId);
186                            ps.setString(23, userName);
187                            ps.setTimestamp(24, createDate);
188    
189                            ps.executeUpdate();
190                    }
191                    catch (Exception e) {
192                            if (_log.isWarnEnabled()) {
193                                    _log.warn(
194                                            "Unable to add file version 1.0 for file entry " + title,
195                                            e);
196                            }
197                    }
198                    finally {
199                            DataAccess.cleanUp(ps);
200                    }
201            }
202    
203            protected long addDLFolder(
204                            long folderId, long groupId, long companyId, long userId,
205                            String userName, Timestamp createDate, long repositoryId,
206                            boolean mountPoint, long parentFolderId, String name,
207                            boolean hidden)
208                    throws Exception {
209    
210                    PreparedStatement ps = null;
211    
212                    try {
213                            StringBundler sb = new StringBundler(8);
214    
215                            sb.append("insert into DLFolder (uuid_, folderId, groupId, ");
216                            sb.append("companyId, userId, userName, createDate, ");
217                            sb.append("modifiedDate, repositoryId, mountPoint, ");
218                            sb.append("parentFolderId, name, description, lastPostDate, ");
219                            sb.append("defaultFileEntryTypeId, hidden_, ");
220                            sb.append("overrideFileEntryTypes, status, statusByUserId, ");
221                            sb.append("statusByUserName, statusDate) values (?, ?, ?, ?, ?, ");
222                            sb.append("?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
223    
224                            String sql = sb.toString();
225    
226                            ps = connection.prepareStatement(sql);
227    
228                            ps.setString(1, PortalUUIDUtil.generate());
229                            ps.setLong(2, folderId);
230                            ps.setLong(3, groupId);
231                            ps.setLong(4, companyId);
232                            ps.setLong(5, userId);
233                            ps.setString(6, userName);
234                            ps.setTimestamp(7, createDate);
235                            ps.setTimestamp(8, createDate);
236                            ps.setLong(9, repositoryId);
237                            ps.setBoolean(10, mountPoint);
238                            ps.setLong(11, parentFolderId);
239                            ps.setString(12, name);
240                            ps.setString(13, StringPool.BLANK);
241                            ps.setTimestamp(14, createDate);
242                            ps.setLong(15, 0);
243                            ps.setBoolean(16, hidden);
244                            ps.setBoolean(17, false);
245                            ps.setLong(18, 0);
246                            ps.setLong(19, userId);
247                            ps.setString(20, userName);
248                            ps.setTimestamp(21, createDate);
249    
250                            ps.executeUpdate();
251    
252                            Map<String, Long> bitwiseValues = getBitwiseValues(
253                                    DLFolder.class.getName());
254    
255                            List<String> guestActionIds = new ArrayList<>();
256    
257                            guestActionIds.add(ActionKeys.VIEW);
258    
259                            long guestBitwiseValue = getBitwiseValue(
260                                    bitwiseValues, guestActionIds);
261    
262                            addResourcePermission(
263                                    companyId, DLFolder.class.getName(), folderId,
264                                    getRoleId(companyId, RoleConstants.GUEST), guestBitwiseValue);
265    
266                            List<String> siteMemberActionIds = new ArrayList<>();
267    
268                            siteMemberActionIds.add(ActionKeys.ADD_DOCUMENT);
269                            siteMemberActionIds.add(ActionKeys.ADD_SUBFOLDER);
270                            siteMemberActionIds.add(ActionKeys.VIEW);
271    
272                            long siteMemberBitwiseValue = getBitwiseValue(
273                                    bitwiseValues, siteMemberActionIds);
274    
275                            addResourcePermission(
276                                    companyId, DLFolder.class.getName(), folderId,
277                                    getRoleId(companyId, RoleConstants.SITE_MEMBER),
278                                    siteMemberBitwiseValue);
279    
280                            return folderId;
281                    }
282                    catch (Exception e) {
283                            if (_log.isWarnEnabled()) {
284                                    _log.warn("Unable to add folder " + name, e);
285                            }
286    
287                            return -1;
288                    }
289                    finally {
290                            DataAccess.cleanUp(ps);
291                    }
292            }
293    
294            protected long addRepository(
295                            long groupId, long companyId, long userId, String userName,
296                            Timestamp createDate, long classNameId, String portletId)
297                    throws Exception {
298    
299                    long repositoryId = increment();
300    
301                    long folderId = addDLFolder(
302                            increment(), groupId, companyId, userId, userName, createDate,
303                            repositoryId, true, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
304                            portletId, true);
305    
306                    if (folderId < 0) {
307                            return -1;
308                    }
309    
310                    PreparedStatement ps = null;
311    
312                    try {
313                            StringBundler sb = new StringBundler(5);
314    
315                            sb.append("insert into Repository (uuid_, repositoryId, groupId, ");
316                            sb.append("companyId, userId, userName, createDate, ");
317                            sb.append("modifiedDate, classNameId, name, description, ");
318                            sb.append("portletId, typeSettings, dlFolderId) values (?, ?, ?, ");
319                            sb.append("?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
320    
321                            ps = connection.prepareStatement(sb.toString());
322    
323                            ps.setString(1, PortalUUIDUtil.generate());
324                            ps.setLong(2, repositoryId);
325                            ps.setLong(3, groupId);
326                            ps.setLong(4, companyId);
327                            ps.setLong(5, userId);
328                            ps.setString(6, userName);
329                            ps.setTimestamp(7, createDate);
330                            ps.setTimestamp(8, createDate);
331                            ps.setLong(9, classNameId);
332                            ps.setString(10, portletId);
333                            ps.setString(11, StringPool.BLANK);
334                            ps.setString(12, portletId);
335                            ps.setString(13, StringPool.BLANK);
336                            ps.setLong(14, folderId);
337    
338                            ps.executeUpdate();
339    
340                            return repositoryId;
341                    }
342                    catch (Exception e) {
343                            if (_log.isWarnEnabled()) {
344                                    _log.warn(
345                                            "Unable to add repository for portlet " + portletId, e);
346                            }
347    
348                            return -1;
349                    }
350                    finally {
351                            DataAccess.cleanUp(ps);
352                    }
353            }
354    
355            protected void addResourcePermission(
356                            long companyId, String className, long primKey, long roleId,
357                            long actionIds)
358                    throws Exception {
359    
360                    PreparedStatement ps = null;
361    
362                    try {
363                            long resourcePermissionId = increment(
364                                    ResourcePermission.class.getName());
365    
366                            StringBundler sb = new StringBundler(3);
367    
368                            sb.append("insert into ResourcePermission (resourcePermissionId, ");
369                            sb.append("companyId, name, scope, primKey, roleId, ownerId, ");
370                            sb.append("actionIds) values (?, ?, ?, ?, ?, ?, ?, ?)");
371    
372                            String sql = sb.toString();
373    
374                            ps = connection.prepareStatement(sql);
375    
376                            ps.setLong(1, resourcePermissionId);
377                            ps.setLong(2, companyId);
378                            ps.setString(3, className);
379                            ps.setInt(4, ResourceConstants.SCOPE_INDIVIDUAL);
380                            ps.setLong(5, primKey);
381                            ps.setLong(6, roleId);
382                            ps.setLong(7, 0);
383                            ps.setLong(8, actionIds);
384    
385                            ps.executeUpdate();
386                    }
387                    catch (Exception e) {
388                            if (_log.isWarnEnabled()) {
389                                    _log.warn("Unable to add resource permission " + className, e);
390                            }
391                    }
392                    finally {
393                            DataAccess.cleanUp(ps);
394                    }
395            }
396    
397            @Override
398            protected void doUpgrade() throws Exception {
399                    updateAttachments();
400            }
401    
402            protected String[] getAttachments(
403                            long companyId, long containerModelId, long resourcePrimKey)
404                    throws Exception {
405    
406                    String dirName = getDirName(containerModelId, resourcePrimKey);
407    
408                    return DLStoreUtil.getFileNames(
409                            companyId, CompanyConstants.SYSTEM, dirName);
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                    Map<String, Long> bitwiseValues = _bitwiseValues.get(name);
432    
433                    if (bitwiseValues != null) {
434                            return bitwiseValues;
435                    }
436    
437                    PreparedStatement ps = null;
438                    ResultSet rs = null;
439    
440                    try {
441                            ps = connection.prepareStatement(
442                                    "select actionId, bitwiseValue from ResourceAction " +
443                                            "where name = ?");
444    
445                            ps.setString(1, name);
446    
447                            rs = ps.executeQuery();
448    
449                            bitwiseValues = new HashMap<>();
450    
451                            while (rs.next()) {
452                                    String actionId = rs.getString("actionId");
453                                    long bitwiseValue = rs.getLong("bitwiseValue");
454    
455                                    bitwiseValues.put(actionId, bitwiseValue);
456                            }
457    
458                            _bitwiseValues.put(name, bitwiseValues);
459    
460                            return bitwiseValues;
461                    }
462                    finally {
463                            DataAccess.cleanUp(ps, rs);
464                    }
465            }
466    
467            protected abstract String getClassName();
468    
469            protected long getClassNameId() {
470                    return PortalUtil.getClassNameId(getClassName());
471            }
472    
473            protected long getContainerModelFolderId(
474                            long groupId, long companyId, long resourcePrimKey,
475                            long containerModelId, long userId, String userName,
476                            Timestamp createDate)
477                    throws Exception {
478    
479                    return DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
480            }
481    
482            protected abstract String getDirName(
483                    long containerModelId, long resourcePrimKey);
484    
485            protected long getFolderId(
486                            long groupId, long companyId, long userId, String userName,
487                            Timestamp createDate, long repositoryId, long parentFolderId,
488                            String name, boolean hidden)
489                    throws Exception {
490    
491                    if ((repositoryId < 0) || (parentFolderId < 0)) {
492                            return -1;
493                    }
494    
495                    PreparedStatement ps = null;
496                    ResultSet rs = null;
497    
498                    try {
499                            ps = connection.prepareStatement(
500                                    "select folderId from DLFolder where repositoryId = ? and " +
501                                            "parentFolderId = ? and name = ?");
502    
503                            ps.setLong(1, repositoryId);
504                            ps.setLong(2, parentFolderId);
505                            ps.setString(3, name);
506    
507                            rs = ps.executeQuery();
508    
509                            while (rs.next()) {
510                                    long folderId = rs.getLong(1);
511    
512                                    return folderId;
513                            }
514                    }
515                    finally {
516                            DataAccess.cleanUp(ps);
517                    }
518    
519                    return addDLFolder(
520                            increment(), groupId, companyId, userId, userName, createDate,
521                            repositoryId, false, parentFolderId, name, hidden);
522            }
523    
524            protected abstract String getPortletId();
525    
526            protected long getRepositoryId(
527                            long groupId, long companyId, long userId, String userName,
528                            Timestamp createDate, long classNameId, String portletId)
529                    throws Exception {
530    
531                    PreparedStatement ps = null;
532                    ResultSet rs = null;
533    
534                    try {
535                            ps = connection.prepareStatement(
536                                    "select repositoryId from Repository where groupId = ? and " +
537                                            "name = ? and portletId = ?");
538    
539                            ps.setLong(1, groupId);
540                            ps.setString(2, portletId);
541                            ps.setString(3, portletId);
542    
543                            rs = ps.executeQuery();
544    
545                            while (rs.next()) {
546                                    long repositoryId = rs.getLong(1);
547    
548                                    return repositoryId;
549                            }
550                    }
551                    finally {
552                            DataAccess.cleanUp(ps);
553                    }
554    
555                    return addRepository(
556                            groupId, companyId, userId, userName, createDate, classNameId,
557                            portletId);
558            }
559    
560            protected long getRoleId(long companyId, String name) throws Exception {
561                    String roleIdsKey = companyId + StringPool.POUND + name;
562    
563                    Long roleId = _roleIds.get(roleIdsKey);
564    
565                    if (roleId != null) {
566                            return roleId;
567                    }
568    
569                    PreparedStatement ps = null;
570                    ResultSet rs = null;
571    
572                    try {
573                            ps = connection.prepareStatement(
574                                    "select roleId from Role_ where companyId = ? and name = ?");
575    
576                            ps.setLong(1, companyId);
577                            ps.setString(2, name);
578    
579                            rs = ps.executeQuery();
580    
581                            if (rs.next()) {
582                                    roleId = rs.getLong("roleId");
583                            }
584    
585                            _roleIds.put(roleIdsKey, roleId);
586    
587                            return roleId;
588                    }
589                    finally {
590                            DataAccess.cleanUp(ps, rs);
591                    }
592            }
593    
594            protected abstract void updateAttachments() throws Exception;
595    
596            protected void updateEntryAttachments(
597                            long companyId, long groupId, long resourcePrimKey,
598                            long containerModelId, long userId, String userName)
599                    throws Exception {
600    
601                    String[] attachments = getAttachments(
602                            companyId, containerModelId, resourcePrimKey);
603    
604                    if (ArrayUtil.isEmpty(attachments)) {
605                            return;
606                    }
607    
608                    Timestamp createDate = new Timestamp(System.currentTimeMillis());
609    
610                    long repositoryId = getRepositoryId(
611                            groupId, companyId, userId, userName, createDate,
612                            PortalUtil.getClassNameId(_LIFERAY_REPOSITORY_CLASS_NAME),
613                            getPortletId());
614    
615                    if (repositoryId < 0) {
616                            return;
617                    }
618    
619                    long containerModelFolderId = getContainerModelFolderId(
620                            groupId, companyId, resourcePrimKey, containerModelId, userId,
621                            userName, createDate);
622    
623                    if (containerModelFolderId < 0) {
624                            return;
625                    }
626    
627                    for (String attachment : attachments) {
628                            String name = String.valueOf(
629                                    increment(DLFileEntry.class.getName()));
630    
631                            String title = FileUtil.getShortFileName(attachment);
632    
633                            String extension = FileUtil.getExtension(title);
634    
635                            String mimeType = MimeTypesUtil.getExtensionContentType(extension);
636    
637                            try {
638                                    long size = DLStoreUtil.getFileSize(
639                                            companyId, CompanyConstants.SYSTEM, attachment);
640    
641                                    long fileEntryId = addDLFileEntry(
642                                            groupId, companyId, userId, getClassName(), resourcePrimKey,
643                                            userName, createDate, repositoryId, containerModelFolderId,
644                                            name, extension, mimeType, title, size);
645    
646                                    if (fileEntryId < 0) {
647                                            continue;
648                                    }
649    
650                                    addDLFileVersion(
651                                            increment(), groupId, companyId, userId, userName,
652                                            createDate, repositoryId, containerModelFolderId,
653                                            fileEntryId, extension, mimeType, title, size);
654    
655                                    byte[] bytes = DLStoreUtil.getFileAsBytes(
656                                            companyId, CompanyConstants.SYSTEM, attachment);
657    
658                                    DLStoreUtil.addFile(
659                                            companyId, containerModelFolderId, name, false, bytes);
660                            }
661                            catch (Exception e) {
662                                    if (_log.isWarnEnabled()) {
663                                            _log.warn("Unable to add attachment " + attachment, e);
664                                    }
665                            }
666    
667                            try {
668                                    DLStoreUtil.deleteFile(
669                                            companyId, CompanyConstants.SYSTEM, attachment);
670                            }
671                            catch (Exception e) {
672                                    if (_log.isWarnEnabled()) {
673                                            _log.warn("Unable to delete attachment " + attachment, e);
674                                    }
675                            }
676                    }
677            }
678    
679            private static final String _LIFERAY_REPOSITORY_CLASS_NAME =
680                    "com.liferay.portal.repository.liferayrepository.LiferayRepository";
681    
682            private static final Log _log = LogFactoryUtil.getLog(
683                    BaseUpgradeAttachments.class);
684    
685            private final Map<String, Map<String, Long>> _bitwiseValues =
686                    new HashMap<>();
687            private final Map<String, Long> _roleIds = new HashMap<>();
688    
689    }