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