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          String key = groupId + StringPool.UNDERLINE + entryId;
74  
75          Long newEntryId = _entryIdsMap.get(key);
76  
77          if (newEntryId != null) {
78              return newEntryId.longValue();
79          }
80  
81          Connection con = null;
82          PreparedStatement ps = null;
83          ResultSet rs = null;
84  
85          try {
86              con = DataAccess.getConnection();
87  
88              ps = con.prepareStatement(
89                  "select * from TagsEntry where entryId = ?");
90  
91              ps.setLong(1, entryId);
92  
93              rs = ps.executeQuery();
94  
95              while (rs.next()) {
96                  long companyId = rs.getLong("companyId");
97                  long userId = rs.getLong("userId");
98                  String userName = rs.getString("userName");
99                  Timestamp createDate = rs.getTimestamp("createDate");
100                 Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
101                 String name = rs.getString("name");
102 
103                 newEntryId = CounterLocalServiceUtil.increment();
104 
105                 ps = con.prepareStatement(
106                     "insert into TagsEntry (entryId, groupId, companyId, " +
107                         "userId, userName, createDate, modifiedDate, name) " +
108                             "values (?, ?, ?, ?, ?, ?, ?, ?)");
109 
110                 ps.setLong(1, newEntryId);
111                 ps.setLong(2, groupId);
112                 ps.setLong(3, companyId);
113                 ps.setLong(4, userId);
114                 ps.setString(5, userName);
115                 ps.setTimestamp(6, createDate);
116                 ps.setTimestamp(7, modifiedDate);
117                 ps.setString(8, name);
118 
119                 ps.executeUpdate();
120 
121                 ps.close();
122 
123                 copyProperties(entryId, newEntryId);
124 
125                 _entryIdsMap.put(key, newEntryId);
126 
127                 return newEntryId;
128             }
129         }
130         finally {
131             DataAccess.cleanUp(con, ps, rs);
132         }
133 
134         throw new NoSuchEntryException(
135             "No TagsEntry exists with the primary key " + entryId);
136     }
137 
138     public void copyProperties(long entryId, long newEntryId) throws Exception {
139         Connection con = null;
140         PreparedStatement ps = null;
141         ResultSet rs = null;
142 
143         try {
144             con = DataAccess.getConnection();
145 
146             ps = con.prepareStatement(
147                 "select * from TagsProperty where entryId = ?");
148 
149             ps.setLong(1, entryId);
150 
151             rs = ps.executeQuery();
152 
153             while (rs.next()) {
154                 long companyId = rs.getLong("companyId");
155                 long userId = rs.getLong("userId");
156                 String userName = rs.getString("userName");
157                 Timestamp createDate = rs.getTimestamp("createDate");
158                 Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
159                 String key = rs.getString("key_");
160                 String value = rs.getString("value");
161 
162                 long newPropertyId = CounterLocalServiceUtil.increment();
163 
164                 ps = con.prepareStatement(
165                     "insert into TagsProperty (propertyId, companyId, " +
166                         "userId, userName, createDate, modifiedDate, " +
167                             "entryId, key_, value) values (?, ?, ?, ?, ?, ?, " +
168                                 "?, ?, ?)");
169 
170                 ps.setLong(1, newPropertyId);
171                 ps.setLong(2, companyId);
172                 ps.setLong(3, userId);
173                 ps.setString(4, userName);
174                 ps.setTimestamp(5, createDate);
175                 ps.setTimestamp(6, modifiedDate);
176                 ps.setLong(7, newEntryId);
177                 ps.setString(8, key);
178                 ps.setString(9, value);
179 
180                 ps.executeUpdate();
181 
182                 ps.close();
183             }
184         }
185         finally {
186             DataAccess.cleanUp(con, ps, rs);
187         }
188     }
189 
190     protected void deleteEntries() throws Exception {
191         Connection con = null;
192         PreparedStatement ps = null;
193         ResultSet rs = null;
194 
195         try {
196             con = DataAccess.getConnection();
197 
198             ps = con.prepareStatement(
199                 "select entryId from TagsEntry where groupId = 0");
200 
201             rs = ps.executeQuery();
202 
203             while (rs.next()) {
204                 long entryId = rs.getLong("entryId");
205 
206                 ps = con.prepareStatement(
207                     "delete from TagsAssets_TagsEntries where entryId = ?");
208 
209                 ps.setLong(1, entryId);
210 
211                 ps.executeUpdate();
212 
213                 ps.close();
214 
215                 ps = con.prepareStatement(
216                     "delete from TagsProperty where entryId = ?");
217 
218                 ps.setLong(1, entryId);
219 
220                 ps.executeUpdate();
221 
222                 ps.close();
223             }
224 
225             ps = con.prepareStatement(
226                 "delete from TagsEntry where groupId = 0");
227 
228             ps.executeUpdate();
229 
230             ps.close();
231         }
232         finally {
233             DataAccess.cleanUp(con, ps, rs);
234         }
235     }
236 
237     protected long getVocabularyId(
238             long userId, long groupId, String vocabularyName)
239         throws Exception {
240 
241         vocabularyName = vocabularyName.trim();
242 
243         if (Validator.isNull(vocabularyName) ||
244             ArrayUtil.contains(
245                 _DEFAULT_CATEGORY_PROPERTY_VALUES, vocabularyName)) {
246 
247             vocabularyName = PropsValues.TAGS_VOCABULARY_DEFAULT;
248         }
249 
250         String key = groupId + StringPool.UNDERLINE + vocabularyName;
251 
252         TagsVocabulary vocabulary = _vocabulariesMap.get(key);
253 
254         if (vocabulary == null) {
255             try {
256                 vocabulary = TagsVocabularyLocalServiceUtil.getGroupVocabulary(
257                     groupId, vocabularyName);
258             }
259             catch (NoSuchVocabularyException nsve) {
260                 ServiceContext serviceContext = new ServiceContext();
261 
262                 serviceContext.setAddCommunityPermissions(true);
263                 serviceContext.setAddGuestPermissions(true);
264                 serviceContext.setScopeGroupId(groupId);
265 
266                 vocabulary = TagsVocabularyLocalServiceUtil.addVocabulary(
267                     userId, vocabularyName, true, serviceContext);
268             }
269 
270             _vocabulariesMap.put(key, vocabulary);
271         }
272 
273         return vocabulary.getVocabularyId();
274     }
275 
276     protected void updateAssets() throws Exception {
277         Connection con = null;
278         PreparedStatement ps = null;
279         ResultSet rs = null;
280 
281         try {
282             con = DataAccess.getConnection();
283 
284             ps = con.prepareStatement(
285                 "select resourcePrimKey from JournalArticle where approved " +
286                     "= ?");
287 
288             ps.setBoolean(1, false);
289 
290             rs = ps.executeQuery();
291 
292             while (rs.next()) {
293                 long resourcePrimKey = rs.getLong("resourcePrimKey");
294 
295                 ps = con.prepareStatement(
296                     "update TagsAsset set visible = ? where classPK = ?");
297 
298                 ps.setBoolean(1, false);
299                 ps.setLong(2, resourcePrimKey);
300 
301                 ps.executeUpdate();
302 
303                 ps.close();
304             }
305         }
306         finally {
307             DataAccess.cleanUp(con, ps, rs);
308         }
309     }
310 
311     protected void updateCategories() throws Exception {
312         Connection con = null;
313         PreparedStatement ps = null;
314         ResultSet rs = null;
315 
316         try {
317             con = DataAccess.getConnection();
318 
319             ps = con.prepareStatement(
320                 "select TE.entryId, TE.groupId, TE.userId, TP.propertyId, " +
321                     "TP.value from TagsEntry TE, TagsProperty TP where " +
322                         "TE.entryId = TP.entryId and TE.vocabularyId <= 0 " +
323                             "and TP.key_ = 'category'");
324 
325             rs = ps.executeQuery();
326 
327             SmartResultSet srs = new SmartResultSet(rs);
328 
329             while (srs.next()) {
330                 long entryId = srs.getLong("TE.entryId");
331                 long groupId = srs.getLong("TE.groupId");
332                 long userId = srs.getLong("TE.userId");
333                 long propertyId = srs.getLong("TP.propertyId");
334                 String value = srs.getString("TP.value");
335 
336                 long vocabularyId = getVocabularyId(userId, groupId, value);
337 
338                 ps = con.prepareStatement(
339                     "update TagsEntry set vocabularyId = ? where entryId = ?");
340 
341                 ps.setLong(1, vocabularyId);
342                 ps.setLong(2, entryId);
343 
344                 ps.executeUpdate();
345 
346                 ps.close();
347 
348                 ps = con.prepareStatement(
349                     "delete from TagsProperty where propertyId = ?");
350 
351                 ps.setLong(1, propertyId);
352 
353                 ps.executeUpdate();
354 
355                 ps.close();
356             }
357         }
358         finally {
359             DataAccess.cleanUp(con, ps, rs);
360         }
361     }
362 
363     protected void updateGroupIds() throws Exception {
364         Connection con = null;
365         PreparedStatement ps = null;
366         ResultSet rs = null;
367 
368         try {
369             con = DataAccess.getConnection();
370 
371             ps = con.prepareStatement(
372                 "select TA.assetId, TA.groupId, TA_TE.entryId from " +
373                     "TagsAssets_TagsEntries TA_TE inner join TagsAsset TA on " +
374                         "TA.assetId = TA_TE.assetId");
375 
376             rs = ps.executeQuery();
377 
378             SmartResultSet srs = new SmartResultSet(rs);
379 
380             while (srs.next()) {
381                 long assetId = srs.getLong("TA.assetId");
382                 long groupId = srs.getLong("TA.groupId");
383                 long entryId = srs.getLong("TA_TE.entryId");
384 
385                 long newEntryId = copyEntry(groupId, entryId);
386 
387                 ps = con.prepareStatement(
388                     "insert into TagsAssets_TagsEntries (assetId, entryId) " +
389                         "values (?, ?)");
390 
391                 ps.setLong(1, assetId);
392                 ps.setLong(2, newEntryId);
393 
394                 ps.executeUpdate();
395 
396                 ps.close();
397             }
398         }
399         finally {
400             DataAccess.cleanUp(con, ps, rs);
401         }
402 
403         deleteEntries();
404     }
405 
406     private String[] _DEFAULT_CATEGORY_PROPERTY_VALUES = new String[] {
407         "undefined", "no category", "category"
408     };
409 
410     private static Log _log = LogFactoryUtil.getLog(UpgradeTags.class);
411 
412     private Map<String, Long> _entryIdsMap = new HashMap<String, Long>();
413     private Map<String, TagsVocabulary> _vocabulariesMap =
414         new HashMap<String, TagsVocabulary>();
415 
416 }