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