1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.upgrade.v5_2_0;
24  
25  import com.liferay.counter.service.CounterLocalServiceUtil;
26  import com.liferay.portal.kernel.dao.jdbc.DataAccess;
27  import com.liferay.portal.kernel.dao.jdbc.SmartResultSet;
28  import com.liferay.portal.kernel.log.Log;
29  import com.liferay.portal.kernel.log.LogFactoryUtil;
30  import com.liferay.portal.kernel.util.ArrayUtil;
31  import com.liferay.portal.kernel.util.StringPool;
32  import com.liferay.portal.kernel.util.Validator;
33  import com.liferay.portal.service.ServiceContext;
34  import com.liferay.portal.upgrade.UpgradeException;
35  import com.liferay.portal.upgrade.UpgradeProcess;
36  import com.liferay.portal.util.PropsValues;
37  import com.liferay.portlet.tags.NoSuchEntryException;
38  import com.liferay.portlet.tags.NoSuchVocabularyException;
39  import com.liferay.portlet.tags.model.TagsVocabulary;
40  import com.liferay.portlet.tags.service.TagsVocabularyLocalServiceUtil;
41  
42  import java.sql.Connection;
43  import java.sql.PreparedStatement;
44  import java.sql.ResultSet;
45  import java.sql.Timestamp;
46  
47  import java.util.HashMap;
48  import java.util.Map;
49  
50  /**
51   * <a href="UpgradeTags.java.html"><b><i>View Source</i></b></a>
52   *
53   * @author Jorge Ferrer
54   * @author Brian Wing Shun Chan
55   *
56   */
57  public class UpgradeTags extends UpgradeProcess {
58  
59      public void upgrade() throws UpgradeException {
60          _log.info("Upgrading");
61  
62          try {
63              updateGroupIds();
64              updateCategories();
65              updateAssets();
66          }
67          catch (Exception e) {
68              throw new UpgradeException(e);
69          }
70      }
71  
72      protected long copyEntry(long groupId, long entryId) throws Exception {
73          Connection con = null;
74          PreparedStatement ps = null;
75          ResultSet rs = null;
76  
77          try {
78              con = DataAccess.getConnection();
79  
80              ps = con.prepareStatement(
81                  "select * from TagsEntry where entryId = ?");
82  
83              ps.setLong(1, entryId);
84  
85              rs = ps.executeQuery();
86  
87              while (rs.next()) {
88                  long companyId = rs.getLong("companyId");
89                  long userId = rs.getLong("userId");
90                  String userName = rs.getString("userName");
91                  Timestamp createDate = rs.getTimestamp("createDate");
92                  Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
93                  String name = rs.getString("name");
94  
95                  long newEntryId = CounterLocalServiceUtil.increment();
96  
97                  ps = con.prepareStatement(
98                      "insert into TagsEntry (entryId, groupId, companyId, " +
99                          "userId, userName, createDate, modifiedDate, name) " +
100                             "values (?, ?, ?, ?, ?, ?, ?, ?)");
101 
102                 ps.setLong(1, newEntryId);
103                 ps.setLong(2, groupId);
104                 ps.setLong(3, companyId);
105                 ps.setLong(4, userId);
106                 ps.setString(5, userName);
107                 ps.setTimestamp(6, createDate);
108                 ps.setTimestamp(7, modifiedDate);
109                 ps.setString(8, name);
110 
111                 ps.executeUpdate();
112 
113                 ps.close();
114 
115                 copyProperties(entryId, newEntryId);
116 
117                 return newEntryId;
118             }
119         }
120         finally {
121             DataAccess.cleanUp(con, ps, rs);
122         }
123 
124         throw new NoSuchEntryException(
125             "No TagsEntry exists with the primary key " + entryId);
126     }
127 
128     public void copyProperties(long entryId, long newEntryId) throws Exception {
129         Connection con = null;
130         PreparedStatement ps = null;
131         ResultSet rs = null;
132 
133         try {
134             con = DataAccess.getConnection();
135 
136             ps = con.prepareStatement(
137                 "select * from TagsProperty where entryId = ?");
138 
139             ps.setLong(1, entryId);
140 
141             rs = ps.executeQuery();
142 
143             while (rs.next()) {
144                 long companyId = rs.getLong("companyId");
145                 long userId = rs.getLong("userId");
146                 String userName = rs.getString("userName");
147                 Timestamp createDate = rs.getTimestamp("createDate");
148                 Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
149                 String key = rs.getString("key_");
150                 String value = rs.getString("value");
151 
152                 long newPropertyId = CounterLocalServiceUtil.increment();
153 
154                 ps = con.prepareStatement(
155                     "insert into TagsProperty (propertyId, companyId, " +
156                         "userId, userName, createDate, modifiedDate, " +
157                             "entryId, key_, value) values (?, ?, ?, ?, ?, ?, " +
158                                 "?, ?, ?)");
159 
160                 ps.setLong(1, newPropertyId);
161                 ps.setLong(2, companyId);
162                 ps.setLong(3, userId);
163                 ps.setString(4, userName);
164                 ps.setTimestamp(5, createDate);
165                 ps.setTimestamp(6, modifiedDate);
166                 ps.setLong(7, newEntryId);
167                 ps.setString(8, key);
168                 ps.setString(9, value);
169 
170                 ps.executeUpdate();
171 
172                 ps.close();
173             }
174         }
175         finally {
176             DataAccess.cleanUp(con, ps, rs);
177         }
178     }
179 
180     protected void deleteEntries() throws Exception {
181         Connection con = null;
182         PreparedStatement ps = null;
183         ResultSet rs = null;
184 
185         try {
186             con = DataAccess.getConnection();
187 
188             ps = con.prepareStatement(
189                 "select entryId from TagsEntry where groupId = 0");
190 
191             rs = ps.executeQuery();
192 
193             while (rs.next()) {
194                 long entryId = rs.getLong("entryId");
195 
196                 ps = con.prepareStatement(
197                     "delete from TagsAssets_TagsEntries where entryId = ?");
198 
199                 ps.setLong(1, entryId);
200 
201                 ps.executeUpdate();
202 
203                 ps.close();
204 
205                 ps = con.prepareStatement(
206                     "delete from TagsProperty where entryId = ?");
207 
208                 ps.setLong(1, entryId);
209 
210                 ps.executeUpdate();
211 
212                 ps.close();
213             }
214 
215             ps = con.prepareStatement(
216                 "delete from TagsEntry where groupId = 0");
217 
218             ps.executeUpdate();
219 
220             ps.close();
221         }
222         finally {
223             DataAccess.cleanUp(con, ps, rs);
224         }
225     }
226 
227     protected long getVocabularyId(
228             long userId, long groupId, String vocabularyName)
229         throws Exception {
230 
231         vocabularyName = vocabularyName.trim();
232 
233         if (Validator.isNull(vocabularyName) ||
234             ArrayUtil.contains(
235                 _DEFAULT_CATEGORY_PROPERTY_VALUES, vocabularyName)) {
236 
237             vocabularyName = PropsValues.TAGS_VOCABULARY_DEFAULT;
238         }
239 
240         String key = groupId + StringPool.UNDERLINE + vocabularyName;
241 
242         TagsVocabulary vocabulary = _vocabulariesMap.get(key);
243 
244         if (vocabulary == null) {
245             try {
246                 vocabulary = TagsVocabularyLocalServiceUtil.getGroupVocabulary(
247                     groupId, vocabularyName);
248             }
249             catch (NoSuchVocabularyException nsve) {
250                 ServiceContext serviceContext = new ServiceContext();
251 
252                 serviceContext.setAddCommunityPermissions(true);
253                 serviceContext.setAddGuestPermissions(true);
254                 serviceContext.setScopeGroupId(groupId);
255 
256                 vocabulary = TagsVocabularyLocalServiceUtil.addVocabulary(
257                     userId, vocabularyName, true, serviceContext);
258             }
259 
260             _vocabulariesMap.put(key, vocabulary);
261         }
262 
263         return vocabulary.getVocabularyId();
264     }
265 
266     protected void updateAssets() throws Exception {
267         Connection con = null;
268         PreparedStatement ps = null;
269         ResultSet rs = null;
270 
271         try {
272             con = DataAccess.getConnection();
273 
274             ps = con.prepareStatement(
275                 "select resourcePrimKey from JournalArticle where approved " +
276                     "= ?");
277 
278             ps.setBoolean(1, false);
279 
280             rs = ps.executeQuery();
281 
282             while (rs.next()) {
283                 long resourcePrimKey = rs.getLong("resourcePrimKey");
284 
285                 ps = con.prepareStatement(
286                     "update TagsAsset set visible = ? where classPK = ?");
287 
288                 ps.setBoolean(1, false);
289                 ps.setLong(2, resourcePrimKey);
290 
291                 ps.executeUpdate();
292 
293                 ps.close();
294             }
295         }
296         finally {
297             DataAccess.cleanUp(con, ps, rs);
298         }
299     }
300 
301     protected void updateCategories() throws Exception {
302         Connection con = null;
303         PreparedStatement ps = null;
304         ResultSet rs = null;
305 
306         try {
307             con = DataAccess.getConnection();
308 
309             ps = con.prepareStatement(
310                 "select TE.entryId, TE.groupId, TE.userId, TP.propertyId, " +
311                     "TP.value from TagsEntry TE, TagsProperty TP where " +
312                         "TE.entryId = TP.entryId and TE.vocabularyId <= 0 " +
313                             "and TP.key_ = 'category'");
314 
315             rs = ps.executeQuery();
316 
317             SmartResultSet srs = new SmartResultSet(rs);
318 
319             while (srs.next()) {
320                 long entryId = srs.getLong("TE.entryId");
321                 long groupId = srs.getLong("TE.groupId");
322                 long userId = srs.getLong("TE.userId");
323                 long propertyId = srs.getLong("TP.propertyId");
324                 String value = srs.getString("TP.value");
325 
326                 long vocabularyId = getVocabularyId(userId, groupId, value);
327 
328                 ps = con.prepareStatement(
329                     "update TagsEntry set vocabularyId = ? where entryId = ?");
330 
331                 ps.setLong(1, vocabularyId);
332                 ps.setLong(2, entryId);
333 
334                 ps.executeUpdate();
335 
336                 ps.close();
337 
338                 ps = con.prepareStatement(
339                     "delete from TagsProperty where propertyId = ?");
340 
341                 ps.setLong(1, propertyId);
342 
343                 ps.executeUpdate();
344 
345                 ps.close();
346             }
347         }
348         finally {
349             DataAccess.cleanUp(con, ps, rs);
350         }
351     }
352 
353     protected void updateGroupIds() throws Exception {
354         Connection con = null;
355         PreparedStatement ps = null;
356         ResultSet rs = null;
357 
358         try {
359             con = DataAccess.getConnection();
360 
361             ps = con.prepareStatement(
362                 "select TA.assetId, TA.groupId, TA_TE.entryId from " +
363                     "TagsAssets_TagsEntries TA_TE inner join TagsAsset TA on " +
364                         "TA.assetId = TA_TE.assetId");
365 
366             rs = ps.executeQuery();
367 
368             SmartResultSet srs = new SmartResultSet(rs);
369 
370             while (srs.next()) {
371                 long assetId = srs.getLong("TA.assetId");
372                 long groupId = srs.getLong("TA.groupId");
373                 long entryId = srs.getLong("TA_TE.entryId");
374 
375                 long newEntryId = copyEntry(groupId, entryId);
376 
377                 ps = con.prepareStatement(
378                     "insert into TagsAssets_TagsEntries (assetId, entryId) " +
379                         "values (?, ?)");
380 
381                 ps.setLong(1, assetId);
382                 ps.setLong(2, newEntryId);
383 
384                 ps.executeUpdate();
385 
386                 ps.close();
387             }
388         }
389         finally {
390             DataAccess.cleanUp(con, ps, rs);
391         }
392 
393         deleteEntries();
394     }
395 
396     private String[] _DEFAULT_CATEGORY_PROPERTY_VALUES = new String[] {
397         "undefined", "no category", "category"
398     };
399 
400     private static Log _log = LogFactoryUtil.getLog(UpgradeTags.class);
401 
402     private Map<String, TagsVocabulary> _vocabulariesMap =
403         new HashMap<String, TagsVocabulary>();
404 
405 }