001
014
015 package com.liferay.portal.lar;
016
017 import com.liferay.portal.LARFileException;
018 import com.liferay.portal.LARTypeException;
019 import com.liferay.portal.LayoutImportException;
020 import com.liferay.portal.LocaleException;
021 import com.liferay.portal.MissingReferenceException;
022 import com.liferay.portal.NoSuchPortletPreferencesException;
023 import com.liferay.portal.PortletIdException;
024 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal;
025 import com.liferay.portal.kernel.exception.PortalException;
026 import com.liferay.portal.kernel.exception.SystemException;
027 import com.liferay.portal.kernel.language.LanguageUtil;
028 import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
029 import com.liferay.portal.kernel.lar.ExportImportPathUtil;
030 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
031 import com.liferay.portal.kernel.lar.ManifestSummary;
032 import com.liferay.portal.kernel.lar.MissingReference;
033 import com.liferay.portal.kernel.lar.MissingReferences;
034 import com.liferay.portal.kernel.lar.PortletDataContext;
035 import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
036 import com.liferay.portal.kernel.lar.PortletDataHandler;
037 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
038 import com.liferay.portal.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
039 import com.liferay.portal.kernel.lar.UserIdStrategy;
040 import com.liferay.portal.kernel.log.Log;
041 import com.liferay.portal.kernel.log.LogFactoryUtil;
042 import com.liferay.portal.kernel.search.Indexer;
043 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
044 import com.liferay.portal.kernel.staging.MergeLayoutPrototypesThreadLocal;
045 import com.liferay.portal.kernel.util.ArrayUtil;
046 import com.liferay.portal.kernel.util.GetterUtil;
047 import com.liferay.portal.kernel.util.LocaleUtil;
048 import com.liferay.portal.kernel.util.MapUtil;
049 import com.liferay.portal.kernel.util.ReleaseInfo;
050 import com.liferay.portal.kernel.util.StringBundler;
051 import com.liferay.portal.kernel.util.StringPool;
052 import com.liferay.portal.kernel.util.StringUtil;
053 import com.liferay.portal.kernel.util.Validator;
054 import com.liferay.portal.kernel.xml.Attribute;
055 import com.liferay.portal.kernel.xml.Document;
056 import com.liferay.portal.kernel.xml.DocumentException;
057 import com.liferay.portal.kernel.xml.Element;
058 import com.liferay.portal.kernel.xml.SAXReaderUtil;
059 import com.liferay.portal.kernel.zip.ZipReader;
060 import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
061 import com.liferay.portal.model.Group;
062 import com.liferay.portal.model.Layout;
063 import com.liferay.portal.model.LayoutConstants;
064 import com.liferay.portal.model.Lock;
065 import com.liferay.portal.model.Portlet;
066 import com.liferay.portal.model.PortletConstants;
067 import com.liferay.portal.model.PortletItem;
068 import com.liferay.portal.model.PortletPreferences;
069 import com.liferay.portal.model.User;
070 import com.liferay.portal.security.permission.PermissionCacheUtil;
071 import com.liferay.portal.service.LayoutLocalServiceUtil;
072 import com.liferay.portal.service.PortletItemLocalServiceUtil;
073 import com.liferay.portal.service.PortletLocalServiceUtil;
074 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
075 import com.liferay.portal.service.ServiceContext;
076 import com.liferay.portal.service.ServiceContextThreadLocal;
077 import com.liferay.portal.service.UserLocalServiceUtil;
078 import com.liferay.portal.service.persistence.PortletPreferencesUtil;
079 import com.liferay.portal.service.persistence.UserUtil;
080 import com.liferay.portal.servlet.filters.cache.CacheUtil;
081 import com.liferay.portal.util.PortalUtil;
082 import com.liferay.portal.util.PortletKeys;
083 import com.liferay.portlet.PortletPreferencesFactoryUtil;
084 import com.liferay.portlet.PortletPreferencesImpl;
085 import com.liferay.portlet.asset.NoSuchTagException;
086 import com.liferay.portlet.asset.model.AssetEntry;
087 import com.liferay.portlet.asset.model.AssetLink;
088 import com.liferay.portlet.asset.model.AssetTag;
089 import com.liferay.portlet.asset.model.AssetTagConstants;
090 import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
091 import com.liferay.portlet.asset.service.AssetLinkLocalServiceUtil;
092 import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
093 import com.liferay.portlet.asset.service.persistence.AssetTagUtil;
094 import com.liferay.portlet.expando.NoSuchTableException;
095 import com.liferay.portlet.expando.model.ExpandoColumn;
096 import com.liferay.portlet.expando.model.ExpandoTable;
097 import com.liferay.portlet.expando.service.ExpandoColumnLocalServiceUtil;
098 import com.liferay.portlet.expando.service.ExpandoTableLocalServiceUtil;
099 import com.liferay.portlet.expando.util.ExpandoConverterUtil;
100 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
101
102 import java.io.File;
103 import java.io.Serializable;
104
105 import java.util.Enumeration;
106 import java.util.List;
107 import java.util.Locale;
108 import java.util.Map;
109
110 import org.apache.commons.lang.time.StopWatch;
111
112
123 public class PortletImporter {
124
125 public static PortletImporter getInstance() {
126 return _instance;
127 }
128
129 public String importPortletData(
130 PortletDataContext portletDataContext, String portletId,
131 PortletPreferences portletPreferences, Element portletDataElement)
132 throws Exception {
133
134 Portlet portlet = PortletLocalServiceUtil.getPortletById(
135 portletDataContext.getCompanyId(), portletId);
136
137 if (portlet == null) {
138 if (_log.isDebugEnabled()) {
139 _log.debug(
140 "Do not import portlet data for " + portletId +
141 " because the portlet does not exist");
142 }
143
144 return null;
145 }
146
147 PortletDataHandler portletDataHandler =
148 portlet.getPortletDataHandlerInstance();
149
150 if ((portletDataHandler == null) ||
151 portletDataHandler.isDataPortletInstanceLevel()) {
152
153 if (_log.isDebugEnabled()) {
154 _log.debug(
155 "Do not import portlet data for " + portletId +
156 " because the portlet does not have a " +
157 "PortletDataHandler");
158 }
159
160 return null;
161 }
162
163 if (_log.isDebugEnabled()) {
164 _log.debug("Importing data for " + portletId);
165 }
166
167 PortletPreferencesImpl portletPreferencesImpl = null;
168
169 if (portletPreferences != null) {
170 portletPreferencesImpl =
171 (PortletPreferencesImpl)
172 PortletPreferencesFactoryUtil.fromDefaultXML(
173 portletPreferences.getPreferences());
174 }
175
176 String portletData = portletDataContext.getZipEntryAsString(
177 portletDataElement.attributeValue("path"));
178
179 if (Validator.isNull(portletData)) {
180 return null;
181 }
182
183 portletPreferencesImpl =
184 (PortletPreferencesImpl)portletDataHandler.importData(
185 portletDataContext, portletId, portletPreferencesImpl,
186 portletData);
187
188 if (portletPreferencesImpl == null) {
189 return null;
190 }
191
192 return PortletPreferencesFactoryUtil.toXML(portletPreferencesImpl);
193 }
194
195 public void importPortletInfo(
196 long userId, long plid, long groupId, String portletId,
197 Map<String, String[]> parameterMap, File file)
198 throws Exception {
199
200 try {
201 ExportImportThreadLocal.setPortletImportInProcess(true);
202
203 doImportPortletInfo(
204 userId, plid, groupId, portletId, parameterMap, file);
205 }
206 finally {
207 ExportImportThreadLocal.setPortletImportInProcess(false);
208
209 CacheUtil.clearCache();
210 JournalContentUtil.clearCache();
211 PermissionCacheUtil.clearCache();
212 }
213 }
214
215 public MissingReferences validateFile(
216 long userId, long plid, long groupId, String portletId,
217 Map<String, String[]> parameterMap, File file)
218 throws Exception {
219
220 ZipReader zipReader = null;
221
222 try {
223 ExportImportThreadLocal.setPortletValidationInProcess(true);
224
225 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
226
227 zipReader = ZipReaderFactoryUtil.getZipReader(file);
228
229 validateFile(layout.getCompanyId(), groupId, portletId, zipReader);
230
231 String userIdStrategyString = MapUtil.getString(
232 parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
233
234 UserIdStrategy userIdStrategy =
235 ExportImportHelperUtil.getUserIdStrategy(
236 userId, userIdStrategyString);
237
238 PortletDataContext portletDataContext =
239 PortletDataContextFactoryUtil.createImportPortletDataContext(
240 layout.getCompanyId(), groupId, parameterMap,
241 userIdStrategy, zipReader);
242
243 portletDataContext.setPrivateLayout(layout.isPrivateLayout());
244
245 MissingReferences missingReferences =
246 ExportImportHelperUtil.validateMissingReferences(
247 portletDataContext);
248
249 Map<String, MissingReference> dependencyMissingReferences =
250 missingReferences.getDependencyMissingReferences();
251
252 if (!dependencyMissingReferences.isEmpty()) {
253 throw new MissingReferenceException(missingReferences);
254 }
255
256 return missingReferences;
257 }
258 finally {
259 ExportImportThreadLocal.setPortletValidationInProcess(false);
260
261 if (zipReader != null) {
262 zipReader.close();
263 }
264 }
265 }
266
267 protected void deletePortletData(
268 PortletDataContext portletDataContext, String portletId, long plid)
269 throws Exception {
270
271 long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
272 int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
273
274 PortletPreferences portletPreferences =
275 PortletPreferencesUtil.fetchByO_O_P_P(
276 ownerId, ownerType, plid, portletId);
277
278 if (portletPreferences == null) {
279 portletPreferences =
280 new com.liferay.portal.model.impl.PortletPreferencesImpl();
281 }
282
283 String xml = deletePortletData(
284 portletDataContext, portletId, portletPreferences);
285
286 if (xml != null) {
287 PortletPreferencesLocalServiceUtil.updatePreferences(
288 ownerId, ownerType, plid, portletId, xml);
289 }
290 }
291
292 protected String deletePortletData(
293 PortletDataContext portletDataContext, String portletId,
294 PortletPreferences portletPreferences)
295 throws Exception {
296
297 Portlet portlet = PortletLocalServiceUtil.getPortletById(
298 portletDataContext.getCompanyId(), portletId);
299
300 if (portlet == null) {
301 if (_log.isDebugEnabled()) {
302 _log.debug(
303 "Do not delete portlet data for " + portletId +
304 " because the portlet does not exist");
305 }
306
307 return null;
308 }
309
310 PortletDataHandler portletDataHandler =
311 portlet.getPortletDataHandlerInstance();
312
313 if (portletDataHandler == null) {
314 if (_log.isDebugEnabled()) {
315 _log.debug(
316 "Do not delete portlet data for " + portletId +
317 " because the portlet does not have a " +
318 "PortletDataHandler");
319 }
320
321 return null;
322 }
323
324 if (_log.isDebugEnabled()) {
325 _log.debug("Deleting data for " + portletId);
326 }
327
328 PortletPreferencesImpl portletPreferencesImpl =
329 (PortletPreferencesImpl)
330 PortletPreferencesFactoryUtil.fromDefaultXML(
331 portletPreferences.getPreferences());
332
333 try {
334 portletPreferencesImpl =
335 (PortletPreferencesImpl)portletDataHandler.deleteData(
336 portletDataContext, portletId, portletPreferencesImpl);
337 }
338 finally {
339 portletDataContext.setGroupId(portletDataContext.getScopeGroupId());
340 }
341
342 if (portletPreferencesImpl == null) {
343 return null;
344 }
345
346 return PortletPreferencesFactoryUtil.toXML(portletPreferencesImpl);
347 }
348
349 protected void doImportPortletInfo(
350 long userId, long plid, long groupId, String portletId,
351 Map<String, String[]> parameterMap, File file)
352 throws Exception {
353
354 boolean deletePortletData = MapUtil.getBoolean(
355 parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
356 boolean importPermissions = MapUtil.getBoolean(
357 parameterMap, PortletDataHandlerKeys.PERMISSIONS);
358 String userIdStrategyString = MapUtil.getString(
359 parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
360
361 StopWatch stopWatch = new StopWatch();
362
363 stopWatch.start();
364
365 User user = UserUtil.findByPrimaryKey(userId);
366
367 ServiceContext serviceContext =
368 ServiceContextThreadLocal.getServiceContext();
369
370 if (serviceContext == null) {
371 serviceContext = new ServiceContext();
372
373 serviceContext.setCompanyId(user.getCompanyId());
374 serviceContext.setSignedIn(false);
375 serviceContext.setUserId(userId);
376
377 ServiceContextThreadLocal.pushServiceContext(serviceContext);
378 }
379
380 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
381
382 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
383
384
385
386 validateFile(layout.getCompanyId(), groupId, portletId, zipReader);
387
388
389
390 UserIdStrategy userIdStrategy =
391 ExportImportHelperUtil.getUserIdStrategy(
392 userId, userIdStrategyString);
393
394 PortletDataContext portletDataContext =
395 PortletDataContextFactoryUtil.createImportPortletDataContext(
396 layout.getCompanyId(), groupId, parameterMap, userIdStrategy,
397 zipReader);
398
399 portletDataContext.setPlid(plid);
400 portletDataContext.setPrivateLayout(layout.isPrivateLayout());
401
402
403
404 Map<Long, Long> groupIds =
405 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
406 Group.class);
407
408 groupIds.put(portletDataContext.getSourceGroupId(), groupId);
409
410
411
412 ManifestSummary manifestSummary =
413 ExportImportHelperUtil.getManifestSummary(portletDataContext);
414
415 if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
416 PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
417 "portlet", portletId, manifestSummary);
418 }
419
420 portletDataContext.setManifestSummary(manifestSummary);
421
422
423
424
425 Element rootElement = portletDataContext.getImportDataRootElement();
426
427 Element portletElement = null;
428
429 try {
430 portletElement = rootElement.element("portlet");
431
432 Document portletDocument = SAXReaderUtil.read(
433 portletDataContext.getZipEntryAsString(
434 portletElement.attributeValue("path")));
435
436 portletElement = portletDocument.getRootElement();
437 }
438 catch (DocumentException de) {
439 throw new SystemException(de);
440 }
441
442 LayoutCache layoutCache = new LayoutCache();
443
444 if (importPermissions) {
445 _permissionImporter.checkRoles(
446 layoutCache, layout.getCompanyId(), groupId, userId,
447 portletElement);
448
449 _permissionImporter.readPortletDataPermissions(portletDataContext);
450 }
451
452 readAssetTags(portletDataContext);
453 readExpandoTables(portletDataContext);
454 readLocks(portletDataContext);
455
456
457
458 if (_log.isDebugEnabled()) {
459 _log.debug("Deleting portlet data");
460 }
461
462 if (deletePortletData) {
463 deletePortletData(portletDataContext, portletId, plid);
464 }
465
466 Element portletDataElement = portletElement.element("portlet-data");
467
468 Map<String, Boolean> importPortletControlsMap =
469 ExportImportHelperUtil.getImportPortletControlsMap(
470 layout.getCompanyId(), portletId, parameterMap,
471 portletDataElement, manifestSummary);
472
473 try {
474
475
476
477 importPortletPreferences(
478 portletDataContext, layout.getCompanyId(), groupId, layout,
479 portletId, portletElement, true,
480 importPortletControlsMap.get(
481 PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
482 importPortletControlsMap.get(
483 PortletDataHandlerKeys.PORTLET_DATA),
484 importPortletControlsMap.get(
485 PortletDataHandlerKeys.PORTLET_SETUP),
486 importPortletControlsMap.get(
487 PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
488
489
490
491 if (importPortletControlsMap.get(
492 PortletDataHandlerKeys.PORTLET_DATA)) {
493
494 if (_log.isDebugEnabled()) {
495 _log.debug("Importing portlet data");
496 }
497
498 importPortletData(
499 portletDataContext, portletId, plid, portletDataElement);
500 }
501 }
502 finally {
503 resetPortletScope(portletDataContext, groupId);
504 }
505
506
507
508 if (importPermissions) {
509 if (_log.isDebugEnabled()) {
510 _log.debug("Importing portlet permissions");
511 }
512
513 _permissionImporter.importPortletPermissions(
514 layoutCache, layout.getCompanyId(), groupId, userId, layout,
515 portletElement, portletId);
516
517 if (userId > 0) {
518 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
519 User.class);
520
521 indexer.reindex(userId);
522 }
523 }
524
525
526
527 if (_log.isDebugEnabled()) {
528 _log.debug("Importing asset links");
529 }
530
531 readAssetLinks(portletDataContext);
532
533
534
535 _deletionSystemEventImporter.importDeletionSystemEvents(
536 portletDataContext);
537
538 if (_log.isInfoEnabled()) {
539 _log.info("Importing portlet takes " + stopWatch.getTime() + " ms");
540 }
541
542
543
544 boolean importPortletSetup = importPortletControlsMap.get(
545 PortletDataHandlerKeys.PORTLET_SETUP);
546
547 if (importPortletSetup) {
548 try {
549 List<Element> serviceElements = rootElement.elements("service");
550
551 for (Element serviceElement : serviceElements) {
552 Document serviceDocument = SAXReaderUtil.read(
553 portletDataContext.getZipEntryAsString(
554 serviceElement.attributeValue("path")));
555
556 importServicePortletPreferences(
557 portletDataContext, serviceDocument.getRootElement());
558 }
559 }
560 catch (DocumentException de) {
561 throw new SystemException(de);
562 }
563 }
564
565 zipReader.close();
566 }
567
568 protected PortletPreferences getPortletPreferences(
569 long companyId, long ownerId, int ownerType, long plid,
570 String serviceName)
571 throws PortalException {
572
573 PortletPreferences portletPreferences = null;
574
575 try {
576 if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) ||
577 (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
578 (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP)) {
579
580 portletPreferences =
581 PortletPreferencesLocalServiceUtil.getPortletPreferences(
582 ownerId, ownerType, LayoutConstants.DEFAULT_PLID,
583 serviceName);
584 }
585 else {
586 portletPreferences =
587 PortletPreferencesLocalServiceUtil.getPortletPreferences(
588 ownerId, ownerType, plid, serviceName);
589 }
590 }
591 catch (NoSuchPortletPreferencesException nsppe) {
592 portletPreferences =
593 PortletPreferencesLocalServiceUtil.addPortletPreferences(
594 companyId, ownerId, ownerType, plid, serviceName, null,
595 null);
596 }
597
598 return portletPreferences;
599 }
600
601 protected void importAssetTag(
602 PortletDataContext portletDataContext, Map<Long, Long> assetTagPKs,
603 Element assetTagElement, AssetTag assetTag)
604 throws PortalException {
605
606 long userId = portletDataContext.getUserId(assetTag.getUserUuid());
607
608 ServiceContext serviceContext = new ServiceContext();
609
610 serviceContext.setAddGroupPermissions(true);
611 serviceContext.setAddGuestPermissions(true);
612 serviceContext.setCreateDate(assetTag.getCreateDate());
613 serviceContext.setModifiedDate(assetTag.getModifiedDate());
614 serviceContext.setScopeGroupId(portletDataContext.getScopeGroupId());
615
616 AssetTag importedAssetTag = null;
617
618 List<Element> propertyElements = assetTagElement.elements("property");
619
620 String[] properties = new String[propertyElements.size()];
621
622 for (int i = 0; i < propertyElements.size(); i++) {
623 Element propertyElement = propertyElements.get(i);
624
625 String key = propertyElement.attributeValue("key");
626 String value = propertyElement.attributeValue("value");
627
628 properties[i] = key.concat(
629 AssetTagConstants.PROPERTY_KEY_VALUE_SEPARATOR).concat(value);
630 }
631
632 AssetTag existingAssetTag = null;
633
634 try {
635 existingAssetTag = AssetTagUtil.findByG_N(
636 portletDataContext.getScopeGroupId(), assetTag.getName());
637 }
638 catch (NoSuchTagException nste) {
639 if (_log.isDebugEnabled()) {
640 StringBundler sb = new StringBundler(5);
641
642 sb.append("No AssetTag exists with the key {groupId=");
643 sb.append(portletDataContext.getScopeGroupId());
644 sb.append(", name=");
645 sb.append(assetTag.getName());
646 sb.append("}");
647
648 _log.debug(sb.toString());
649 }
650 }
651
652 try {
653 if (existingAssetTag == null) {
654 importedAssetTag = AssetTagLocalServiceUtil.addTag(
655 userId, assetTag.getName(), properties, serviceContext);
656 }
657 else {
658 importedAssetTag = AssetTagLocalServiceUtil.updateTag(
659 userId, existingAssetTag.getTagId(), assetTag.getName(),
660 properties, serviceContext);
661 }
662
663 assetTagPKs.put(assetTag.getTagId(), importedAssetTag.getTagId());
664
665 portletDataContext.importPermissions(
666 AssetTag.class, assetTag.getTagId(),
667 importedAssetTag.getTagId());
668 }
669 catch (NoSuchTagException nste) {
670 _log.error(
671 "Could not find the parent category for category " +
672 assetTag.getTagId());
673 }
674 }
675
676 protected void importPortletData(
677 PortletDataContext portletDataContext, String portletId, long plid,
678 Element portletDataElement)
679 throws Exception {
680
681 long ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
682 int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
683
684 PortletPreferences portletPreferences =
685 PortletPreferencesUtil.fetchByO_O_P_P(
686 ownerId, ownerType, plid, portletId);
687
688 if (portletPreferences == null) {
689 portletPreferences =
690 new com.liferay.portal.model.impl.PortletPreferencesImpl();
691 }
692
693 String xml = importPortletData(
694 portletDataContext, portletId, portletPreferences,
695 portletDataElement);
696
697 if (Validator.isNotNull(xml)) {
698 PortletPreferencesLocalServiceUtil.updatePreferences(
699 ownerId, ownerType, plid, portletId, xml);
700 }
701 }
702
703 protected void importPortletPreferences(
704 PortletDataContext portletDataContext, long companyId, long groupId,
705 Layout layout, String portletId, Element parentElement,
706 boolean preserveScopeLayoutId, boolean importPortletArchivedSetups,
707 boolean importPortletData, boolean importPortletSetup,
708 boolean importPortletUserPreferences)
709 throws Exception {
710
711 if (portletId == null) {
712 portletId = parentElement.attributeValue("portlet-id");
713 }
714
715 long plid = LayoutConstants.DEFAULT_PLID;
716 String scopeType = StringPool.BLANK;
717 String scopeLayoutUuid = StringPool.BLANK;
718
719 if (layout != null) {
720 plid = layout.getPlid();
721
722 if (preserveScopeLayoutId && (portletId != null)) {
723 javax.portlet.PortletPreferences jxPortletPreferences =
724 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
725 layout, portletId);
726
727 scopeType = GetterUtil.getString(
728 jxPortletPreferences.getValue("lfrScopeType", null));
729 scopeLayoutUuid = GetterUtil.getString(
730 jxPortletPreferences.getValue("lfrScopeLayoutUuid", null));
731
732 portletDataContext.setScopeType(scopeType);
733 portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
734 }
735 }
736
737 List<Element> portletPreferencesElements = parentElement.elements(
738 "portlet-preferences");
739
740 for (Element portletPreferencesElement : portletPreferencesElements) {
741 String path = portletPreferencesElement.attributeValue("path");
742
743 if (portletDataContext.isPathNotProcessed(path)) {
744 String xml = null;
745
746 Element element = null;
747
748 try {
749 xml = portletDataContext.getZipEntryAsString(path);
750
751 Document preferencesDocument = SAXReaderUtil.read(xml);
752
753 element = preferencesDocument.getRootElement();
754 }
755 catch (DocumentException de) {
756 throw new SystemException(de);
757 }
758
759 long ownerId = GetterUtil.getLong(
760 element.attributeValue("owner-id"));
761 int ownerType = GetterUtil.getInteger(
762 element.attributeValue("owner-type"));
763
764 if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
765 !importPortletSetup) {
766
767 continue;
768 }
769
770 if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) &&
771 !importPortletArchivedSetups) {
772
773 continue;
774 }
775
776 if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) &&
777 (ownerId != PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
778 !importPortletUserPreferences) {
779
780 continue;
781 }
782
783 long curPlid = plid;
784 String curPortletId = portletId;
785
786 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
787 curPlid = PortletKeys.PREFS_PLID_SHARED;
788 curPortletId = PortletConstants.getRootPortletId(portletId);
789 ownerId = portletDataContext.getScopeGroupId();
790 }
791
792 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
793 String userUuid = element.attributeValue(
794 "archive-user-uuid");
795
796 long userId = portletDataContext.getUserId(userUuid);
797
798 String name = element.attributeValue("archive-name");
799
800 curPortletId = PortletConstants.getRootPortletId(portletId);
801
802 PortletItem portletItem =
803 PortletItemLocalServiceUtil.updatePortletItem(
804 userId, groupId, name, curPortletId,
805 PortletPreferences.class.getName());
806
807 curPlid = LayoutConstants.DEFAULT_PLID;
808 ownerId = portletItem.getPortletItemId();
809 }
810
811 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
812 String userUuid = element.attributeValue("user-uuid");
813
814 ownerId = portletDataContext.getUserId(userUuid);
815 }
816
817 boolean defaultUser = GetterUtil.getBoolean(
818 element.attributeValue("default-user"));
819
820 if (defaultUser) {
821 ownerId = UserLocalServiceUtil.getDefaultUserId(companyId);
822 }
823
824 javax.portlet.PortletPreferences jxPortletPreferences =
825 PortletPreferencesFactoryUtil.fromXML(
826 companyId, ownerId, ownerType, curPlid, curPortletId,
827 xml);
828
829 Element importDataRootElement =
830 portletDataContext.getImportDataRootElement();
831
832 try {
833 Element preferenceDataElement =
834 portletPreferencesElement.element("preference-data");
835
836 if (preferenceDataElement != null) {
837 portletDataContext.setImportDataRootElement(
838 preferenceDataElement);
839 }
840
841 Portlet portlet = PortletLocalServiceUtil.getPortletById(
842 portletDataContext.getCompanyId(), curPortletId);
843
844 PortletDataHandler portletDataHandler =
845 portlet.getPortletDataHandlerInstance();
846
847 jxPortletPreferences =
848 portletDataHandler.processImportPortletPreferences(
849 portletDataContext, curPortletId,
850 jxPortletPreferences);
851 }
852 finally {
853 portletDataContext.setImportDataRootElement(
854 importDataRootElement);
855 }
856
857 updatePortletPreferences(
858 portletDataContext, ownerId, ownerType, curPlid,
859 curPortletId,
860 PortletPreferencesFactoryUtil.toXML(jxPortletPreferences),
861 importPortletData);
862 }
863 }
864
865 if (preserveScopeLayoutId && (layout != null)) {
866 javax.portlet.PortletPreferences jxPortletPreferences =
867 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
868 layout, portletId);
869
870 try {
871 jxPortletPreferences.setValue("lfrScopeType", scopeType);
872 jxPortletPreferences.setValue(
873 "lfrScopeLayoutUuid", scopeLayoutUuid);
874
875 jxPortletPreferences.store();
876 }
877 finally {
878 portletDataContext.setScopeType(scopeType);
879 portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
880 }
881 }
882 }
883
884 protected void importServicePortletPreferences(
885 PortletDataContext portletDataContext, Element serviceElement)
886 throws PortalException {
887
888 long ownerId = GetterUtil.getLong(
889 serviceElement.attributeValue("owner-id"));
890 int ownerType = GetterUtil.getInteger(
891 serviceElement.attributeValue("owner-type"));
892 String serviceName = serviceElement.attributeValue("service-name");
893
894 PortletPreferences portletPreferences = getPortletPreferences(
895 portletDataContext.getCompanyId(), ownerId, ownerType,
896 LayoutConstants.DEFAULT_PLID, serviceName);
897
898 for (Attribute attribute : serviceElement.attributes()) {
899 serviceElement.remove(attribute);
900 }
901
902 String xml = serviceElement.asXML();
903
904 portletPreferences.setPreferences(xml);
905
906 PortletPreferencesLocalServiceUtil.updatePortletPreferences(
907 portletPreferences);
908 }
909
910 protected void readAssetLinks(PortletDataContext portletDataContext)
911 throws Exception {
912
913 String xml = portletDataContext.getZipEntryAsString(
914 ExportImportPathUtil.getSourceRootPath(portletDataContext) +
915 "/links.xml");
916
917 if (xml == null) {
918 return;
919 }
920
921 Document document = SAXReaderUtil.read(xml);
922
923 Element rootElement = document.getRootElement();
924
925 List<Element> assetLinkGroupElements = rootElement.elements(
926 "asset-link-group");
927
928 for (Element assetLinkGroupElement : assetLinkGroupElements) {
929 String sourceUuid = assetLinkGroupElement.attributeValue(
930 "source-uuid");
931
932 AssetEntry sourceAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
933 portletDataContext.getScopeGroupId(), sourceUuid);
934
935 if (sourceAssetEntry == null) {
936 sourceAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
937 portletDataContext.getCompanyGroupId(), sourceUuid);
938 }
939
940 if (sourceAssetEntry == null) {
941 if (_log.isWarnEnabled()) {
942 _log.warn(
943 "Unable to find asset entry with uuid " + sourceUuid);
944 }
945
946 continue;
947 }
948
949 List<Element> assetLinksElements = assetLinkGroupElement.elements(
950 "asset-link");
951
952 for (Element assetLinkElement : assetLinksElements) {
953 String path = assetLinkElement.attributeValue("path");
954
955 if (!portletDataContext.isPathNotProcessed(path)) {
956 continue;
957 }
958
959 String targetUuid = assetLinkElement.attributeValue(
960 "target-uuid");
961
962 AssetEntry targetAssetEntry =
963 AssetEntryLocalServiceUtil.fetchEntry(
964 portletDataContext.getScopeGroupId(), targetUuid);
965
966 if (targetAssetEntry == null) {
967 targetAssetEntry = AssetEntryLocalServiceUtil.fetchEntry(
968 portletDataContext.getCompanyGroupId(), targetUuid);
969 }
970
971 if (targetAssetEntry == null) {
972 if (_log.isWarnEnabled()) {
973 _log.warn(
974 "Unable to find asset entry with uuid " +
975 targetUuid);
976 }
977
978 continue;
979 }
980
981 AssetLink assetLink =
982 (AssetLink)portletDataContext.getZipEntryAsObject(path);
983
984 long userId = portletDataContext.getUserId(
985 assetLink.getUserUuid());
986
987 AssetLinkLocalServiceUtil.updateLink(
988 userId, sourceAssetEntry.getEntryId(),
989 targetAssetEntry.getEntryId(), assetLink.getType(),
990 assetLink.getWeight());
991 }
992 }
993 }
994
995 protected void readAssetTags(PortletDataContext portletDataContext)
996 throws Exception {
997
998 String xml = portletDataContext.getZipEntryAsString(
999 ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1000 "/tags.xml");
1001
1002 if (xml == null) {
1003 return;
1004 }
1005
1006 Document document = SAXReaderUtil.read(xml);
1007
1008 Element rootElement = document.getRootElement();
1009
1010 List<Element> assetTagElements = rootElement.elements("tag");
1011
1012 for (Element assetTagElement : assetTagElements) {
1013 String path = assetTagElement.attributeValue("path");
1014
1015 if (!portletDataContext.isPathNotProcessed(path)) {
1016 continue;
1017 }
1018
1019 AssetTag assetTag =
1020 (AssetTag)portletDataContext.getZipEntryAsObject(path);
1021
1022 Map<Long, Long> assetTagPKs =
1023 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1024 AssetTag.class);
1025
1026 importAssetTag(
1027 portletDataContext, assetTagPKs, assetTagElement, assetTag);
1028 }
1029
1030 List<Element> assetElements = rootElement.elements("asset");
1031
1032 for (Element assetElement : assetElements) {
1033 String className = GetterUtil.getString(
1034 assetElement.attributeValue("class-name"));
1035 long classPK = GetterUtil.getLong(
1036 assetElement.attributeValue("class-pk"));
1037 String assetTagNames = GetterUtil.getString(
1038 assetElement.attributeValue("tags"));
1039
1040 portletDataContext.addAssetTags(
1041 className, classPK, StringUtil.split(assetTagNames));
1042 }
1043 }
1044
1045 protected void readExpandoTables(PortletDataContext portletDataContext)
1046 throws Exception {
1047
1048 String xml = portletDataContext.getZipEntryAsString(
1049 ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1050 "/expando-tables.xml");
1051
1052 if (xml == null) {
1053 return;
1054 }
1055
1056 Document document = SAXReaderUtil.read(xml);
1057
1058 Element rootElement = document.getRootElement();
1059
1060 List<Element> expandoTableElements = rootElement.elements(
1061 "expando-table");
1062
1063 for (Element expandoTableElement : expandoTableElements) {
1064 String className = expandoTableElement.attributeValue("class-name");
1065
1066 ExpandoTable expandoTable = null;
1067
1068 try {
1069 expandoTable = ExpandoTableLocalServiceUtil.getDefaultTable(
1070 portletDataContext.getCompanyId(), className);
1071 }
1072 catch (NoSuchTableException nste) {
1073 expandoTable = ExpandoTableLocalServiceUtil.addDefaultTable(
1074 portletDataContext.getCompanyId(), className);
1075 }
1076
1077 List<Element> expandoColumnElements = expandoTableElement.elements(
1078 "expando-column");
1079
1080 for (Element expandoColumnElement : expandoColumnElements) {
1081 long columnId = GetterUtil.getLong(
1082 expandoColumnElement.attributeValue("column-id"));
1083 String name = expandoColumnElement.attributeValue("name");
1084 int type = GetterUtil.getInteger(
1085 expandoColumnElement.attributeValue("type"));
1086 String defaultData = expandoColumnElement.elementText(
1087 "default-data");
1088 String typeSettings = expandoColumnElement.elementText(
1089 "type-settings");
1090
1091 Serializable defaultDataObject =
1092 ExpandoConverterUtil.getAttributeFromString(
1093 type, defaultData);
1094
1095 ExpandoColumn expandoColumn =
1096 ExpandoColumnLocalServiceUtil.getColumn(
1097 expandoTable.getTableId(), name);
1098
1099 if (expandoColumn != null) {
1100 ExpandoColumnLocalServiceUtil.updateColumn(
1101 expandoColumn.getColumnId(), name, type,
1102 defaultDataObject);
1103 }
1104 else {
1105 expandoColumn = ExpandoColumnLocalServiceUtil.addColumn(
1106 expandoTable.getTableId(), name, type,
1107 defaultDataObject);
1108 }
1109
1110 ExpandoColumnLocalServiceUtil.updateTypeSettings(
1111 expandoColumn.getColumnId(), typeSettings);
1112
1113 portletDataContext.importPermissions(
1114 ExpandoColumn.class, columnId, expandoColumn.getColumnId());
1115 }
1116 }
1117 }
1118
1119 protected void readLocks(PortletDataContext portletDataContext)
1120 throws Exception {
1121
1122 String xml = portletDataContext.getZipEntryAsString(
1123 ExportImportPathUtil.getSourceRootPath(portletDataContext) +
1124 "/locks.xml");
1125
1126 if (xml == null) {
1127 return;
1128 }
1129
1130 Document document = SAXReaderUtil.read(xml);
1131
1132 Element rootElement = document.getRootElement();
1133
1134 List<Element> assetElements = rootElement.elements("asset");
1135
1136 for (Element assetElement : assetElements) {
1137 String path = assetElement.attributeValue("path");
1138 String className = assetElement.attributeValue("class-name");
1139 String key = assetElement.attributeValue("key");
1140
1141 Lock lock = (Lock)portletDataContext.getZipEntryAsObject(path);
1142
1143 if (lock != null) {
1144 portletDataContext.addLocks(className, key, lock);
1145 }
1146 }
1147 }
1148
1149 protected void resetPortletScope(
1150 PortletDataContext portletDataContext, long groupId) {
1151
1152 portletDataContext.setScopeGroupId(groupId);
1153 portletDataContext.setScopeLayoutUuid(StringPool.BLANK);
1154 portletDataContext.setScopeType(StringPool.BLANK);
1155 }
1156
1157 protected void updatePortletPreferences(
1158 PortletDataContext portletDataContext, long ownerId, int ownerType,
1159 long plid, String portletId, String xml, boolean importData)
1160 throws Exception {
1161
1162 Portlet portlet = PortletLocalServiceUtil.getPortletById(
1163 portletDataContext.getCompanyId(), portletId);
1164
1165 if (portlet == null) {
1166 if (_log.isDebugEnabled()) {
1167 _log.debug(
1168 "Do not update portlet preferences for " + portletId +
1169 " because the portlet does not exist");
1170 }
1171
1172 return;
1173 }
1174
1175 PortletDataHandler portletDataHandler =
1176 portlet.getPortletDataHandlerInstance();
1177
1178 if (importData || !MergeLayoutPrototypesThreadLocal.isInProgress()) {
1179 PortletPreferencesLocalServiceUtil.updatePreferences(
1180 ownerId, ownerType, plid, portletId, xml);
1181
1182 return;
1183 }
1184
1185
1186
1187 String[] dataPortletPreferences =
1188 portletDataHandler.getDataPortletPreferences();
1189
1190
1191
1192 javax.portlet.PortletPreferences portletPreferences =
1193 PortletPreferencesLocalServiceUtil.getPreferences(
1194 portletDataContext.getCompanyId(), ownerId, ownerType, plid,
1195 portletId);
1196
1197
1198
1199 javax.portlet.PortletPreferences jxPortletPreferences =
1200 PortletPreferencesFactoryUtil.fromXML(
1201 portletDataContext.getCompanyId(), ownerId, ownerType, plid,
1202 portletId, xml);
1203
1204 Enumeration<String> enu = jxPortletPreferences.getNames();
1205
1206 while (enu.hasMoreElements()) {
1207 String name = enu.nextElement();
1208
1209 String scopeLayoutUuid = portletDataContext.getScopeLayoutUuid();
1210 String scopeType = portletDataContext.getScopeType();
1211
1212 if (!ArrayUtil.contains(dataPortletPreferences, name) ||
1213 (Validator.isNull(scopeLayoutUuid) &&
1214 scopeType.equals("company"))) {
1215
1216 String[] values = jxPortletPreferences.getValues(name, null);
1217
1218 portletPreferences.setValues(name, values);
1219 }
1220 }
1221
1222 PortletPreferencesLocalServiceUtil.updatePreferences(
1223 ownerId, ownerType, plid, portletId, portletPreferences);
1224 }
1225
1226 protected void validateFile(
1227 long companyId, long groupId, String portletId, ZipReader zipReader)
1228 throws Exception {
1229
1230
1231
1232 String xml = zipReader.getEntryAsString("/manifest.xml");
1233
1234 if (xml == null) {
1235 throw new LARFileException("manifest.xml not found in the LAR");
1236 }
1237
1238 Element rootElement = null;
1239
1240 try {
1241 Document document = SAXReaderUtil.read(xml);
1242
1243 rootElement = document.getRootElement();
1244 }
1245 catch (Exception e) {
1246 throw new LARFileException(e);
1247 }
1248
1249
1250
1251 int buildNumber = ReleaseInfo.getBuildNumber();
1252
1253 Element headerElement = rootElement.element("header");
1254
1255 int importBuildNumber = GetterUtil.getInteger(
1256 headerElement.attributeValue("build-number"));
1257
1258 if (buildNumber != importBuildNumber) {
1259 throw new LayoutImportException(
1260 "LAR build number " + importBuildNumber + " does not match " +
1261 "portal build number " + buildNumber);
1262 }
1263
1264
1265
1266 String larType = headerElement.attributeValue("type");
1267
1268 if (!larType.equals("portlet")) {
1269 throw new LARTypeException(larType);
1270 }
1271
1272
1273
1274 String rootPortletId = headerElement.attributeValue("root-portlet-id");
1275
1276 if (!PortletConstants.getRootPortletId(portletId).equals(
1277 rootPortletId)) {
1278
1279 throw new PortletIdException("Invalid portlet id " + rootPortletId);
1280 }
1281
1282
1283
1284 Portlet portlet = PortletLocalServiceUtil.getPortletById(
1285 companyId, portletId);
1286
1287 PortletDataHandler portletDataHandler =
1288 portlet.getPortletDataHandlerInstance();
1289
1290 if (portletDataHandler.isDataLocalized()) {
1291 Locale[] sourceAvailableLocales = LocaleUtil.fromLanguageIds(
1292 StringUtil.split(
1293 headerElement.attributeValue("available-locales")));
1294
1295 Locale[] targetAvailableLocales = LanguageUtil.getAvailableLocales(
1296 PortalUtil.getSiteGroupId(groupId));
1297
1298 for (Locale sourceAvailableLocale : sourceAvailableLocales) {
1299 if (!ArrayUtil.contains(
1300 targetAvailableLocales, sourceAvailableLocale)) {
1301
1302 LocaleException le = new LocaleException(
1303 LocaleException.TYPE_EXPORT_IMPORT,
1304 "Locale " + sourceAvailableLocale + " is not " +
1305 "available in company " + companyId);
1306
1307 le.setSourceAvailableLocales(sourceAvailableLocales);
1308 le.setTargetAvailableLocales(targetAvailableLocales);
1309
1310 throw le;
1311 }
1312 }
1313 }
1314 }
1315
1316 private PortletImporter() {
1317 }
1318
1319 private static Log _log = LogFactoryUtil.getLog(PortletImporter.class);
1320
1321 private static PortletImporter _instance = new PortletImporter();
1322
1323 private DeletionSystemEventImporter _deletionSystemEventImporter =
1324 DeletionSystemEventImporter.getInstance();
1325 private PermissionImporter _permissionImporter =
1326 PermissionImporter.getInstance();
1327
1328 }