1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.lar;
16  
17  import com.liferay.portal.LARFileException;
18  import com.liferay.portal.LARTypeException;
19  import com.liferay.portal.LayoutImportException;
20  import com.liferay.portal.PortletIdException;
21  import com.liferay.portal.kernel.exception.PortalException;
22  import com.liferay.portal.kernel.exception.SystemException;
23  import com.liferay.portal.kernel.lar.PortletDataContext;
24  import com.liferay.portal.kernel.lar.PortletDataHandler;
25  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
26  import com.liferay.portal.kernel.lar.UserIdStrategy;
27  import com.liferay.portal.kernel.log.Log;
28  import com.liferay.portal.kernel.log.LogFactoryUtil;
29  import com.liferay.portal.kernel.util.ArrayUtil;
30  import com.liferay.portal.kernel.util.GetterUtil;
31  import com.liferay.portal.kernel.util.MapUtil;
32  import com.liferay.portal.kernel.util.ReleaseInfo;
33  import com.liferay.portal.kernel.util.StringBundler;
34  import com.liferay.portal.kernel.util.StringPool;
35  import com.liferay.portal.kernel.util.StringUtil;
36  import com.liferay.portal.kernel.workflow.WorkflowThreadLocal;
37  import com.liferay.portal.kernel.xml.Document;
38  import com.liferay.portal.kernel.xml.DocumentException;
39  import com.liferay.portal.kernel.xml.Element;
40  import com.liferay.portal.kernel.xml.Node;
41  import com.liferay.portal.kernel.xml.SAXReaderUtil;
42  import com.liferay.portal.kernel.zip.ZipReader;
43  import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
44  import com.liferay.portal.model.Group;
45  import com.liferay.portal.model.Layout;
46  import com.liferay.portal.model.Lock;
47  import com.liferay.portal.model.Portlet;
48  import com.liferay.portal.model.PortletConstants;
49  import com.liferay.portal.model.PortletItem;
50  import com.liferay.portal.model.PortletPreferences;
51  import com.liferay.portal.model.User;
52  import com.liferay.portal.service.GroupLocalServiceUtil;
53  import com.liferay.portal.service.LayoutLocalServiceUtil;
54  import com.liferay.portal.service.PortletItemLocalServiceUtil;
55  import com.liferay.portal.service.PortletLocalServiceUtil;
56  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
57  import com.liferay.portal.service.ServiceContext;
58  import com.liferay.portal.service.UserLocalServiceUtil;
59  import com.liferay.portal.service.persistence.PortletPreferencesUtil;
60  import com.liferay.portal.service.persistence.UserUtil;
61  import com.liferay.portal.util.PortletKeys;
62  import com.liferay.portlet.PortletPreferencesFactoryUtil;
63  import com.liferay.portlet.PortletPreferencesImpl;
64  import com.liferay.portlet.PortletPreferencesSerializer;
65  import com.liferay.portlet.asset.NoSuchCategoryException;
66  import com.liferay.portlet.asset.model.AssetCategory;
67  import com.liferay.portlet.asset.model.AssetCategoryConstants;
68  import com.liferay.portlet.asset.model.AssetVocabulary;
69  import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
70  import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil;
71  import com.liferay.portlet.asset.service.persistence.AssetCategoryUtil;
72  import com.liferay.portlet.asset.service.persistence.AssetVocabularyUtil;
73  import com.liferay.portlet.messageboards.model.MBMessage;
74  import com.liferay.portlet.ratings.model.RatingsEntry;
75  import com.liferay.portlet.social.util.SocialActivityThreadLocal;
76  
77  import java.io.File;
78  
79  import java.util.ArrayList;
80  import java.util.HashSet;
81  import java.util.List;
82  import java.util.Map;
83  
84  import org.apache.commons.lang.time.StopWatch;
85  
86  /**
87   * <a href="PortletImporter.java.html"><b><i>View Source</i></b></a>
88   *
89   * @author Brian Wing Shun Chan
90   * @author Joel Kozikowski
91   * @author Charles May
92   * @author Raymond Augé
93   * @author Jorge Ferrer
94   * @author Bruno Farache
95   * @author Zsigmond Rab
96   * @author Douglas Wong
97   */
98  public class PortletImporter {
99  
100     public void importPortletInfo(
101             long userId, long plid, long groupId, String portletId,
102             Map<String, String[]> parameterMap, File file)
103         throws PortalException, SystemException {
104 
105         boolean deletePortletData = MapUtil.getBoolean(
106             parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
107         boolean importPermissions = MapUtil.getBoolean(
108             parameterMap, PortletDataHandlerKeys.PERMISSIONS);
109         boolean importPortletData = MapUtil.getBoolean(
110             parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
111         boolean importPortletArchivedSetups = MapUtil.getBoolean(
112             parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
113         boolean importPortletSetup = MapUtil.getBoolean(
114             parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
115         boolean importUserPreferences = MapUtil.getBoolean(
116             parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
117         String userIdStrategy = MapUtil.getString(
118             parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
119 
120         StopWatch stopWatch = null;
121 
122         if (_log.isInfoEnabled()) {
123             stopWatch = new StopWatch();
124 
125             stopWatch.start();
126         }
127 
128         Layout layout = LayoutLocalServiceUtil.getLayout(plid);
129 
130         long companyId = layout.getCompanyId();
131 
132         User user = UserUtil.findByPrimaryKey(userId);
133 
134         UserIdStrategy strategy = getUserIdStrategy(user, userIdStrategy);
135 
136         ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
137 
138         PortletDataContext context = new PortletDataContextImpl(
139             companyId, groupId, parameterMap, new HashSet<String>(),
140             strategy, zipReader);
141 
142         context.setPortetDataContextListener(
143             new PortletDataContextListenerImpl(context));
144 
145         context.setPlid(plid);
146         context.setPrivateLayout(layout.isPrivateLayout());
147 
148         // Zip
149 
150         Element root = null;
151 
152         // Manifest
153 
154         String xml = context.getZipEntryAsString("/manifest.xml");
155 
156         try {
157             Document doc = SAXReaderUtil.read(xml);
158 
159             root = doc.getRootElement();
160         }
161         catch (Exception e) {
162             throw new LARFileException(
163                 "Cannot locate a manifest in this LAR file.");
164         }
165 
166         // Build compatibility
167 
168         Element header = root.element("header");
169 
170         int buildNumber = ReleaseInfo.getBuildNumber();
171 
172         int importBuildNumber = GetterUtil.getInteger(
173             header.attributeValue("build-number"));
174 
175         if (buildNumber != importBuildNumber) {
176             throw new LayoutImportException(
177                 "LAR build number " + importBuildNumber + " does not match " +
178                     "portal build number " + buildNumber);
179         }
180 
181         // Type compatibility
182 
183         String type = header.attributeValue("type");
184 
185         if (!type.equals("portlet")) {
186             throw new LARTypeException(
187                 "Invalid type of LAR file (" + type + ")");
188         }
189 
190         // Portlet compatibility
191 
192         String rootPortletId = header.attributeValue("root-portlet-id");
193 
194         if (!PortletConstants.getRootPortletId(portletId).equals(
195                 rootPortletId)) {
196 
197             throw new PortletIdException("Invalid portlet id " + rootPortletId);
198         }
199 
200         // Import group id
201 
202         long sourceGroupId = GetterUtil.getLong(
203             header.attributeValue("group-id"));
204 
205         context.setSourceGroupId(sourceGroupId);
206 
207         // Read categories, comments, locks, ratings, and tags to make them
208         // available to the data handlers through the context
209 
210         if (importPermissions) {
211             _permissionImporter.readPortletDataPermissions(context);
212         }
213 
214         readCategories(context);
215         readComments(context, root);
216         readLocks(context, root);
217         readRatings(context, root);
218         readTags(context, root);
219 
220         // Delete portlet data
221 
222         if (_log.isDebugEnabled()) {
223             _log.debug("Deleting portlet data");
224         }
225 
226         if (deletePortletData) {
227             deletePortletData(context, portletId, plid);
228         }
229 
230         Element portletRefEl = root.element("portlet");
231         Element portletEl = null;
232 
233         try {
234             Document portletDoc = SAXReaderUtil.read(
235                 context.getZipEntryAsString(
236                     portletRefEl.attributeValue("path")));
237 
238             portletEl = portletDoc.getRootElement();
239         }
240         catch (DocumentException de) {
241             throw new SystemException(de);
242         }
243 
244         // Portlet preferences
245 
246         importPortletPreferences(
247             context, layout.getCompanyId(), groupId, layout, portletId,
248             portletEl, importPortletSetup, importPortletArchivedSetups,
249             importUserPreferences, true);
250 
251         // Portlet data
252 
253         if (_log.isDebugEnabled()) {
254             _log.debug("Importing portlet data");
255         }
256 
257         if (importPortletData) {
258             Element portletDataRefEl = portletEl.element("portlet-data");
259 
260             if (portletDataRefEl != null) {
261                 importPortletData(context, portletId, plid, portletDataRefEl);
262             }
263             else {
264                 if (_log.isWarnEnabled()) {
265                     _log.warn(
266                         "Could not import portlet data because it cannot be " +
267                             "found in the input");
268                 }
269             }
270         }
271 
272         if (_log.isInfoEnabled()) {
273             _log.info(
274                 "Importing portlet data takes " + stopWatch.getTime() + " ms");
275         }
276 
277         zipReader.close();
278     }
279 
280     protected void deletePortletData(
281             PortletDataContext context, String portletId, long plid)
282         throws SystemException {
283 
284         long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
285         int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
286 
287         PortletPreferences portletPreferences =
288             PortletPreferencesUtil.fetchByO_O_P_P(
289                 ownerId, ownerType, plid, portletId);
290 
291         if (portletPreferences == null) {
292             portletPreferences =
293                 new com.liferay.portal.model.impl.PortletPreferencesImpl();
294         }
295 
296         String xml = deletePortletData(
297             context, portletId, portletPreferences);
298 
299         if (xml != null) {
300             PortletPreferencesLocalServiceUtil.updatePreferences(
301                 ownerId, ownerType, plid, portletId, xml);
302         }
303     }
304 
305     protected String deletePortletData(
306             PortletDataContext context, String portletId,
307             PortletPreferences portletPreferences)
308         throws SystemException {
309 
310         Portlet portlet = PortletLocalServiceUtil.getPortletById(
311             context.getCompanyId(), portletId);
312 
313         if (portlet == null) {
314             if (_log.isDebugEnabled()) {
315                 _log.debug(
316                     "Do not delete portlet data for " + portletId +
317                         " because the portlet does not exist");
318             }
319 
320             return null;
321         }
322 
323         PortletDataHandler portletDataHandler =
324             portlet.getPortletDataHandlerInstance();
325 
326         if (portletDataHandler == null) {
327             if (_log.isDebugEnabled()) {
328                 _log.debug(
329                     "Do not delete portlet data for " + portletId +
330                         " because the portlet does not have a " +
331                             "PortletDataHandler");
332             }
333 
334             return null;
335         }
336 
337         if (_log.isDebugEnabled()) {
338             _log.debug("Deleting data for " + portletId);
339         }
340 
341         PortletPreferencesImpl preferencesImpl =
342             (PortletPreferencesImpl)PortletPreferencesSerializer.fromDefaultXML(
343                 portletPreferences.getPreferences());
344 
345         try {
346             preferencesImpl =
347                 (PortletPreferencesImpl)portletDataHandler.deleteData(
348                     context, portletId, preferencesImpl);
349         }
350         catch (Exception e) {
351             throw new SystemException(e);
352         }
353         finally {
354             context.setGroupId(context.getScopeGroupId());
355         }
356 
357         if (preferencesImpl == null) {
358             return null;
359         }
360 
361         return PortletPreferencesSerializer.toXML(preferencesImpl);
362     }
363 
364     protected String getCategoryPath(
365         PortletDataContext context, long categoryId) {
366 
367         StringBundler sb = new StringBundler(6);
368 
369         sb.append(context.getSourceRootPath());
370         sb.append("/categories/");
371         sb.append(categoryId);
372         sb.append(".xml");
373 
374         return sb.toString();
375     }
376 
377     protected UserIdStrategy getUserIdStrategy(
378         User user, String userIdStrategy) {
379 
380         if (UserIdStrategy.ALWAYS_CURRENT_USER_ID.equals(userIdStrategy)) {
381             return new AlwaysCurrentUserIdStrategy(user);
382         }
383 
384         return new CurrentUserIdStrategy(user);
385     }
386 
387     protected void importCategory(
388             PortletDataContext context, Map<Long, Long> vocabularyPKs,
389             Map<Long, Long> categoryPKs, Element categoryEl,
390             AssetCategory category)
391         throws Exception {
392 
393         long userId = context.getUserId(category.getUserUuid());
394         long vocabularyId = MapUtil.getLong(
395             vocabularyPKs, category.getVocabularyId(),
396             category.getVocabularyId());
397         long parentCategoryId = MapUtil.getLong(
398             categoryPKs, category.getParentCategoryId(),
399             category.getParentCategoryId());
400 
401         if ((parentCategoryId !=
402                 AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
403             (parentCategoryId == category.getParentCategoryId())) {
404 
405             String path = getCategoryPath(context, parentCategoryId);
406 
407             AssetCategory parentCategory =
408                 (AssetCategory)context.getZipEntryAsObject(path);
409 
410             Node parentCategoryNode = categoryEl.getParent().selectSingleNode(
411                 "./category[@path='" + path + "']");
412 
413             if (parentCategoryNode != null) {
414                 importCategory(
415                     context, vocabularyPKs, categoryPKs,
416                     (Element)parentCategoryNode, parentCategory);
417 
418                 parentCategoryId = MapUtil.getLong(
419                     categoryPKs, category.getParentCategoryId(),
420                     category.getParentCategoryId());
421             }
422         }
423 
424         ServiceContext serviceContext = new ServiceContext();
425 
426         serviceContext.setAddCommunityPermissions(true);
427         serviceContext.setAddGuestPermissions(true);
428         serviceContext.setCreateDate(category.getCreateDate());
429         serviceContext.setModifiedDate(category.getModifiedDate());
430         serviceContext.setScopeGroupId(context.getScopeGroupId());
431 
432         AssetCategory importedCategory = null;
433 
434         try {
435             if (parentCategoryId !=
436                     AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
437 
438                 AssetCategoryUtil.findByPrimaryKey(parentCategoryId);
439             }
440 
441             List<Element> propertyEls = categoryEl.elements("property");
442 
443             String[] properties = new String[propertyEls.size()];
444 
445             for (int i = 0; i < properties.length; i++) {
446                 Element propertyEl = propertyEls.get(i);
447                 String key = propertyEl.attributeValue("key");
448                 String value = propertyEl.attributeValue("value");
449 
450                 properties[i] = key.concat(StringPool.COLON).concat(value);
451             }
452 
453             AssetCategory existingCategory = AssetCategoryUtil.fetchByP_N_V(
454                 parentCategoryId, category.getName(), vocabularyId);
455 
456             if (existingCategory == null) {
457                 importedCategory = AssetCategoryLocalServiceUtil.addCategory(
458                     category.getUuid(), userId, parentCategoryId,
459                     category.getTitleMap(), vocabularyId, properties,
460                     serviceContext);
461             }
462             else {
463                 importedCategory = AssetCategoryLocalServiceUtil.updateCategory(
464                     userId, existingCategory.getCategoryId(), parentCategoryId,
465                     category.getTitleMap(), vocabularyId, properties,
466                     serviceContext);
467             }
468 
469             categoryPKs.put(
470                 category.getCategoryId(), importedCategory.getCategoryId());
471 
472             context.importPermissions(
473                 AssetCategory.class, category.getCategoryId(),
474                 importedCategory.getCategoryId());
475         }
476         catch (NoSuchCategoryException nsce) {
477             _log.error(
478                 "Could not find the parent category for category " +
479                     category.getCategoryId());
480         }
481     }
482 
483     protected void importVocabulary(
484             PortletDataContext context, Map<Long, Long> vocabularyPKs,
485             Element vocabularyEl, AssetVocabulary vocabulary)
486         throws Exception {
487 
488         long userId = context.getUserId(vocabulary.getUserUuid());
489         long groupId = context.getScopeGroupId();
490 
491         ServiceContext serviceContext = new ServiceContext();
492 
493         serviceContext.setAddCommunityPermissions(true);
494         serviceContext.setAddGuestPermissions(true);
495         serviceContext.setCreateDate(vocabulary.getCreateDate());
496         serviceContext.setModifiedDate(vocabulary.getModifiedDate());
497         serviceContext.setScopeGroupId(context.getScopeGroupId());
498 
499         AssetVocabulary importedVocabulary = null;
500 
501         AssetVocabulary existingVocabulary = AssetVocabularyUtil.fetchByG_N(
502             groupId, vocabulary.getName());
503 
504         if (existingVocabulary == null) {
505             importedVocabulary = AssetVocabularyLocalServiceUtil.addVocabulary(
506                 vocabulary.getUuid(), userId, vocabulary.getTitleMap(),
507                 vocabulary.getDescriptionMap(), vocabulary.getSettings(),
508                 serviceContext);
509         }
510         else {
511             importedVocabulary =
512                 AssetVocabularyLocalServiceUtil.updateVocabulary(
513                     existingVocabulary.getVocabularyId(),
514                     vocabulary.getTitleMap(), vocabulary.getDescriptionMap(),
515                     vocabulary.getSettings(),serviceContext);
516         }
517 
518         vocabularyPKs.put(
519             vocabulary.getVocabularyId(), importedVocabulary.getVocabularyId());
520 
521         context.importPermissions(
522             AssetVocabulary.class, vocabulary.getVocabularyId(),
523             importedVocabulary.getVocabularyId());
524     }
525 
526     protected void importPortletData(
527             PortletDataContext context, String portletId, long plid,
528             Element portletDataRefEl)
529         throws SystemException {
530 
531         long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
532         int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
533 
534         PortletPreferences portletPreferences =
535             PortletPreferencesUtil.fetchByO_O_P_P(
536                 ownerId, ownerType, plid, portletId);
537 
538         if (portletPreferences == null) {
539             portletPreferences =
540                 new com.liferay.portal.model.impl.PortletPreferencesImpl();
541         }
542 
543         String xml = importPortletData(
544             context, portletId, portletPreferences, portletDataRefEl);
545 
546         if (xml != null) {
547             PortletPreferencesLocalServiceUtil.updatePreferences(
548                 ownerId, ownerType, plid, portletId, xml);
549         }
550     }
551 
552     protected String importPortletData(
553             PortletDataContext context, String portletId,
554             PortletPreferences portletPreferences, Element portletDataRefEl)
555         throws SystemException {
556 
557         Portlet portlet = PortletLocalServiceUtil.getPortletById(
558             context.getCompanyId(), portletId);
559 
560         if (portlet == null) {
561             if (_log.isDebugEnabled()) {
562                 _log.debug(
563                     "Do not import portlet data for " + portletId +
564                         " because the portlet does not exist");
565             }
566 
567             return null;
568         }
569 
570         PortletDataHandler portletDataHandler =
571             portlet.getPortletDataHandlerInstance();
572 
573         if (portletDataHandler == null) {
574             if (_log.isDebugEnabled()) {
575                 _log.debug(
576                     "Do not import portlet data for " + portletId +
577                         " because the portlet does not have a " +
578                             "PortletDataHandler");
579             }
580 
581             return null;
582         }
583 
584         if (_log.isDebugEnabled()) {
585             _log.debug("Importing data for " + portletId);
586         }
587 
588         // Layout scope
589 
590         long groupId = context.getGroupId();
591 
592         long scopeLayoutId = context.getScopeLayoutId();
593 
594         if (scopeLayoutId == 0) {
595             scopeLayoutId = GetterUtil.getLong(
596                 portletDataRefEl.getParent().attributeValue("scope-layout-id"));
597         }
598 
599         if (scopeLayoutId > 0) {
600             try {
601                 Layout scopeLayout = LayoutLocalServiceUtil.getLayout(
602                     context.getGroupId(), context.isPrivateLayout(),
603                     scopeLayoutId);
604 
605                 Group scopeGroup = null;
606 
607                 if (scopeLayout.hasScopeGroup()) {
608                     scopeGroup = scopeLayout.getScopeGroup();
609                 }
610                 else {
611                     String name = String.valueOf(scopeLayout.getPlid());
612 
613                     scopeGroup = GroupLocalServiceUtil.addGroup(
614                         context.getUserId(null), Layout.class.getName(),
615                         scopeLayout.getPlid(), name, null, 0, null, true, null);
616                 }
617 
618                 context.setGroupId(scopeGroup.getGroupId());
619             }
620             catch (PortalException pe) {
621             }
622         }
623 
624         PortletPreferencesImpl preferencesImpl = null;
625 
626         if (portletPreferences != null) {
627             preferencesImpl = (PortletPreferencesImpl)
628                 PortletPreferencesSerializer.fromDefaultXML(
629                     portletPreferences.getPreferences());
630         }
631 
632         String portletData = context.getZipEntryAsString(
633             portletDataRefEl.attributeValue("path"));
634 
635         try {
636             SocialActivityThreadLocal.setEnabled(false);
637             WorkflowThreadLocal.setEnabled(false);
638 
639             preferencesImpl =
640                 (PortletPreferencesImpl)portletDataHandler.importData(
641                     context, portletId, preferencesImpl, portletData);
642         }
643         catch (Exception e) {
644             throw new SystemException(e);
645         }
646         finally {
647             context.setGroupId(groupId);
648 
649             SocialActivityThreadLocal.setEnabled(true);
650             WorkflowThreadLocal.setEnabled(true);
651         }
652 
653         if (preferencesImpl == null) {
654             return null;
655         }
656 
657         return PortletPreferencesSerializer.toXML(preferencesImpl);
658     }
659 
660     protected void importPortletPreferences(
661             PortletDataContext context, long companyId, long groupId,
662             Layout layout, String portletId, Element parentEl,
663             boolean importPortletSetup, boolean importPortletArchivedSetups,
664             boolean importUserPreferences, boolean preserveScopeLayoutId)
665         throws PortalException, SystemException {
666 
667         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
668         long plid = 0;
669         long scopeLayoutId = 0;
670 
671         if (layout != null) {
672             plid = layout.getPlid();
673 
674             if (preserveScopeLayoutId && (portletId != null)) {
675                 javax.portlet.PortletPreferences jxPreferences =
676                     PortletPreferencesFactoryUtil.getLayoutPortletSetup(
677                         layout, portletId);
678 
679                 scopeLayoutId = GetterUtil.getLong(
680                     jxPreferences.getValue("lfr-scope-layout-id", null));
681 
682                 context.setScopeLayoutId(scopeLayoutId);
683             }
684         }
685 
686         List<Element> preferencesEls = parentEl.elements("portlet-preferences");
687 
688         for (Element preferencesEl : preferencesEls) {
689             String path = preferencesEl.attributeValue("path");
690 
691             if (context.isPathNotProcessed(path)) {
692                 Element el = null;
693                 String xml = null;
694 
695                 try {
696                     xml = context.getZipEntryAsString(path);
697 
698                     Document preferencesDoc = SAXReaderUtil.read(xml);
699 
700                     el = preferencesDoc.getRootElement();
701                 }
702                 catch (DocumentException de) {
703                     throw new SystemException(de);
704                 }
705 
706                 long ownerId = GetterUtil.getLong(
707                     el.attributeValue("owner-id"));
708                 int ownerType = GetterUtil.getInteger(
709                     el.attributeValue("owner-type"));
710 
711                 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
712                     continue;
713                 }
714 
715                 if (((ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) ||
716                     (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT)) &&
717                     !importPortletSetup) {
718 
719                     continue;
720                 }
721 
722                 if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) &&
723                     !importPortletArchivedSetups) {
724 
725                     continue;
726                 }
727 
728                 if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) &&
729                     (ownerId != PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
730                     !importUserPreferences) {
731 
732                     continue;
733                 }
734 
735                 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
736                     plid = PortletKeys.PREFS_PLID_SHARED;
737                     ownerId = context.getGroupId();
738                 }
739 
740                 boolean defaultUser = GetterUtil.getBoolean(
741                     el.attributeValue("default-user"));
742 
743                 if (portletId == null) {
744                     portletId = el.attributeValue("portlet-id");
745                 }
746 
747                 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
748                     portletId = PortletConstants.getRootPortletId(portletId);
749 
750                     String userUuid = el.attributeValue("archive-user-uuid");
751                     String name = el.attributeValue("archive-name");
752 
753                     long userId = context.getUserId(userUuid);
754 
755                     PortletItem portletItem =
756                         PortletItemLocalServiceUtil.updatePortletItem(
757                             userId, groupId, name, portletId,
758                             PortletPreferences.class.getName());
759 
760                     plid = 0;
761                     ownerId = portletItem.getPortletItemId();
762                 }
763 
764                 if (defaultUser) {
765                     ownerId = defaultUserId;
766                 }
767 
768                 PortletPreferencesLocalServiceUtil.updatePreferences(
769                     ownerId, ownerType, plid, portletId, xml);
770             }
771         }
772 
773         if (preserveScopeLayoutId && (layout != null)) {
774             javax.portlet.PortletPreferences jxPreferences =
775                 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
776                     layout, portletId);
777 
778             try {
779                 jxPreferences.setValue(
780                     "lfr-scope-layout-id", String.valueOf(scopeLayoutId));
781 
782                 jxPreferences.store();
783             }
784             catch (Exception e) {
785                 throw new PortalException(e);
786             }
787             finally {
788                 context.setScopeLayoutId(scopeLayoutId);
789             }
790         }
791     }
792 
793     protected void readComments(PortletDataContext context, Element parentEl)
794         throws SystemException {
795 
796         try {
797             String xml = context.getZipEntryAsString(
798                 context.getSourceRootPath() + "/comments.xml");
799 
800             if (xml == null) {
801                 return;
802             }
803 
804             Document doc = SAXReaderUtil.read(xml);
805 
806             Element root = doc.getRootElement();
807 
808             List<Element> assets = root.elements("asset");
809 
810             for (Element asset : assets) {
811                 String path = asset.attributeValue("path");
812                 String className = asset.attributeValue("class-name");
813                 long classPK = GetterUtil.getLong(
814                     asset.attributeValue("class-pk"));
815 
816                 List<String> zipFolderEntries = context.getZipFolderEntries(
817                     path);
818 
819                 List<MBMessage> messages = new ArrayList<MBMessage>();
820 
821                 for (String zipFolderEntry : zipFolderEntries) {
822                     MBMessage message = (MBMessage)context.getZipEntryAsObject(
823                         zipFolderEntry);
824 
825                     if (message != null) {
826                         messages.add(message);
827                     }
828                 }
829 
830                 context.addComments(className, classPK, messages);
831             }
832         }
833         catch (Exception e) {
834             throw new SystemException(e);
835         }
836     }
837 
838     protected void readLocks(PortletDataContext context, Element parentEl)
839         throws SystemException {
840 
841         try {
842             String xml = context.getZipEntryAsString(
843                 context.getSourceRootPath() + "/locks.xml");
844 
845             if (xml == null) {
846                 return;
847             }
848 
849             Document doc = SAXReaderUtil.read(xml);
850 
851             Element root = doc.getRootElement();
852 
853             List<Element> assets = root.elements("asset");
854 
855             for (Element asset : assets) {
856                 String className = asset.attributeValue("class-name");
857                 String key = asset.attributeValue("key");
858                 String path = asset.attributeValue("path");
859 
860                 Lock lock = (Lock)context.getZipEntryAsObject(path);
861 
862                 if (lock != null) {
863                     context.addLocks(className, key, lock);
864                 }
865             }
866         }
867         catch (Exception e) {
868             throw new SystemException(e);
869         }
870     }
871 
872     protected void readRatings(PortletDataContext context, Element parentEl)
873         throws SystemException {
874 
875         try {
876             String xml = context.getZipEntryAsString(
877                 context.getSourceRootPath() + "/ratings.xml");
878 
879             if (xml == null) {
880                 return;
881             }
882 
883             Document doc = SAXReaderUtil.read(xml);
884 
885             Element root = doc.getRootElement();
886 
887             List<Element> assets = root.elements("asset");
888 
889             for (Element asset : assets) {
890                 String path = asset.attributeValue("path");
891                 String className = asset.attributeValue("class-name");
892                 long classPK = GetterUtil.getLong(
893                     asset.attributeValue("class-pk"));
894 
895                 List<String> zipFolderEntries = context.getZipFolderEntries(
896                     path);
897 
898                 List<RatingsEntry> ratingsEntries =
899                     new ArrayList<RatingsEntry>();
900 
901                 for (String zipFolderEntry : zipFolderEntries) {
902                     RatingsEntry ratingsEntry =
903                         (RatingsEntry)context.getZipEntryAsObject(
904                             zipFolderEntry);
905 
906                     if (ratingsEntry != null) {
907                         ratingsEntries.add(ratingsEntry);
908                     }
909                 }
910 
911                 context.addRatingsEntries(
912                     className, new Long(classPK), ratingsEntries);
913             }
914         }
915         catch (Exception e) {
916             throw new SystemException(e);
917         }
918     }
919 
920     protected void readCategories(PortletDataContext context)
921         throws SystemException {
922 
923         try {
924             String xml = context.getZipEntryAsString(
925                 context.getSourceRootPath() + "/categories-hierarchy.xml");
926 
927             if (xml == null) {
928                 return;
929             }
930 
931             Document doc = SAXReaderUtil.read(xml);
932 
933             Element root = doc.getRootElement();
934 
935             List<Element> vocabularyEls = root.element("vocabularies").elements(
936                 "vocabulary");
937 
938             Map<Long, Long> vocabularyPKs =
939                 (Map<Long, Long>)context.getNewPrimaryKeysMap(
940                     AssetVocabulary.class);
941 
942             for (Element vocabularyEl : vocabularyEls) {
943                 String path = vocabularyEl.attributeValue("path");
944 
945                 if (!context.isPathNotProcessed(path)) {
946                     continue;
947                 }
948 
949                 AssetVocabulary vocabulary =
950                     (AssetVocabulary)context.getZipEntryAsObject(path);
951 
952                 importVocabulary(
953                     context, vocabularyPKs, vocabularyEl, vocabulary);
954             }
955 
956             List<Element> categoryEls = root.element("categories").elements(
957                 "category");
958 
959             Map<Long, Long> categoryPKs =
960                 (Map<Long, Long>)context.getNewPrimaryKeysMap(
961                     AssetCategory.class);
962 
963             for (Element categoryEl : categoryEls) {
964                 String path = categoryEl.attributeValue("path");
965 
966                 if (!context.isPathNotProcessed(path)) {
967                     continue;
968                 }
969 
970                 AssetCategory category =
971                     (AssetCategory)context.getZipEntryAsObject(path);
972 
973                 importCategory(
974                     context, vocabularyPKs, categoryPKs, categoryEl, category);
975             }
976 
977             List<Element> assets = root.element("assets").elements("asset");
978 
979             for (Element asset : assets) {
980                 String className = GetterUtil.getString(
981                     asset.attributeValue("class-name"));
982                 long classPK = GetterUtil.getLong(
983                     asset.attributeValue("class-pk"));
984                 String[] assetCategoryUuids = StringUtil.split(
985                     GetterUtil.getString(
986                         asset.attributeValue("category-uuids")));
987 
988                 long[] assetCategoryIds = new long[0];
989 
990                 for (String assetCategoryUuid : assetCategoryUuids) {
991                     AssetCategory assetCategory =
992                         AssetCategoryUtil.fetchByUUID_G(
993                             assetCategoryUuid, context.getScopeGroupId());
994 
995                     if (assetCategory != null) {
996                         assetCategoryIds = ArrayUtil.append(
997                             assetCategoryIds, assetCategory.getCategoryId());
998                     }
999                 }
1000
1001                context.addAssetCategories(
1002                    className, new Long(classPK), assetCategoryIds);
1003            }
1004        }
1005        catch (Exception e) {
1006            throw new SystemException(e);
1007        }
1008    }
1009
1010    protected void readTags(PortletDataContext context, Element parentEl)
1011        throws SystemException {
1012
1013        try {
1014            String xml = context.getZipEntryAsString(
1015                context.getSourceRootPath() + "/tags.xml");
1016
1017            if (xml == null) {
1018                return;
1019            }
1020
1021            Document doc = SAXReaderUtil.read(xml);
1022
1023            Element root = doc.getRootElement();
1024
1025            List<Element> assets = root.elements("asset");
1026
1027            for (Element asset : assets) {
1028                String className = GetterUtil.getString(
1029                    asset.attributeValue("class-name"));
1030                long classPK = GetterUtil.getLong(
1031                    asset.attributeValue("class-pk"));
1032                String assetTagNames = GetterUtil.getString(
1033                    asset.attributeValue("tags"));
1034
1035                context.addAssetTags(
1036                    className, new Long(classPK),
1037                    StringUtil.split(assetTagNames));
1038            }
1039        }
1040        catch (Exception e) {
1041            throw new SystemException(e);
1042        }
1043    }
1044
1045    private static Log _log = LogFactoryUtil.getLog(PortletImporter.class);
1046
1047    private PermissionImporter _permissionImporter = new PermissionImporter();
1048
1049}