1   /**
2    * Copyright (c) 2000-2008 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.lar;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.util.ObjectValuePair;
28  import com.liferay.portal.kernel.util.StringPool;
29  import com.liferay.portal.kernel.util.Validator;
30  import com.liferay.portal.kernel.zip.ZipReader;
31  import com.liferay.portal.kernel.zip.ZipWriter;
32  import com.liferay.portlet.blogs.model.impl.BlogsEntryImpl;
33  import com.liferay.portlet.bookmarks.model.impl.BookmarksEntryImpl;
34  import com.liferay.portlet.bookmarks.model.impl.BookmarksFolderImpl;
35  import com.liferay.portlet.calendar.model.impl.CalEventImpl;
36  import com.liferay.portlet.documentlibrary.model.impl.DLFileEntryImpl;
37  import com.liferay.portlet.documentlibrary.model.impl.DLFileRankImpl;
38  import com.liferay.portlet.documentlibrary.model.impl.DLFileShortcutImpl;
39  import com.liferay.portlet.documentlibrary.model.impl.DLFolderImpl;
40  import com.liferay.portlet.imagegallery.model.impl.IGFolderImpl;
41  import com.liferay.portlet.imagegallery.model.impl.IGImageImpl;
42  import com.liferay.portlet.journal.model.impl.JournalArticleImpl;
43  import com.liferay.portlet.journal.model.impl.JournalFeedImpl;
44  import com.liferay.portlet.journal.model.impl.JournalStructureImpl;
45  import com.liferay.portlet.journal.model.impl.JournalTemplateImpl;
46  import com.liferay.portlet.messageboards.model.MBMessage;
47  import com.liferay.portlet.messageboards.model.impl.MBBanImpl;
48  import com.liferay.portlet.messageboards.model.impl.MBCategoryImpl;
49  import com.liferay.portlet.messageboards.model.impl.MBMessageFlagImpl;
50  import com.liferay.portlet.messageboards.model.impl.MBMessageImpl;
51  import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
52  import com.liferay.portlet.polls.model.impl.PollsChoiceImpl;
53  import com.liferay.portlet.polls.model.impl.PollsQuestionImpl;
54  import com.liferay.portlet.polls.model.impl.PollsVoteImpl;
55  import com.liferay.portlet.ratings.model.RatingsEntry;
56  import com.liferay.portlet.ratings.model.impl.RatingsEntryImpl;
57  import com.liferay.portlet.ratings.service.RatingsEntryLocalServiceUtil;
58  import com.liferay.portlet.tags.NoSuchAssetException;
59  import com.liferay.portlet.tags.model.TagsAsset;
60  import com.liferay.portlet.tags.model.TagsEntry;
61  import com.liferay.portlet.tags.service.TagsAssetLocalServiceUtil;
62  import com.liferay.portlet.wiki.model.impl.WikiNodeImpl;
63  import com.liferay.portlet.wiki.model.impl.WikiPageImpl;
64  import com.liferay.util.MapUtil;
65  
66  import com.thoughtworks.xstream.XStream;
67  
68  import java.io.IOException;
69  import java.io.InputStream;
70  
71  import java.util.Date;
72  import java.util.HashMap;
73  import java.util.HashSet;
74  import java.util.Iterator;
75  import java.util.List;
76  import java.util.Map;
77  import java.util.Set;
78  
79  /**
80   * <a href="PortletDataContextImpl.java.html"><b><i>View Source</i></b></a>
81   *
82   * <p>
83   * Holds context information that is used during exporting and importing portlet
84   * data.
85   * </p>
86   *
87   * @author Brian Wing Shun Chan
88   * @author Raymond Augé
89   * @author Bruno Farache
90   * @author Alex Chow
91   *
92   */
93  public class PortletDataContextImpl implements PortletDataContext {
94  
95      public PortletDataContextImpl(
96          long companyId, long groupId, Map<String, String[]> parameterMap,
97          Set<String> primaryKeys, UserIdStrategy userIdStrategy,
98          ZipReader zipReader) {
99  
100         _companyId = companyId;
101         _groupId = groupId;
102         _parameterMap = parameterMap;
103         _primaryKeys = primaryKeys;
104         _dataStrategy =  MapUtil.getString(
105             parameterMap, PortletDataHandlerKeys.DATA_STRATEGY,
106             PortletDataHandlerKeys.DATA_STRATEGY_MIRROR);
107         _userIdStrategy = userIdStrategy;
108         _zipReader = zipReader;
109         _zipWriter = null;
110 
111         initXStream();
112     }
113 
114     public PortletDataContextImpl(
115             long companyId, long groupId, Map<String, String[]> parameterMap,
116             Set<String> primaryKeys, Date startDate, Date endDate,
117             ZipWriter zipWriter)
118         throws PortletDataException {
119 
120         validateDateRange(startDate, endDate);
121 
122         _companyId = companyId;
123         _groupId = groupId;
124         _parameterMap = parameterMap;
125         _primaryKeys = primaryKeys;
126         _dataStrategy =  null;
127         _userIdStrategy = null;
128         _startDate = startDate;
129         _endDate = endDate;
130         _zipReader = null;
131         _zipWriter = zipWriter;
132 
133         initXStream();
134     }
135 
136     public void addComments(Class<?> classObj, long classPK)
137         throws SystemException {
138 
139         List<MBMessage> messages = MBMessageLocalServiceUtil.getMessages(
140             classObj.getName(), classPK);
141 
142         if (messages.size() == 0) {
143             return;
144         }
145 
146         Iterator<MBMessage> itr = messages.iterator();
147 
148         while (itr.hasNext()) {
149             MBMessage message = itr.next();
150 
151             message.setUserUuid(message.getUserUuid());
152         }
153 
154         _commentsMap.put(getPrimaryKeyString(classObj, classPK), messages);
155     }
156 
157     public void addComments(
158         String className, long classPK, List<MBMessage> messages) {
159 
160         _commentsMap.put(getPrimaryKeyString(className, classPK), messages);
161     }
162 
163     public boolean addPrimaryKey(Class<?> classObj, String primaryKey) {
164         boolean value = hasPrimaryKey(classObj, primaryKey);
165 
166         if (!value) {
167             _primaryKeys.add(getPrimaryKeyString(classObj, primaryKey));
168         }
169 
170         return value;
171     }
172 
173     public void addRatingsEntries(Class<?> classObj, long classPK)
174         throws SystemException {
175 
176         List<RatingsEntry> entries = RatingsEntryLocalServiceUtil.getEntries(
177             classObj.getName(), classPK);
178 
179         if (entries.size() == 0) {
180             return;
181         }
182 
183         Iterator<RatingsEntry> itr = entries.iterator();
184 
185         while (itr.hasNext()) {
186             RatingsEntry entry = itr.next();
187 
188             entry.setUserUuid(entry.getUserUuid());
189         }
190 
191         _ratingsEntriesMap.put(
192             getPrimaryKeyString(classObj, classPK), entries);
193     }
194 
195     public void addRatingsEntries(
196         String className, long classPK, List<RatingsEntry> entries) {
197 
198         _ratingsEntriesMap.put(
199             getPrimaryKeyString(className, classPK), entries);
200     }
201 
202     public void addTagsEntries(Class<?> classObj, long classPK)
203         throws PortalException, SystemException {
204 
205         TagsAsset tagsAsset = null;
206 
207         try {
208             tagsAsset = TagsAssetLocalServiceUtil.getAsset(
209                 classObj.getName(), classPK);
210         }
211         catch (NoSuchAssetException nsae) {
212 
213             // LEP-4979
214 
215             return;
216         }
217 
218         List<TagsEntry> tagsEntriesList = tagsAsset.getEntries();
219 
220         if (tagsEntriesList.size() == 0) {
221             return;
222         }
223 
224         String[] tagsEntries = new String[tagsEntriesList.size()];
225 
226         Iterator<TagsEntry> itr = tagsEntriesList.iterator();
227 
228         for (int i = 0; itr.hasNext(); i++) {
229             TagsEntry tagsEntry = itr.next();
230 
231             tagsEntries[i] = tagsEntry.getName();
232         }
233 
234         _tagsEntriesMap.put(
235             getPrimaryKeyString(classObj, classPK), tagsEntries);
236     }
237 
238     public void addTagsEntries(
239         String className, long classPK, String[] values) {
240 
241         _tagsEntriesMap.put(getPrimaryKeyString(className, classPK), values);
242     }
243 
244     public void addZipEntry(String path, byte[] bytes) throws SystemException {
245         try {
246             getZipWriter().addEntry(path, bytes);
247         }
248         catch (IOException ioe) {
249             throw new SystemException(ioe);
250         }
251     }
252 
253     public void addZipEntry(String path, InputStream is)
254         throws SystemException {
255 
256         try {
257             getZipWriter().addEntry(path, is);
258         }
259         catch (IOException ioe) {
260             throw new SystemException(ioe);
261         }
262     }
263 
264     public void addZipEntry(String path, Object object) throws SystemException {
265         addZipEntry(path, toXML(object));
266     }
267 
268     public void addZipEntry(String path, String s) throws SystemException {
269         try {
270             getZipWriter().addEntry(path, s);
271         }
272         catch (IOException ioe) {
273             throw new SystemException(ioe);
274         }
275     }
276 
277     public void addZipEntry(String path, StringBuilder sb)
278         throws SystemException {
279 
280         try {
281             getZipWriter().addEntry(path, sb);
282         }
283         catch (IOException ioe) {
284             throw new SystemException(ioe);
285         }
286     }
287 
288     public Object fromXML(byte[] bytes) {
289         return _xStream.fromXML(new String(bytes));
290     }
291 
292     public Object fromXML(String xml) {
293         return _xStream.fromXML(xml);
294     }
295 
296     public boolean getBooleanParameter(String namespace, String name) {
297         boolean defaultValue = MapUtil.getBoolean(
298             getParameterMap(),
299             PortletDataHandlerKeys.PORTLET_DATA_CONTROL_DEFAULT, true);
300 
301         return MapUtil.getBoolean(
302             getParameterMap(),
303             PortletDataHandlerControl.getNamespacedControlName(namespace, name),
304             defaultValue);
305     }
306 
307     public Map<String, List<MBMessage>> getComments() {
308         return _commentsMap;
309     }
310 
311     public long getCompanyId() {
312         return _companyId;
313     }
314 
315     public String getDataStrategy() {
316         return _dataStrategy;
317     }
318 
319     public Date getEndDate() {
320         return _endDate;
321     }
322 
323     public long getGroupId() {
324         return _groupId;
325     }
326 
327     public long getImportGroupId() {
328         return _importGroupId;
329     }
330 
331     public String getImportLayoutPath(long layoutId) {
332         return getImportRootPath() + ROOT_PATH_LAYOUTS + layoutId;
333     }
334 
335     public String getImportPortletPath(String portletId) {
336         return getImportRootPath() + ROOT_PATH_PORTLETS + portletId;
337     }
338 
339     public String getImportRootPath() {
340         return ROOT_PATH_GROUPS + getImportGroupId();
341     }
342 
343     public String getLayoutPath(long layoutId) {
344         return getRootPath() + ROOT_PATH_LAYOUTS + layoutId;
345     }
346 
347     public Map<?, ?> getNewPrimaryKeysMap(Class<?> classObj) {
348         Map<?, ?> map = _newPrimaryKeysMaps.get(classObj.getName());
349 
350         if (map == null) {
351             map = new HashMap<Object, Object>();
352 
353             _newPrimaryKeysMaps.put(classObj.getName(), map);
354         }
355 
356         return map;
357     }
358 
359     public long getOldPlid() {
360         return _oldPlid;
361     }
362 
363     public Map<String, String[]> getParameterMap() {
364         return _parameterMap;
365     }
366 
367     public long getPlid() {
368         return _plid;
369     }
370 
371     public String getPortletPath(String portletId) {
372         return getRootPath() + ROOT_PATH_PORTLETS + portletId;
373     }
374 
375     public Set<String> getPrimaryKeys() {
376         return _primaryKeys;
377     }
378 
379     public Map<String, List<RatingsEntry>> getRatingsEntries() {
380         return _ratingsEntriesMap;
381     }
382 
383     public String getRootPath() {
384         return ROOT_PATH_GROUPS + getGroupId();
385     }
386 
387     public Date getStartDate() {
388         return _startDate;
389     }
390 
391     public Map<String, String[]> getTagsEntries() {
392         return _tagsEntriesMap;
393     }
394 
395     public String[] getTagsEntries(Class<?> classObj, long classPK) {
396         return _tagsEntriesMap.get(getPrimaryKeyString(classObj, classPK));
397     }
398 
399     public String[] getTagsEntries(String className, long classPK) {
400         return _tagsEntriesMap.get(getPrimaryKeyString(className, classPK));
401     }
402 
403     public long getUserId(String userUuid) throws SystemException {
404         return _userIdStrategy.getUserId(userUuid);
405     }
406 
407     public UserIdStrategy getUserIdStrategy() {
408         return _userIdStrategy;
409     }
410 
411     public Map<String, byte[]> getZipEntries() {
412         return getZipReader().getEntries();
413     }
414 
415     public byte[] getZipEntryAsByteArray(String path) {
416         return getZipReader().getEntryAsByteArray(path);
417     }
418 
419     public Object getZipEntryAsObject(String path) {
420         return fromXML(getZipEntryAsString(path));
421     }
422 
423     public String getZipEntryAsString(String path) {
424         return getZipReader().getEntryAsString(path);
425     }
426 
427     public Map<String, List<ObjectValuePair<String, byte[]>>>
428         getZipFolderEntries() {
429 
430         return getZipReader().getFolderEntries();
431     }
432 
433     public List<ObjectValuePair<String, byte[]>> getZipFolderEntries(
434         String path) {
435 
436         if (Validator.isNull(path)) {
437             return null;
438         }
439 
440         List<ObjectValuePair<String, byte[]>> folderEntries =
441             getZipReader().getFolderEntries(path);
442 
443         if ((folderEntries == null) && path.startsWith(StringPool.SLASH)) {
444             folderEntries = getZipReader().getFolderEntries(path.substring(1));
445         }
446 
447         return folderEntries;
448     }
449 
450     public ZipReader getZipReader() {
451         return _zipReader;
452     }
453 
454     public ZipWriter getZipWriter() {
455         return _zipWriter;
456     }
457 
458     public boolean hasDateRange() {
459         if (_startDate != null) {
460             return true;
461         }
462         else {
463             return false;
464         }
465     }
466 
467     public boolean hasNotUniquePerLayout(String portletId) {
468         return _notUniquePerLayout.contains(portletId);
469     }
470 
471     public boolean hasPrimaryKey(Class<?> classObj, String primaryKey) {
472         return _primaryKeys.contains(getPrimaryKeyString(classObj, primaryKey));
473     }
474 
475     public void importComments(
476             Class<?> classObj, long classPK, long newClassPK, long groupId)
477         throws PortalException, SystemException {
478 
479         Map<Long, Long> messagePKs = new HashMap<Long, Long>();
480         Map<Long, Long> threadPKs = new HashMap<Long, Long>();
481 
482         List<MBMessage> messages = _commentsMap.get(
483             getPrimaryKeyString(classObj, classPK));
484 
485         if (messages == null) {
486             return;
487         }
488 
489         for (MBMessage message : messages) {
490             long userId = getUserId(message.getUserUuid());
491             long parentMessageId = MapUtil.getLong(
492                 messagePKs, message.getParentMessageId(),
493                 message.getParentMessageId());
494             long threadId = MapUtil.getLong(
495                 threadPKs, message.getThreadId(), message.getThreadId());
496 
497             MBMessage newMessage =
498                 MBMessageLocalServiceUtil.addDiscussionMessage(
499                     userId, message.getUserName(), groupId, classObj.getName(),
500                     ((Long)newClassPK).longValue(), threadId,
501                     parentMessageId, message.getSubject(), message.getBody());
502 
503             messagePKs.put(message.getMessageId(), newMessage.getMessageId());
504             threadPKs.put(message.getThreadId(), newMessage.getThreadId());
505         }
506     }
507 
508     public void importRatingsEntries(
509             Class<?> classObj, long classPK, long newClassPK)
510         throws PortalException, SystemException {
511 
512         List<RatingsEntry> entries = _ratingsEntriesMap.get(
513             getPrimaryKeyString(classObj, classPK));
514 
515         if (entries == null) {
516             return;
517         }
518 
519         for (RatingsEntry entry : entries) {
520             long userId = getUserId(entry.getUserUuid());
521 
522             RatingsEntryLocalServiceUtil.updateEntry(
523                 userId, classObj.getName(), ((Long)newClassPK).longValue(),
524                 entry.getScore());
525         }
526     }
527 
528     public boolean isPathNotProcessed(String path) {
529         return !addPrimaryKey(String.class, path);
530     }
531 
532     public boolean isWithinDateRange(Date modifiedDate) {
533         if (!hasDateRange()) {
534             return true;
535         }
536         else if ((_startDate.compareTo(modifiedDate) <= 0) &&
537                  (_endDate.after(modifiedDate))) {
538 
539             return true;
540         }
541         else {
542             return false;
543         }
544     }
545 
546     public void putNotUniquePerLayout(String portletId) {
547         _notUniquePerLayout.add(portletId);
548     }
549 
550     public void setImportGroupId(long importGroupId) {
551         _importGroupId = importGroupId;
552     }
553 
554     public void setOldPlid(long oldPlid) {
555         _oldPlid = oldPlid;
556     }
557 
558     public void setPlid(long plid) {
559         _plid = plid;
560     }
561 
562     public String toXML(Object object) {
563         return _xStream.toXML(object);
564     }
565 
566     protected String getPrimaryKeyString(Class<?> classObj, long classPK) {
567         return getPrimaryKeyString(classObj.getName(), String.valueOf(classPK));
568     }
569 
570     protected String getPrimaryKeyString(String className, long classPK) {
571         return getPrimaryKeyString(className, String.valueOf(classPK));
572     }
573 
574     protected String getPrimaryKeyString(Class<?> classObj, String primaryKey) {
575         return getPrimaryKeyString(classObj.getName(), primaryKey);
576     }
577 
578     protected String getPrimaryKeyString(String className, String primaryKey) {
579         StringBuilder sb = new StringBuilder();
580 
581         sb.append(className);
582         sb.append(StringPool.POUND);
583         sb.append(primaryKey);
584 
585         return sb.toString();
586     }
587 
588     protected void initXStream() {
589         _xStream = new XStream();
590 
591         _xStream.alias("BlogsEntry", BlogsEntryImpl.class);
592         _xStream.alias("BookmarksFolder", BookmarksFolderImpl.class);
593         _xStream.alias("BookmarksEntry", BookmarksEntryImpl.class);
594         _xStream.alias("CalEvent", CalEventImpl.class);
595         _xStream.alias("DLFolder", DLFolderImpl.class);
596         _xStream.alias("DLFileEntry", DLFileEntryImpl.class);
597         _xStream.alias("DLFileShortcut", DLFileShortcutImpl.class);
598         _xStream.alias("DLFileRank", DLFileRankImpl.class);
599         _xStream.alias("IGFolder", IGFolderImpl.class);
600         _xStream.alias("IGImage", IGImageImpl.class);
601         _xStream.alias("JournalArticle", JournalArticleImpl.class);
602         _xStream.alias("JournalFeed", JournalFeedImpl.class);
603         _xStream.alias("JournalStructure", JournalStructureImpl.class);
604         _xStream.alias("JournalTemplate", JournalTemplateImpl.class);
605         _xStream.alias("MBCategory", MBCategoryImpl.class);
606         _xStream.alias("MBMessage", MBMessageImpl.class);
607         _xStream.alias("MBMessageFlag", MBMessageFlagImpl.class);
608         _xStream.alias("MBBan", MBBanImpl.class);
609         _xStream.alias("PollsQuestion", PollsQuestionImpl.class);
610         _xStream.alias("PollsChoice", PollsChoiceImpl.class);
611         _xStream.alias("PollsVote", PollsVoteImpl.class);
612         _xStream.alias("RatingsEntry", RatingsEntryImpl.class);
613         _xStream.alias("WikiNode", WikiNodeImpl.class);
614         _xStream.alias("WikiPage", WikiPageImpl.class);
615     }
616 
617     protected void validateDateRange(Date startDate, Date endDate)
618         throws PortletDataException {
619 
620         if ((startDate == null) ^ (endDate == null)) {
621             throw new PortletDataException(
622                 "Both start and end dates must have valid values or be null");
623         }
624 
625         if (startDate != null) {
626             if (startDate.after(endDate) || startDate.equals(endDate)) {
627                 throw new PortletDataException(
628                     "The start date cannot be after the end date");
629             }
630 
631             Date now = new Date();
632 
633             if (startDate.after(now) || endDate.after(now)) {
634                 throw new PortletDataException(
635                     "Dates must not be in the future");
636             }
637         }
638     }
639 
640     private long _companyId;
641     private long _groupId;
642     private long _importGroupId;
643     private long _oldPlid;
644     private long _plid;
645     private Set<String> _primaryKeys;
646     private Map<String, Map<?, ?>> _newPrimaryKeysMaps =
647         new HashMap<String, Map<?, ?>>();
648     private String _dataStrategy;
649     private UserIdStrategy _userIdStrategy;
650     private Date _startDate;
651     private Date _endDate;
652     private ZipReader _zipReader;
653     private ZipWriter _zipWriter;
654     private XStream _xStream;
655     private Map<String, List<MBMessage>> _commentsMap =
656         new HashMap<String, List<MBMessage>>();
657     private Map<String, String[]> _parameterMap;
658     private Map<String, List<RatingsEntry>> _ratingsEntriesMap =
659         new HashMap<String, List<RatingsEntry>>();
660     private Map<String, String[]> _tagsEntriesMap =
661         new HashMap<String, String[]>();
662     private Set<String> _notUniquePerLayout = new HashSet<String>();
663 
664 }