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