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.MBMessage;
45  import com.liferay.portlet.messageboards.model.impl.MBBanImpl;
46  import com.liferay.portlet.messageboards.model.impl.MBCategoryImpl;
47  import com.liferay.portlet.messageboards.model.impl.MBMessageFlagImpl;
48  import com.liferay.portlet.messageboards.model.impl.MBMessageImpl;
49  import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
50  import com.liferay.portlet.polls.model.impl.PollsChoiceImpl;
51  import com.liferay.portlet.polls.model.impl.PollsQuestionImpl;
52  import com.liferay.portlet.polls.model.impl.PollsVoteImpl;
53  import com.liferay.portlet.ratings.model.RatingsEntry;
54  import com.liferay.portlet.ratings.model.impl.RatingsEntryImpl;
55  import com.liferay.portlet.ratings.service.RatingsEntryLocalServiceUtil;
56  import com.liferay.portlet.tags.NoSuchAssetException;
57  import com.liferay.portlet.tags.model.TagsAsset;
58  import com.liferay.portlet.tags.model.TagsEntry;
59  import com.liferay.portlet.tags.service.TagsAssetLocalServiceUtil;
60  import com.liferay.portlet.wiki.model.impl.WikiNodeImpl;
61  import com.liferay.portlet.wiki.model.impl.WikiPageImpl;
62  
63  import com.thoughtworks.xstream.XStream;
64  
65  import java.io.IOException;
66  import java.io.InputStream;
67  
68  import java.util.Date;
69  import java.util.HashMap;
70  import java.util.HashSet;
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, InputStream is)
251         throws SystemException {
252 
253         try {
254             getZipWriter().addEntry(path, is);
255         }
256         catch (IOException ioe) {
257             throw new SystemException(ioe);
258         }
259     }
260 
261     public void addZipEntry(String path, Object object) throws SystemException {
262         addZipEntry(path, toXML(object));
263     }
264 
265     public void addZipEntry(String path, String s) throws SystemException {
266         try {
267             getZipWriter().addEntry(path, s);
268         }
269         catch (IOException ioe) {
270             throw new SystemException(ioe);
271         }
272     }
273 
274     public void addZipEntry(String path, StringBuilder sb)
275         throws SystemException {
276 
277         try {
278             getZipWriter().addEntry(path, sb);
279         }
280         catch (IOException ioe) {
281             throw new SystemException(ioe);
282         }
283     }
284 
285     public Object fromXML(byte[] bytes) {
286         return _xStream.fromXML(new String(bytes));
287     }
288 
289     public Object fromXML(String xml) {
290         return _xStream.fromXML(xml);
291     }
292 
293     public boolean getBooleanParameter(String namespace, String name) {
294         boolean defaultValue = MapUtil.getBoolean(
295             getParameterMap(),
296             PortletDataHandlerKeys.PORTLET_DATA_CONTROL_DEFAULT, true);
297 
298         return MapUtil.getBoolean(
299             getParameterMap(),
300             PortletDataHandlerControl.getNamespacedControlName(namespace, name),
301             defaultValue);
302     }
303 
304     public Map<String, List<MBMessage>> getComments() {
305         return _commentsMap;
306     }
307 
308     public long getCompanyId() {
309         return _companyId;
310     }
311 
312     public String getDataStrategy() {
313         return _dataStrategy;
314     }
315 
316     public Date getEndDate() {
317         return _endDate;
318     }
319 
320     public long getGroupId() {
321         return _groupId;
322     }
323 
324     public long getImportGroupId() {
325         return _importGroupId;
326     }
327 
328     public String getImportLayoutPath(long layoutId) {
329         return getImportRootPath() + ROOT_PATH_LAYOUTS + layoutId;
330     }
331 
332     public String getImportPortletPath(String portletId) {
333         return getImportRootPath() + ROOT_PATH_PORTLETS + portletId;
334     }
335 
336     public String getImportRootPath() {
337         return ROOT_PATH_GROUPS + getImportGroupId();
338     }
339 
340     public String getLayoutPath(long layoutId) {
341         return getRootPath() + ROOT_PATH_LAYOUTS + layoutId;
342     }
343 
344     public Map<?, ?> getNewPrimaryKeysMap(Class<?> classObj) {
345         Map<?, ?> map = _newPrimaryKeysMaps.get(classObj.getName());
346 
347         if (map == null) {
348             map = new HashMap<Object, Object>();
349 
350             _newPrimaryKeysMaps.put(classObj.getName(), map);
351         }
352 
353         return map;
354     }
355 
356     public long getOldPlid() {
357         return _oldPlid;
358     }
359 
360     public Map<String, String[]> getParameterMap() {
361         return _parameterMap;
362     }
363 
364     public long getPlid() {
365         return _plid;
366     }
367 
368     public String getPortletPath(String portletId) {
369         return getRootPath() + ROOT_PATH_PORTLETS + portletId;
370     }
371 
372     public Set<String> getPrimaryKeys() {
373         return _primaryKeys;
374     }
375 
376     public Map<String, List<RatingsEntry>> getRatingsEntries() {
377         return _ratingsEntriesMap;
378     }
379 
380     public String getRootPath() {
381         return ROOT_PATH_GROUPS + getGroupId();
382     }
383 
384     public Date getStartDate() {
385         return _startDate;
386     }
387 
388     public Map<String, String[]> getTagsEntries() {
389         return _tagsEntriesMap;
390     }
391 
392     public String[] getTagsEntries(Class<?> classObj, long classPK) {
393         return _tagsEntriesMap.get(getPrimaryKeyString(classObj, classPK));
394     }
395 
396     public String[] getTagsEntries(String className, long classPK) {
397         return _tagsEntriesMap.get(getPrimaryKeyString(className, classPK));
398     }
399 
400     public long getUserId(String userUuid) throws SystemException {
401         return _userIdStrategy.getUserId(userUuid);
402     }
403 
404     public UserIdStrategy getUserIdStrategy() {
405         return _userIdStrategy;
406     }
407 
408     public Map<String, byte[]> getZipEntries() {
409         return getZipReader().getEntries();
410     }
411 
412     public byte[] getZipEntryAsByteArray(String path) {
413         return getZipReader().getEntryAsByteArray(path);
414     }
415 
416     public Object getZipEntryAsObject(String path) {
417         return fromXML(getZipEntryAsString(path));
418     }
419 
420     public String getZipEntryAsString(String path) {
421         return getZipReader().getEntryAsString(path);
422     }
423 
424     public Map<String, List<ObjectValuePair<String, byte[]>>>
425         getZipFolderEntries() {
426 
427         return getZipReader().getFolderEntries();
428     }
429 
430     public List<ObjectValuePair<String, byte[]>> getZipFolderEntries(
431         String path) {
432 
433         if (Validator.isNull(path)) {
434             return null;
435         }
436 
437         List<ObjectValuePair<String, byte[]>> folderEntries =
438             getZipReader().getFolderEntries(path);
439 
440         if ((folderEntries == null) && path.startsWith(StringPool.SLASH)) {
441             folderEntries = getZipReader().getFolderEntries(path.substring(1));
442         }
443 
444         return folderEntries;
445     }
446 
447     public ZipReader getZipReader() {
448         return _zipReader;
449     }
450 
451     public ZipWriter getZipWriter() {
452         return _zipWriter;
453     }
454 
455     public boolean hasDateRange() {
456         if (_startDate != null) {
457             return true;
458         }
459         else {
460             return false;
461         }
462     }
463 
464     public boolean hasNotUniquePerLayout(String portletId) {
465         return _notUniquePerLayout.contains(portletId);
466     }
467 
468     public boolean hasPrimaryKey(Class<?> classObj, String primaryKey) {
469         return _primaryKeys.contains(getPrimaryKeyString(classObj, primaryKey));
470     }
471 
472     public void importComments(
473             Class<?> classObj, long classPK, long newClassPK, long groupId)
474         throws PortalException, SystemException {
475 
476         Map<Long, Long> messagePKs = new HashMap<Long, Long>();
477         Map<Long, Long> threadPKs = new HashMap<Long, Long>();
478 
479         List<MBMessage> messages = _commentsMap.get(
480             getPrimaryKeyString(classObj, classPK));
481 
482         if (messages == null) {
483             return;
484         }
485 
486         for (MBMessage message : messages) {
487             long userId = getUserId(message.getUserUuid());
488             long parentMessageId = MapUtil.getLong(
489                 messagePKs, message.getParentMessageId(),
490                 message.getParentMessageId());
491             long threadId = MapUtil.getLong(
492                 threadPKs, message.getThreadId(), message.getThreadId());
493 
494             MBMessage newMessage =
495                 MBMessageLocalServiceUtil.addDiscussionMessage(
496                     userId, message.getUserName(), groupId, classObj.getName(),
497                     ((Long)newClassPK).longValue(), threadId,
498                     parentMessageId, message.getSubject(), message.getBody());
499 
500             messagePKs.put(message.getMessageId(), newMessage.getMessageId());
501             threadPKs.put(message.getThreadId(), newMessage.getThreadId());
502         }
503     }
504 
505     public void importRatingsEntries(
506             Class<?> classObj, long classPK, long newClassPK)
507         throws PortalException, SystemException {
508 
509         List<RatingsEntry> entries = _ratingsEntriesMap.get(
510             getPrimaryKeyString(classObj, classPK));
511 
512         if (entries == null) {
513             return;
514         }
515 
516         for (RatingsEntry entry : entries) {
517             long userId = getUserId(entry.getUserUuid());
518 
519             RatingsEntryLocalServiceUtil.updateEntry(
520                 userId, classObj.getName(), ((Long)newClassPK).longValue(),
521                 entry.getScore());
522         }
523     }
524 
525     public boolean isPathNotProcessed(String path) {
526         return !addPrimaryKey(String.class, path);
527     }
528 
529     public boolean isWithinDateRange(Date modifiedDate) {
530         if (!hasDateRange()) {
531             return true;
532         }
533         else if ((_startDate.compareTo(modifiedDate) <= 0) &&
534                  (_endDate.after(modifiedDate))) {
535 
536             return true;
537         }
538         else {
539             return false;
540         }
541     }
542 
543     public void putNotUniquePerLayout(String portletId) {
544         _notUniquePerLayout.add(portletId);
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(String className, long classPK) {
568         return getPrimaryKeyString(className, String.valueOf(classPK));
569     }
570 
571     protected String getPrimaryKeyString(Class<?> classObj, String primaryKey) {
572         return getPrimaryKeyString(classObj.getName(), primaryKey);
573     }
574 
575     protected String getPrimaryKeyString(String className, String primaryKey) {
576         StringBuilder sb = new StringBuilder();
577 
578         sb.append(className);
579         sb.append(StringPool.POUND);
580         sb.append(primaryKey);
581 
582         return sb.toString();
583     }
584 
585     protected void initXStream() {
586         _xStream = new XStream();
587 
588         _xStream.alias("BlogsEntry", BlogsEntryImpl.class);
589         _xStream.alias("BookmarksFolder", BookmarksFolderImpl.class);
590         _xStream.alias("BookmarksEntry", BookmarksEntryImpl.class);
591         _xStream.alias("CalEvent", CalEventImpl.class);
592         _xStream.alias("DLFolder", DLFolderImpl.class);
593         _xStream.alias("DLFileEntry", DLFileEntryImpl.class);
594         _xStream.alias("DLFileShortcut", DLFileShortcutImpl.class);
595         _xStream.alias("DLFileRank", DLFileRankImpl.class);
596         _xStream.alias("IGFolder", IGFolderImpl.class);
597         _xStream.alias("IGImage", IGImageImpl.class);
598         _xStream.alias("JournalArticle", JournalArticleImpl.class);
599         _xStream.alias("JournalFeed", JournalFeedImpl.class);
600         _xStream.alias("JournalStructure", JournalStructureImpl.class);
601         _xStream.alias("JournalTemplate", JournalTemplateImpl.class);
602         _xStream.alias("MBCategory", MBCategoryImpl.class);
603         _xStream.alias("MBMessage", MBMessageImpl.class);
604         _xStream.alias("MBMessageFlag", MBMessageFlagImpl.class);
605         _xStream.alias("MBBan", MBBanImpl.class);
606         _xStream.alias("PollsQuestion", PollsQuestionImpl.class);
607         _xStream.alias("PollsChoice", PollsChoiceImpl.class);
608         _xStream.alias("PollsVote", PollsVoteImpl.class);
609         _xStream.alias("RatingsEntry", RatingsEntryImpl.class);
610         _xStream.alias("WikiNode", WikiNodeImpl.class);
611         _xStream.alias("WikiPage", WikiPageImpl.class);
612     }
613 
614     protected void validateDateRange(Date startDate, Date endDate)
615         throws PortletDataException {
616 
617         if ((startDate == null) ^ (endDate == null)) {
618             throw new PortletDataException(
619                 "Both start and end dates must have valid values or be null");
620         }
621 
622         if (startDate != null) {
623             if (startDate.after(endDate) || startDate.equals(endDate)) {
624                 throw new PortletDataException(
625                     "The start date cannot be after the end date");
626             }
627 
628             Date now = new Date();
629 
630             if (startDate.after(now) || endDate.after(now)) {
631                 throw new PortletDataException(
632                     "Dates must not be in the future");
633             }
634         }
635     }
636 
637     private long _companyId;
638     private long _groupId;
639     private long _importGroupId;
640     private long _oldPlid;
641     private long _plid;
642     private Set<String> _primaryKeys;
643     private Map<String, Map<?, ?>> _newPrimaryKeysMaps =
644         new HashMap<String, Map<?, ?>>();
645     private String _dataStrategy;
646     private UserIdStrategy _userIdStrategy;
647     private Date _startDate;
648     private Date _endDate;
649     private ZipReader _zipReader;
650     private ZipWriter _zipWriter;
651     private XStream _xStream;
652     private Map<String, List<MBMessage>> _commentsMap =
653         new HashMap<String, List<MBMessage>>();
654     private Map<String, String[]> _parameterMap;
655     private Map<String, List<RatingsEntry>> _ratingsEntriesMap =
656         new HashMap<String, List<RatingsEntry>>();
657     private Map<String, String[]> _tagsEntriesMap =
658         new HashMap<String, String[]>();
659     private Set<String> _notUniquePerLayout = new HashSet<String>();
660 
661 }