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