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