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