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