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