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.v7_0_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.repository.model.Folder;
021    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
022    import com.liferay.portal.kernel.util.ArrayUtil;
023    import com.liferay.portal.kernel.util.StringBundler;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.workflow.WorkflowInstance;
026    import com.liferay.portal.model.Layout;
027    import com.liferay.portal.model.PortletPreferences;
028    import com.liferay.portal.util.PortalUtil;
029    import com.liferay.portlet.blogs.model.BlogsEntry;
030    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
031    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
032    import com.liferay.portlet.documentlibrary.model.DLFolder;
033    import com.liferay.portlet.messageboards.model.MBCategory;
034    import com.liferay.portlet.messageboards.model.MBThread;
035    
036    import java.sql.PreparedStatement;
037    import java.sql.ResultSet;
038    
039    import java.util.HashMap;
040    import java.util.Map;
041    
042    /**
043     * @author Eduardo Garcia
044     * @author Roberto D??az
045     * @author Iv??n Zaera
046     */
047    public class UpgradeSubscription extends UpgradeProcess {
048    
049            protected void addClassName(long classNameId, String className)
050                    throws Exception {
051    
052                    PreparedStatement ps = null;
053    
054                    try {
055                            ps = connection.prepareStatement(
056                                    "insert into ClassName_ (mvccVersion, classNameId, value) " +
057                                            "values (?, ?, ?)");
058    
059                            ps.setLong(1, 0);
060                            ps.setLong(2, classNameId);
061                            ps.setString(3, className);
062    
063                            ps.executeUpdate();
064                    }
065                    finally {
066                            DataAccess.cleanUp(ps);
067                    }
068            }
069    
070            protected void deleteOrphanedSubscriptions() throws Exception {
071                    long classNameId = PortalUtil.getClassNameId(
072                            PortletPreferences.class.getName());
073    
074                    runSQL(
075                            "delete from Subscription where classNameId = " + classNameId +
076                                    " and classPK not in (select portletPreferencesId from " +
077                                            " PortletPreferences)");
078            }
079    
080            @Override
081            protected void doUpgrade() throws Exception {
082                    deleteOrphanedSubscriptions();
083    
084                    updateSubscriptionClassNames(
085                            Folder.class.getName(), DLFolder.class.getName());
086                    updateSubscriptionClassNames(
087                            "com.liferay.portlet.journal.model.JournalArticle",
088                            "com.liferay.portlet.journal.model.JournalFolder");
089    
090                    updateSubscriptionGroupIds();
091            }
092    
093            protected long getClassNameId(String className) throws Exception {
094                    long classNameId = PortalUtil.getClassNameId(className);
095    
096                    if (classNameId != 0) {
097                            return classNameId;
098                    }
099    
100                    classNameId = increment();
101    
102                    addClassName(classNameId, className);
103    
104                    return classNameId;
105            }
106    
107            protected long getGroupId(long classNameId, long classPK) throws Exception {
108                    PreparedStatement ps = null;
109                    ResultSet rs = null;
110    
111                    try {
112                            String className = PortalUtil.getClassName(classNameId);
113    
114                            String[] groupIdSQLParts = StringUtil.split(
115                                    _getGroupIdSQLPartsMap.get(className));
116    
117                            if (ArrayUtil.isEmpty(groupIdSQLParts)) {
118                                    if (_log.isWarnEnabled()) {
119                                            _log.warn(
120                                                    "Unable to determine the group ID for the class name " +
121                                                            className);
122                                    }
123    
124                                    return 0;
125                            }
126    
127                            String sql =
128                                    "select " + groupIdSQLParts[1] + " from " + groupIdSQLParts[0] +
129                                            " where " + groupIdSQLParts[2] + " = ?";
130    
131                            ps = connection.prepareStatement(sql);
132    
133                            ps.setLong(1, classPK);
134    
135                            rs = ps.executeQuery();
136    
137                            if (rs.next()) {
138                                    return rs.getLong("groupId");
139                            }
140                    }
141                    finally {
142                            DataAccess.cleanUp(ps, rs);
143                    }
144    
145                    return 0;
146            }
147    
148            protected boolean hasGroup(long groupId) throws Exception {
149                    PreparedStatement ps = null;
150                    ResultSet rs = null;
151    
152                    try {
153                            ps = connection.prepareStatement(
154                                    "select count(*) from Group_ where groupId = ?");
155    
156                            ps.setLong(1, groupId);
157    
158                            rs = ps.executeQuery();
159    
160                            if (rs.next()) {
161                                    int count = rs.getInt(1);
162    
163                                    if (count > 0) {
164                                            return true;
165                                    }
166                            }
167    
168                            return false;
169                    }
170                    finally {
171                            DataAccess.cleanUp(ps, rs);
172                    }
173            }
174    
175            protected void updateSubscriptionClassNames(
176                            String oldClassName, String newClassName)
177                    throws Exception {
178    
179                    StringBundler sb = new StringBundler(4);
180    
181                    sb.append("update Subscription set classNameId = ");
182                    sb.append(getClassNameId(newClassName));
183                    sb.append(" where classNameId = ");
184                    sb.append(PortalUtil.getClassNameId(oldClassName));
185    
186                    runSQL(sb.toString());
187            }
188    
189            protected void updateSubscriptionGroupId(
190                            long subscriptionId, long classNameId, long classPK)
191                    throws Exception {
192    
193                    long groupId = getGroupId(classNameId, classPK);
194    
195                    if ((groupId == 0) && hasGroup(classPK)) {
196                            groupId = classPK;
197                    }
198    
199                    if (groupId != 0) {
200                            runSQL(
201                                    "update Subscription set groupId = " + groupId + " where " +
202                                            "subscriptionId = " + subscriptionId);
203                    }
204            }
205    
206            protected void updateSubscriptionGroupIds() throws Exception {
207                    PreparedStatement ps = null;
208                    ResultSet rs = null;
209    
210                    try {
211                            ps = connection.prepareStatement(
212                                    "select subscriptionId, classNameId, classPK from " +
213                                            "Subscription");
214    
215                            rs = ps.executeQuery();
216    
217                            while (rs.next()) {
218                                    long subscriptionId = rs.getLong("subscriptionId");
219                                    long classNameId = rs.getLong("classNameId");
220                                    long classPK = rs.getLong("classPK");
221    
222                                    updateSubscriptionGroupId(subscriptionId, classNameId, classPK);
223                            }
224                    }
225                    finally {
226                            DataAccess.cleanUp(ps, rs);
227                    }
228            }
229    
230            private static final Log _log = LogFactoryUtil.getLog(
231                    UpgradeSubscription.class);
232    
233            private static final Map<String, String> _getGroupIdSQLPartsMap =
234                    new HashMap<>();
235    
236            static {
237                    _getGroupIdSQLPartsMap.put(
238                            BlogsEntry.class.getName(), "BlogsEntry,groupId,entryId");
239                    _getGroupIdSQLPartsMap.put(
240                            DLFileEntry.class.getName(), "DLFileEntry,groupId,fileEntryId");
241                    _getGroupIdSQLPartsMap.put(
242                            DLFileEntryType.class.getName(),
243                            "DLFileEntryType,groupId,fileEntryTypeId");
244                    _getGroupIdSQLPartsMap.put(
245                            DLFolder.class.getName(), "DLFolder,groupId,folderId");
246                    _getGroupIdSQLPartsMap.put(
247                            Layout.class.getName(), "Layout,groupId,plid");
248                    _getGroupIdSQLPartsMap.put(
249                            MBCategory.class.getName(), "MBCategory,groupId,categoryId");
250                    _getGroupIdSQLPartsMap.put(
251                            MBThread.class.getName(), "MBThread,groupId,threadId");
252                    _getGroupIdSQLPartsMap.put(
253                            WorkflowInstance.class.getName(),
254                            "WorkflowInstance,groupId,workflowInstanceId");
255                    _getGroupIdSQLPartsMap.put(
256                            "com.liferay.bookmarks.model.BookmarksEntry",
257                            "BookmarksEntry,groupId,entryId");
258                    _getGroupIdSQLPartsMap.put(
259                            "com.liferay.bookmarks.model.BookmarksFolder",
260                            "BookmarksFolder,groupId,folderId");
261                    _getGroupIdSQLPartsMap.put(
262                            "com.liferay.portlet.dynamicdatamapping.DDMStructure",
263                            "DDMStructure,groupId,structureId");
264                    _getGroupIdSQLPartsMap.put(
265                            "com.liferay.portlet.journal.model.JournalFolder",
266                            "JournalFolder,groupId,folderId");
267                    _getGroupIdSQLPartsMap.put(
268                            "com.liferay.portlet.wiki.model.WikiNode",
269                            "WikiNode,groupId,nodeId");
270                    _getGroupIdSQLPartsMap.put(
271                            "com.liferay.portlet.wiki.model.WikiPage",
272                            "WikiPage,groupId,resourcePrimKey");
273            }
274    
275    }