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