001
014
015 package com.liferay.portal.lar;
016
017 import com.liferay.portal.LARFileException;
018 import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
019 import com.liferay.portal.kernel.dao.orm.Disjunction;
020 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
021 import com.liferay.portal.kernel.dao.orm.Property;
022 import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
023 import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
024 import com.liferay.portal.kernel.exception.PortalException;
025 import com.liferay.portal.kernel.exception.SystemException;
026 import com.liferay.portal.kernel.json.JSONArray;
027 import com.liferay.portal.kernel.json.JSONFactoryUtil;
028 import com.liferay.portal.kernel.json.JSONObject;
029 import com.liferay.portal.kernel.lar.DefaultConfigurationPortletDataHandler;
030 import com.liferay.portal.kernel.lar.ExportImportHelper;
031 import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
032 import com.liferay.portal.kernel.lar.ExportImportPathUtil;
033 import com.liferay.portal.kernel.lar.ManifestSummary;
034 import com.liferay.portal.kernel.lar.MissingReference;
035 import com.liferay.portal.kernel.lar.MissingReferences;
036 import com.liferay.portal.kernel.lar.PortletDataContext;
037 import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
038 import com.liferay.portal.kernel.lar.PortletDataHandler;
039 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
040 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
041 import com.liferay.portal.kernel.lar.StagedModelDataHandler;
042 import com.liferay.portal.kernel.lar.StagedModelDataHandlerRegistryUtil;
043 import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
044 import com.liferay.portal.kernel.lar.StagedModelType;
045 import com.liferay.portal.kernel.lar.UserIdStrategy;
046 import com.liferay.portal.kernel.log.Log;
047 import com.liferay.portal.kernel.log.LogFactoryUtil;
048 import com.liferay.portal.kernel.repository.model.FileEntry;
049 import com.liferay.portal.kernel.util.ArrayUtil;
050 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
051 import com.liferay.portal.kernel.util.CharPool;
052 import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
053 import com.liferay.portal.kernel.util.DateRange;
054 import com.liferay.portal.kernel.util.FileUtil;
055 import com.liferay.portal.kernel.util.GetterUtil;
056 import com.liferay.portal.kernel.util.HttpUtil;
057 import com.liferay.portal.kernel.util.LocaleUtil;
058 import com.liferay.portal.kernel.util.MapUtil;
059 import com.liferay.portal.kernel.util.ParamUtil;
060 import com.liferay.portal.kernel.util.StringBundler;
061 import com.liferay.portal.kernel.util.StringPool;
062 import com.liferay.portal.kernel.util.StringUtil;
063 import com.liferay.portal.kernel.util.TempFileUtil;
064 import com.liferay.portal.kernel.util.Time;
065 import com.liferay.portal.kernel.util.TimeZoneUtil;
066 import com.liferay.portal.kernel.util.Validator;
067 import com.liferay.portal.kernel.xml.Document;
068 import com.liferay.portal.kernel.xml.Element;
069 import com.liferay.portal.kernel.xml.ElementHandler;
070 import com.liferay.portal.kernel.xml.ElementProcessor;
071 import com.liferay.portal.kernel.zip.ZipReader;
072 import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
073 import com.liferay.portal.model.Company;
074 import com.liferay.portal.model.Group;
075 import com.liferay.portal.model.Layout;
076 import com.liferay.portal.model.LayoutFriendlyURL;
077 import com.liferay.portal.model.LayoutSet;
078 import com.liferay.portal.model.Organization;
079 import com.liferay.portal.model.Portlet;
080 import com.liferay.portal.model.PortletConstants;
081 import com.liferay.portal.model.StagedModel;
082 import com.liferay.portal.model.SystemEventConstants;
083 import com.liferay.portal.model.User;
084 import com.liferay.portal.service.CompanyLocalServiceUtil;
085 import com.liferay.portal.service.GroupLocalServiceUtil;
086 import com.liferay.portal.service.LayoutFriendlyURLLocalServiceUtil;
087 import com.liferay.portal.service.LayoutLocalServiceUtil;
088 import com.liferay.portal.service.LayoutServiceUtil;
089 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
090 import com.liferay.portal.service.OrganizationLocalServiceUtil;
091 import com.liferay.portal.service.PortletLocalServiceUtil;
092 import com.liferay.portal.service.UserLocalServiceUtil;
093 import com.liferay.portal.service.persistence.OrganizationUtil;
094 import com.liferay.portal.service.persistence.SystemEventActionableDynamicQuery;
095 import com.liferay.portal.theme.ThemeDisplay;
096 import com.liferay.portal.util.PortalUtil;
097 import com.liferay.portal.util.PortletKeys;
098 import com.liferay.portal.util.PropsValues;
099 import com.liferay.portal.util.WebKeys;
100 import com.liferay.portlet.PortletPreferencesFactoryUtil;
101 import com.liferay.portlet.asset.model.AssetCategory;
102 import com.liferay.portlet.asset.model.AssetVocabulary;
103 import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
104 import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil;
105 import com.liferay.portlet.asset.service.persistence.AssetCategoryUtil;
106 import com.liferay.portlet.asset.service.persistence.AssetVocabularyUtil;
107 import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
108 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
109 import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
110 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
111 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
112 import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeLocalServiceUtil;
113 import com.liferay.portlet.documentlibrary.service.persistence.DLFileEntryTypeUtil;
114 import com.liferay.portlet.documentlibrary.util.DLUtil;
115 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
116 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
117 import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMStructureUtil;
118 import com.liferay.portlet.journal.model.JournalArticle;
119
120 import java.io.File;
121 import java.io.InputStream;
122 import java.io.StringReader;
123
124 import java.util.ArrayList;
125 import java.util.Calendar;
126 import java.util.Date;
127 import java.util.HashMap;
128 import java.util.LinkedHashMap;
129 import java.util.List;
130 import java.util.Locale;
131 import java.util.Map;
132 import java.util.TimeZone;
133 import java.util.regex.Matcher;
134 import java.util.regex.Pattern;
135
136 import javax.portlet.PortletPreferences;
137 import javax.portlet.PortletRequest;
138
139 import org.apache.xerces.parsers.SAXParser;
140
141 import org.xml.sax.InputSource;
142
143
148 public class ExportImportHelperImpl implements ExportImportHelper {
149
150 @Override
151 public Calendar getCalendar(
152 PortletRequest portletRequest, String paramPrefix,
153 boolean timeZoneSensitive) {
154
155 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
156 WebKeys.THEME_DISPLAY);
157
158 int dateMonth = ParamUtil.getInteger(
159 portletRequest, paramPrefix + "Month");
160 int dateDay = ParamUtil.getInteger(portletRequest, paramPrefix + "Day");
161 int dateYear = ParamUtil.getInteger(
162 portletRequest, paramPrefix + "Year");
163 int dateHour = ParamUtil.getInteger(
164 portletRequest, paramPrefix + "Hour");
165 int dateMinute = ParamUtil.getInteger(
166 portletRequest, paramPrefix + "Minute");
167 int dateAmPm = ParamUtil.getInteger(
168 portletRequest, paramPrefix + "AmPm");
169
170 if (dateAmPm == Calendar.PM) {
171 dateHour += 12;
172 }
173
174 Locale locale = null;
175 TimeZone timeZone = null;
176
177 if (timeZoneSensitive) {
178 locale = themeDisplay.getLocale();
179 timeZone = themeDisplay.getTimeZone();
180 }
181 else {
182 locale = LocaleUtil.getDefault();
183 timeZone = TimeZoneUtil.getTimeZone(StringPool.UTC);
184 }
185
186 Calendar calendar = CalendarFactoryUtil.getCalendar(timeZone, locale);
187
188 calendar.set(Calendar.MONTH, dateMonth);
189 calendar.set(Calendar.DATE, dateDay);
190 calendar.set(Calendar.YEAR, dateYear);
191 calendar.set(Calendar.HOUR_OF_DAY, dateHour);
192 calendar.set(Calendar.MINUTE, dateMinute);
193 calendar.set(Calendar.SECOND, 0);
194 calendar.set(Calendar.MILLISECOND, 0);
195
196 return calendar;
197 }
198
199 @Override
200 public DateRange getDateRange(
201 PortletRequest portletRequest, long groupId, boolean privateLayout,
202 long plid, String portletId)
203 throws Exception {
204
205 Date startDate = null;
206 Date endDate = null;
207
208 String range = ParamUtil.getString(portletRequest, "range");
209
210 if (range.equals("dateRange")) {
211 Calendar startCalendar = getCalendar(
212 portletRequest, "startDate", true);
213
214 startDate = startCalendar.getTime();
215
216 Calendar endCalendar = getCalendar(portletRequest, "endDate", true);
217
218 endDate = endCalendar.getTime();
219 }
220 else if (range.equals("fromLastPublishDate")) {
221 if (Validator.isNotNull(portletId) && (plid > 0)) {
222 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
223
224 PortletPreferences preferences =
225 PortletPreferencesFactoryUtil.getPortletSetup(
226 layout, portletId, StringPool.BLANK);
227
228 long lastPublishDate = GetterUtil.getLong(
229 preferences.getValue(
230 "last-publish-date", StringPool.BLANK));
231
232 if (lastPublishDate > 0) {
233 endDate = new Date();
234
235 startDate = new Date(lastPublishDate);
236 }
237 }
238 else {
239 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
240 groupId, privateLayout);
241
242 long lastPublishDate = GetterUtil.getLong(
243 layoutSet.getSettingsProperty("last-publish-date"));
244
245 if (lastPublishDate > 0) {
246 endDate = new Date();
247
248 startDate = new Date(lastPublishDate);
249 }
250 }
251 }
252 else if (range.equals("last")) {
253 int rangeLast = ParamUtil.getInteger(portletRequest, "last");
254
255 Date now = new Date();
256
257 startDate = new Date(now.getTime() - (rangeLast * Time.HOUR));
258
259 endDate = now;
260 }
261
262 return new DateRange(startDate, endDate);
263 }
264
265 @Override
266 public Layout getExportableLayout(ThemeDisplay themeDisplay)
267 throws PortalException, SystemException {
268
269 Layout layout = themeDisplay.getLayout();
270
271 if (!layout.isTypeControlPanel()) {
272 return layout;
273 }
274
275 Group scopeGroup = themeDisplay.getScopeGroup();
276
277 if (scopeGroup.isLayout()) {
278 layout = LayoutLocalServiceUtil.getLayout(scopeGroup.getClassPK());
279 }
280 else if (!scopeGroup.isCompany()) {
281 long defaultPlid = LayoutLocalServiceUtil.getDefaultPlid(
282 themeDisplay.getSiteGroupId());
283
284 if (defaultPlid > 0) {
285 layout = LayoutLocalServiceUtil.getLayout(defaultPlid);
286 }
287 }
288
289 return layout;
290 }
291
292 @Override
293 public String getExportableRootPortletId(long companyId, String portletId)
294 throws Exception {
295
296 Portlet portlet = PortletLocalServiceUtil.getPortletById(
297 companyId, portletId);
298
299 if (portlet == null) {
300 return null;
301 }
302
303 String portletDataHandlerClass = portlet.getPortletDataHandlerClass();
304
305 if (portletDataHandlerClass == null) {
306 return null;
307 }
308
309 return PortletConstants.getRootPortletId(portletId);
310 }
311
312 @Override
313 public Map<Long, Boolean> getLayoutIdMap(PortletRequest portletRequest)
314 throws Exception {
315
316 Map<Long, Boolean> layoutIdMap = new LinkedHashMap<Long, Boolean>();
317
318 String layoutIdsJSON = ParamUtil.getString(portletRequest, "layoutIds");
319
320 if (Validator.isNull(layoutIdsJSON)) {
321 return layoutIdMap;
322 }
323
324 JSONArray jsonArray = JSONFactoryUtil.createJSONArray(layoutIdsJSON);
325
326 for (int i = 0; i < jsonArray.length(); ++i) {
327 JSONObject jsonObject = jsonArray.getJSONObject(i);
328
329 long plid = jsonObject.getLong("plid");
330 boolean includeChildren = jsonObject.getBoolean("includeChildren");
331
332 layoutIdMap.put(plid, includeChildren);
333 }
334
335 return layoutIdMap;
336 }
337
338 @Override
339 public long[] getLayoutIds(List<Layout> layouts) {
340 long[] layoutIds = new long[layouts.size()];
341
342 for (int i = 0; i < layouts.size(); i++) {
343 Layout layout = layouts.get(i);
344
345 layoutIds[i] = layout.getLayoutId();
346 }
347
348 return layoutIds;
349 }
350
351 @Override
352 public ManifestSummary getManifestSummary(
353 long userId, long groupId, Map<String, String[]> parameterMap,
354 File file)
355 throws Exception {
356
357 final Group group = GroupLocalServiceUtil.getGroup(groupId);
358 String userIdStrategy = MapUtil.getString(
359 parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
360 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
361
362 PortletDataContext portletDataContext =
363 PortletDataContextFactoryUtil.createImportPortletDataContext(
364 group.getCompanyId(), groupId, parameterMap,
365 getUserIdStrategy(userId, userIdStrategy), zipReader);
366
367 final ManifestSummary manifestSummary = new ManifestSummary();
368
369 SAXParser saxParser = new SAXParser();
370
371 ElementHandler elementHandler = new ElementHandler(
372 new ManifestSummaryElementProcessor(group, manifestSummary),
373 new String[] {"header", "portlet", "staged-model"});
374
375 saxParser.setContentHandler(elementHandler);
376
377 InputStream is = portletDataContext.getZipEntryAsInputStream(
378 "/manifest.xml");
379
380 if (is == null) {
381 throw new LARFileException("manifest.xml is not in the LAR");
382 }
383
384 String manifestXMLContent = StringUtil.read(is);
385
386 saxParser.parse(new InputSource(new StringReader(manifestXMLContent)));
387
388 return manifestSummary;
389 }
390
391 @Override
392 public ManifestSummary getManifestSummary(
393 long userId, long groupId, Map<String, String[]> parameterMap,
394 FileEntry fileEntry)
395 throws Exception {
396
397 File file = DLFileEntryLocalServiceUtil.getFile(
398 userId, fileEntry.getFileEntryId(), fileEntry.getVersion(), false);
399 File newFile = null;
400 boolean rename = false;
401
402 ManifestSummary manifestSummary = null;
403
404 try {
405 String newFileName = StringUtil.replace(
406 file.getPath(), file.getName(), fileEntry.getTitle());
407
408 newFile = new File(newFileName);
409
410 rename = file.renameTo(newFile);
411
412 if (!rename) {
413 newFile = FileUtil.createTempFile(fileEntry.getExtension());
414
415 FileUtil.copyFile(file, newFile);
416 }
417
418 manifestSummary = getManifestSummary(
419 userId, groupId, parameterMap, newFile);
420 }
421 finally {
422 if (rename) {
423 newFile.renameTo(file);
424 }
425 else {
426 FileUtil.delete(newFile);
427 }
428 }
429
430 return manifestSummary;
431 }
432
433 @Override
434 public long getModelDeletionCount(
435 final PortletDataContext portletDataContext,
436 final StagedModelType stagedModelType)
437 throws PortalException, SystemException {
438
439 ActionableDynamicQuery actionableDynamicQuery =
440 new SystemEventActionableDynamicQuery() {
441
442 protected void addCreateDateProperty(DynamicQuery dynamicQuery) {
443 if (!portletDataContext.hasDateRange()) {
444 return;
445 }
446
447 Property createDateProperty = PropertyFactoryUtil.forName(
448 "createDate");
449
450 Date startDate = portletDataContext.getStartDate();
451
452 dynamicQuery.add(createDateProperty.ge(startDate));
453
454 Date endDate = portletDataContext.getEndDate();
455
456 dynamicQuery.add(createDateProperty.le(endDate));
457 }
458
459 @Override
460 protected void addCriteria(DynamicQuery dynamicQuery) {
461 Disjunction disjunction = RestrictionsFactoryUtil.disjunction();
462
463 Property groupIdProperty = PropertyFactoryUtil.forName(
464 "groupId");
465
466 disjunction.add(groupIdProperty.eq(0L));
467 disjunction.add(
468 groupIdProperty.eq(portletDataContext.getScopeGroupId()));
469
470 dynamicQuery.add(disjunction);
471
472 Property classNameIdProperty = PropertyFactoryUtil.forName(
473 "classNameId");
474
475 dynamicQuery.add(
476 classNameIdProperty.eq(stagedModelType.getClassNameId()));
477
478 Property referrerClassNameIdProperty =
479 PropertyFactoryUtil.forName("referrerClassNameId");
480
481 dynamicQuery.add(
482 referrerClassNameIdProperty.eq(
483 stagedModelType.getReferrerClassNameId()));
484
485 Property typeProperty = PropertyFactoryUtil.forName("type");
486
487 dynamicQuery.add(
488 typeProperty.eq(SystemEventConstants.TYPE_DELETE));
489
490 addCreateDateProperty(dynamicQuery);
491 }
492
493 @Override
494 protected void performAction(Object object) {
495 }
496
497 };
498
499 actionableDynamicQuery.setCompanyId(portletDataContext.getCompanyId());
500
501 return actionableDynamicQuery.performCount();
502 }
503
504 @Override
505 public FileEntry getTempFileEntry(
506 long groupId, long userId, String folderName)
507 throws PortalException, SystemException {
508
509 String[] tempFileEntryNames = LayoutServiceUtil.getTempFileEntryNames(
510 groupId, folderName);
511
512 if (tempFileEntryNames.length == 0) {
513 return null;
514 }
515
516 return TempFileUtil.getTempFile(
517 groupId, userId, tempFileEntryNames[0], folderName);
518 }
519
520 @Override
521 public String replaceExportContentReferences(
522 PortletDataContext portletDataContext,
523 StagedModel entityStagedModel, Element entityElement,
524 String content, boolean exportReferencedContent)
525 throws Exception {
526
527 content = ExportImportHelperUtil.replaceExportLayoutReferences(
528 portletDataContext, content, exportReferencedContent);
529 content = ExportImportHelperUtil.replaceExportLinksToLayouts(
530 portletDataContext, entityStagedModel, entityElement, content,
531 exportReferencedContent);
532
533 content = ExportImportHelperUtil.replaceExportDLReferences(
534 portletDataContext, entityStagedModel, entityElement, content,
535 exportReferencedContent);
536
537 Element groupElement = entityElement.getParent();
538
539 String groupElementName = groupElement.getName();
540
541 if (!groupElementName.equals(JournalArticle.class.getSimpleName())) {
542 content = StringUtil.replace(
543 content, StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
544 }
545
546 return content;
547 }
548
549 @Override
550 public String replaceExportDLReferences(
551 PortletDataContext portletDataContext,
552 StagedModel entityStagedModel, Element entityElement,
553 String content, boolean exportReferencedContent)
554 throws Exception {
555
556 Group group = GroupLocalServiceUtil.getGroup(
557 portletDataContext.getGroupId());
558
559 if (group.isStagingGroup()) {
560 group = group.getLiveGroup();
561 }
562
563 if (group.isStaged() && !group.isStagedRemotely() &&
564 !group.isStagedPortlet(PortletKeys.DOCUMENT_LIBRARY)) {
565
566 return content;
567 }
568
569 StringBuilder sb = new StringBuilder(content);
570
571 String contextPath = PortalUtil.getPathContext();
572
573 String[] patterns = {
574 contextPath.concat("/c/document_library/get_file?"),
575 contextPath.concat("/documents/"),
576 contextPath.concat("/image/image_gallery?")
577 };
578
579 int beginPos = -1;
580 int endPos = content.length();
581
582 while (true) {
583 beginPos = StringUtil.lastIndexOfAny(content, patterns, endPos);
584
585 if (beginPos == -1) {
586 break;
587 }
588
589 Map<String, String[]> dlReferenceParameters =
590 getDLReferenceParameters(
591 portletDataContext, content,
592 beginPos + contextPath.length(), endPos);
593
594 FileEntry fileEntry = getFileEntry(
595 portletDataContext, dlReferenceParameters);
596
597 if (fileEntry == null) {
598 endPos = beginPos - 1;
599
600 continue;
601 }
602
603 endPos = MapUtil.getInteger(dlReferenceParameters, "endPos");
604
605 try {
606 if (exportReferencedContent) {
607 StagedModelDataHandlerUtil.exportReferenceStagedModel(
608 portletDataContext, entityStagedModel, entityElement,
609 fileEntry, FileEntry.class,
610 PortletDataContext.REFERENCE_TYPE_DEPENDENCY);
611 }
612 else {
613 portletDataContext.addReferenceElement(
614 entityStagedModel, entityElement, fileEntry,
615 FileEntry.class,
616 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
617 }
618
619 String path = ExportImportPathUtil.getModelPath(
620 fileEntry.getGroupId(), FileEntry.class.getName(),
621 fileEntry.getFileEntryId());
622
623 sb.replace(beginPos, endPos, "[$dl-reference=" + path + "$]");
624 }
625 catch (Exception e) {
626 if (_log.isDebugEnabled()) {
627 _log.debug(e, e);
628 }
629 else if (_log.isWarnEnabled()) {
630 _log.warn(e.getMessage());
631 }
632 }
633
634 endPos = beginPos - 1;
635 }
636
637 return sb.toString();
638 }
639
640 @Override
641 public String replaceExportLayoutReferences(
642 PortletDataContext portletDataContext, String content,
643 boolean exportReferencedContent)
644 throws Exception {
645
646 Group group = GroupLocalServiceUtil.getGroup(
647 portletDataContext.getScopeGroupId());
648
649 StringBuilder sb = new StringBuilder(content);
650
651 String[] patterns = {"href=", "[["};
652
653 int beginPos = -1;
654 int endPos = content.length();
655 int offset = 0;
656
657 while (true) {
658 if (beginPos > -1) {
659 endPos = beginPos - 1;
660 }
661
662 beginPos = StringUtil.lastIndexOfAny(content, patterns, endPos);
663
664 if (beginPos == -1) {
665 break;
666 }
667
668 if (content.startsWith("href=", beginPos)) {
669 offset = 5;
670
671 char c = content.charAt(beginPos + offset);
672
673 if ((c == CharPool.APOSTROPHE) || (c == CharPool.QUOTE)) {
674 offset++;
675 }
676 }
677 else if (content.charAt(beginPos) == CharPool.OPEN_BRACKET) {
678 offset = 2;
679 }
680
681 endPos = StringUtil.indexOfAny(
682 content, _LAYOUT_REFERENCE_STOP_CHARS, beginPos + offset,
683 endPos);
684
685 if (endPos == -1) {
686 continue;
687 }
688
689 String url = content.substring(beginPos + offset, endPos);
690
691 StringBundler urlSB = new StringBundler(5);
692
693 try {
694 url = replaceExportHostname(portletDataContext, url, urlSB);
695
696 if (!url.startsWith(StringPool.SLASH)) {
697 continue;
698 }
699
700 String pathContext = PortalUtil.getPathContext();
701
702 if (pathContext.length() > 1) {
703 if (!url.startsWith(pathContext)) {
704 continue;
705 }
706
707 urlSB.append(DATA_HANDLER_PATH_CONTEXT);
708
709 url = url.substring(pathContext.length());
710 }
711
712 if (!url.startsWith(StringPool.SLASH)) {
713 continue;
714 }
715
716 int pos = url.indexOf(StringPool.SLASH, 1);
717
718 String localePath = StringPool.BLANK;
719
720 Locale locale = null;
721
722 if (pos != -1) {
723 localePath = url.substring(0, pos);
724
725 locale = LocaleUtil.fromLanguageId(
726 localePath.substring(1), true, false);
727 }
728
729 if (locale != null) {
730 String urlWithoutLocale = url.substring(
731 localePath.length());
732
733 if (urlWithoutLocale.startsWith(
734 _PRIVATE_GROUP_SERVLET_MAPPING) ||
735 urlWithoutLocale.startsWith(
736 _PRIVATE_USER_SERVLET_MAPPING) ||
737 urlWithoutLocale.startsWith(
738 _PUBLIC_GROUP_SERVLET_MAPPING)) {
739
740 urlSB.append(localePath);
741
742 url = urlWithoutLocale;
743 }
744 }
745
746 if (url.startsWith(_PRIVATE_GROUP_SERVLET_MAPPING)) {
747 urlSB.append(DATA_HANDLER_PRIVATE_GROUP_SERVLET_MAPPING);
748
749 url = url.substring(
750 _PRIVATE_GROUP_SERVLET_MAPPING.length() - 1);
751 }
752 else if (url.startsWith(_PRIVATE_USER_SERVLET_MAPPING)) {
753 urlSB.append(DATA_HANDLER_PRIVATE_USER_SERVLET_MAPPING);
754
755 url = url.substring(
756 _PRIVATE_USER_SERVLET_MAPPING.length() - 1);
757 }
758 else if (url.startsWith(_PUBLIC_GROUP_SERVLET_MAPPING)) {
759 urlSB.append(DATA_HANDLER_PUBLIC_SERVLET_MAPPING);
760
761 url = url.substring(
762 _PUBLIC_GROUP_SERVLET_MAPPING.length() - 1);
763 }
764 else {
765 String urlSBString = urlSB.toString();
766
767 LayoutSet layoutSet = null;
768
769 if (urlSBString.contains(
770 DATA_HANDLER_PUBLIC_LAYOUT_SET_SECURE_URL) ||
771 urlSBString.contains(
772 DATA_HANDLER_PUBLIC_LAYOUT_SET_URL)) {
773
774 layoutSet = group.getPublicLayoutSet();
775 }
776 else if (urlSBString.contains(
777 DATA_HANDLER_PRIVATE_LAYOUT_SET_SECURE_URL) ||
778 urlSBString.contains(
779 DATA_HANDLER_PRIVATE_LAYOUT_SET_URL)) {
780
781 layoutSet = group.getPrivateLayoutSet();
782 }
783
784 if (layoutSet == null) {
785 continue;
786 }
787
788 boolean privateLayout = layoutSet.isPrivateLayout();
789
790 LayoutFriendlyURL layoutFriendlyUrl =
791 LayoutFriendlyURLLocalServiceUtil.
792 fetchFirstLayoutFriendlyURL(
793 group.getGroupId(), privateLayout, url);
794
795 if (layoutFriendlyUrl == null) {
796 continue;
797 }
798
799 if (privateLayout) {
800 if (group.isUser()) {
801 urlSB.append(
802 DATA_HANDLER_PRIVATE_USER_SERVLET_MAPPING);
803 }
804 else {
805 urlSB.append(
806 DATA_HANDLER_PRIVATE_GROUP_SERVLET_MAPPING);
807 }
808 }
809 else {
810 urlSB.append(DATA_HANDLER_PUBLIC_SERVLET_MAPPING);
811 }
812
813 urlSB.append(DATA_HANDLER_GROUP_FRIENDLY_URL);
814
815 continue;
816 }
817
818 String groupFriendlyURL = group.getFriendlyURL();
819
820 if (url.equals(groupFriendlyURL) ||
821 url.startsWith(groupFriendlyURL + StringPool.SLASH)) {
822
823 urlSB.append(DATA_HANDLER_GROUP_FRIENDLY_URL);
824
825 url = url.substring(groupFriendlyURL.length());
826 }
827 }
828 finally {
829 if (urlSB.length() > 0) {
830 urlSB.append(url);
831
832 url = urlSB.toString();
833 }
834
835 sb.replace(beginPos + offset, endPos, url);
836 }
837 }
838
839 return sb.toString();
840 }
841
842 @Override
843 public String replaceExportLinksToLayouts(
844 PortletDataContext portletDataContext,
845 StagedModel entityStagedModel, Element entityElement,
846 String content, boolean exportReferencedContent)
847 throws Exception {
848
849 List<String> oldLinksToLayout = new ArrayList<String>();
850 List<String> newLinksToLayout = new ArrayList<String>();
851
852 Matcher matcher = _exportLinksToLayoutPattern.matcher(content);
853
854 while (matcher.find()) {
855 long layoutId = GetterUtil.getLong(matcher.group(1));
856
857 String type = matcher.group(2);
858
859 boolean privateLayout = type.startsWith("private");
860
861 try {
862 Layout layout = LayoutLocalServiceUtil.getLayout(
863 portletDataContext.getScopeGroupId(), privateLayout,
864 layoutId);
865
866 String oldLinkToLayout = matcher.group(0);
867
868 StringBundler sb = new StringBundler(5);
869
870 sb.append(type);
871 sb.append(StringPool.AT);
872 sb.append(layout.getUuid());
873 sb.append(StringPool.AT);
874 sb.append(layout.getFriendlyURL());
875
876 String newLinkToLayout = StringUtil.replace(
877 oldLinkToLayout, type, sb.toString());
878
879 oldLinksToLayout.add(oldLinkToLayout);
880 newLinksToLayout.add(newLinkToLayout);
881
882 if (exportReferencedContent) {
883 StagedModelDataHandlerUtil.exportReferenceStagedModel(
884 portletDataContext, entityStagedModel, layout,
885 PortletDataContext.REFERENCE_TYPE_DEPENDENCY);
886 }
887 else {
888 portletDataContext.addReferenceElement(
889 entityStagedModel, entityElement, layout,
890 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
891 }
892 }
893 catch (Exception e) {
894 if (_log.isDebugEnabled() || _log.isWarnEnabled()) {
895 String message =
896 "Unable to get layout with ID " + layoutId +
897 " in group " + portletDataContext.getScopeGroupId();
898
899 if (_log.isWarnEnabled()) {
900 _log.warn(message);
901 }
902 else {
903 _log.debug(message, e);
904 }
905 }
906 }
907 }
908
909 content = StringUtil.replace(
910 content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
911 ArrayUtil.toStringArray(newLinksToLayout.toArray()));
912
913 return content;
914 }
915
916 @Override
917 public String replaceImportContentReferences(
918 PortletDataContext portletDataContext, Element entityElement,
919 String content, boolean importReferencedContent)
920 throws Exception {
921
922 content = ExportImportHelperUtil.replaceImportLayoutReferences(
923 portletDataContext, content, importReferencedContent);
924 content = ExportImportHelperUtil.replaceImportLinksToLayouts(
925 portletDataContext, content, importReferencedContent);
926
927 content = ExportImportHelperUtil.replaceImportDLReferences(
928 portletDataContext, entityElement, content,
929 importReferencedContent);
930
931 return content;
932 }
933
934 @Override
935 public String replaceImportDLReferences(
936 PortletDataContext portletDataContext, Element entityElement,
937 String content, boolean importReferencedContent)
938 throws Exception {
939
940 List<Element> referenceDataElements =
941 portletDataContext.getReferenceDataElements(
942 entityElement, FileEntry.class,
943 PortletDataContext.REFERENCE_TYPE_DEPENDENCY);
944
945 for (Element referenceDataElement : referenceDataElements) {
946 String fileEntryUUID = referenceDataElement.attributeValue("uuid");
947
948 if (fileEntryUUID == null) {
949 continue;
950 }
951
952 String path = referenceDataElement.attributeValue("path");
953
954 if (!content.contains("[$dl-reference=" + path + "$]")) {
955 continue;
956 }
957
958 FileEntry fileEntry =
959 (FileEntry)portletDataContext.getZipEntryAsObject(path);
960
961 StagedModelDataHandlerUtil.importStagedModel(
962 portletDataContext, fileEntry);
963
964 Map<Long, Long> fileEntryIds =
965 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
966 DLFileEntry.class);
967
968 long importedFileEntryId = MapUtil.getLong(
969 fileEntryIds, fileEntry.getFileEntryId(),
970 fileEntry.getFileEntryId());
971
972 FileEntry importedFileEntry = null;
973
974 try {
975 importedFileEntry = DLAppLocalServiceUtil.getFileEntry(
976 importedFileEntryId);
977 }
978 catch (NoSuchFileEntryException nsfee) {
979 if (_log.isWarnEnabled()) {
980 _log.warn("Unable to reference " + path);
981 }
982
983 continue;
984 }
985
986 String url = DLUtil.getPreviewURL(
987 importedFileEntry, importedFileEntry.getFileVersion(), null,
988 StringPool.BLANK, false, false);
989
990 content = StringUtil.replace(
991 content, "[$dl-reference=" + path + "$]", url);
992 }
993
994 return content;
995 }
996
997 @Override
998 public String replaceImportLayoutReferences(
999 PortletDataContext portletDataContext, String content,
1000 boolean importReferencedContent)
1001 throws Exception {
1002
1003 String companyPortalURL = StringPool.BLANK;
1004 String privateLayoutSetPortalURL = StringPool.BLANK;
1005 String publicLayoutSetPortalURL = StringPool.BLANK;
1006
1007 Group group = GroupLocalServiceUtil.getGroup(
1008 portletDataContext.getScopeGroupId());
1009
1010 Company company = CompanyLocalServiceUtil.getCompany(
1011 group.getCompanyId());
1012
1013 LayoutSet privateLayoutSet = group.getPrivateLayoutSet();
1014 LayoutSet publicLayoutSet = group.getPublicLayoutSet();
1015
1016 int portalPort = PortalUtil.getPortalPort(false);
1017
1018 if (portalPort != -1) {
1019 if (Validator.isNotNull(company.getVirtualHostname())) {
1020 companyPortalURL = PortalUtil.getPortalURL(
1021 company.getVirtualHostname(), portalPort, false);
1022 }
1023
1024 if (Validator.isNotNull(privateLayoutSet.getVirtualHostname())) {
1025 privateLayoutSetPortalURL = PortalUtil.getPortalURL(
1026 privateLayoutSet.getVirtualHostname(), portalPort, false);
1027 }
1028
1029 if (Validator.isNotNull(publicLayoutSet.getVirtualHostname())) {
1030 publicLayoutSetPortalURL = PortalUtil.getPortalURL(
1031 publicLayoutSet.getVirtualHostname(), portalPort, false);
1032 }
1033 }
1034
1035 int securePortalPort = PortalUtil.getPortalPort(true);
1036
1037 String companySecurePortalURL = StringPool.BLANK;
1038 String privateLayoutSetSecurePortalURL = StringPool.BLANK;
1039 String publicLayoutSetSecurePortalURL = StringPool.BLANK;
1040
1041 if (securePortalPort != -1) {
1042 if (Validator.isNotNull(company.getVirtualHostname())) {
1043 companySecurePortalURL = PortalUtil.getPortalURL(
1044 company.getVirtualHostname(), securePortalPort, true);
1045 }
1046
1047 if (Validator.isNotNull(privateLayoutSet.getVirtualHostname())) {
1048 privateLayoutSetSecurePortalURL = PortalUtil.getPortalURL(
1049 privateLayoutSet.getVirtualHostname(), securePortalPort,
1050 true);
1051 }
1052
1053 if (Validator.isNotNull(publicLayoutSet.getVirtualHostname())) {
1054 publicLayoutSetSecurePortalURL = PortalUtil.getPortalURL(
1055 publicLayoutSet.getVirtualHostname(), securePortalPort,
1056 true);
1057 }
1058 }
1059
1060 content = StringUtil.replace(
1061 content, DATA_HANDLER_COMPANY_SECURE_URL, companySecurePortalURL);
1062 content = StringUtil.replace(
1063 content, DATA_HANDLER_COMPANY_URL, companyPortalURL);
1064 content = StringUtil.replace(
1065 content, DATA_HANDLER_GROUP_FRIENDLY_URL, group.getFriendlyURL());
1066 content = StringUtil.replace(
1067 content, DATA_HANDLER_PATH_CONTEXT, PortalUtil.getPathContext());
1068 content = StringUtil.replace(
1069 content, DATA_HANDLER_PRIVATE_GROUP_SERVLET_MAPPING,
1070 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING);
1071 content = StringUtil.replace(
1072 content, DATA_HANDLER_PRIVATE_LAYOUT_SET_SECURE_URL,
1073 privateLayoutSetSecurePortalURL);
1074 content = StringUtil.replace(
1075 content, DATA_HANDLER_PRIVATE_LAYOUT_SET_URL,
1076 privateLayoutSetPortalURL);
1077 content = StringUtil.replace(
1078 content, DATA_HANDLER_PRIVATE_USER_SERVLET_MAPPING,
1079 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING);
1080 content = StringUtil.replace(
1081 content, DATA_HANDLER_PUBLIC_LAYOUT_SET_SECURE_URL,
1082 publicLayoutSetSecurePortalURL);
1083 content = StringUtil.replace(
1084 content, DATA_HANDLER_PUBLIC_LAYOUT_SET_URL,
1085 publicLayoutSetPortalURL);
1086 content = StringUtil.replace(
1087 content, DATA_HANDLER_PUBLIC_SERVLET_MAPPING,
1088 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING);
1089
1090 return content;
1091 }
1092
1093 @Override
1094 public String replaceImportLinksToLayouts(
1095 PortletDataContext portletDataContext, String content,
1096 boolean importReferencedContent)
1097 throws Exception {
1098
1099 List<String> oldLinksToLayout = new ArrayList<String>();
1100 List<String> newLinksToLayout = new ArrayList<String>();
1101
1102 Matcher matcher = _importLinksToLayoutPattern.matcher(content);
1103
1104 while (matcher.find()) {
1105 long oldLayoutId = GetterUtil.getLong(matcher.group(1));
1106
1107 long newLayoutId = oldLayoutId;
1108
1109 String type = matcher.group(2);
1110
1111 boolean privateLayout = type.startsWith("private");
1112
1113 String layoutUuid = matcher.group(3);
1114 String friendlyURL = matcher.group(4);
1115
1116 try {
1117 Layout layout =
1118 LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
1119 layoutUuid, portletDataContext.getScopeGroupId(),
1120 privateLayout);
1121
1122 if (layout == null) {
1123 layout = LayoutLocalServiceUtil.fetchLayoutByFriendlyURL(
1124 portletDataContext.getScopeGroupId(), privateLayout,
1125 friendlyURL);
1126 }
1127
1128 if (layout == null) {
1129 layout = LayoutLocalServiceUtil.fetchLayout(
1130 portletDataContext.getScopeGroupId(), privateLayout,
1131 oldLayoutId);
1132 }
1133
1134 if (layout == null) {
1135 if (_log.isWarnEnabled()) {
1136 StringBundler sb = new StringBundler(9);
1137
1138 sb.append("Unable to get layout with UUID ");
1139 sb.append(layoutUuid);
1140 sb.append(", friendly URL ");
1141 sb.append(friendlyURL);
1142 sb.append(", or ");
1143 sb.append("layoutId ");
1144 sb.append(oldLayoutId);
1145 sb.append(" in group ");
1146 sb.append(portletDataContext.getScopeGroupId());
1147
1148 _log.warn(sb.toString());
1149 }
1150 }
1151 else {
1152 newLayoutId = layout.getLayoutId();
1153 }
1154 }
1155 catch (SystemException se) {
1156 if (_log.isDebugEnabled() || _log.isWarnEnabled()) {
1157 String message =
1158 "Unable to get layout in group " +
1159 portletDataContext.getScopeGroupId();
1160
1161 if (_log.isWarnEnabled()) {
1162 _log.warn(message);
1163 }
1164 else {
1165 _log.debug(message, se);
1166 }
1167 }
1168 }
1169
1170 String oldLinkToLayout = matcher.group(0);
1171
1172 StringBundler sb = new StringBundler(4);
1173
1174 sb.append(StringPool.AT);
1175 sb.append(layoutUuid);
1176 sb.append(StringPool.AT);
1177 sb.append(friendlyURL);
1178
1179 String newLinkToLayout = StringUtil.replace(
1180 oldLinkToLayout,
1181 new String[] {sb.toString(), String.valueOf(oldLayoutId)},
1182 new String[] {StringPool.BLANK, String.valueOf(newLayoutId)});
1183
1184 oldLinksToLayout.add(oldLinkToLayout);
1185 newLinksToLayout.add(newLinkToLayout);
1186 }
1187
1188 content = StringUtil.replace(
1189 content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
1190 ArrayUtil.toStringArray(newLinksToLayout.toArray()));
1191
1192 return content;
1193 }
1194
1195 @Override
1196 public void updateExportPortletPreferencesClassPKs(
1197 PortletDataContext portletDataContext, Portlet portlet,
1198 PortletPreferences portletPreferences, String key, String className,
1199 Element rootElement)
1200 throws Exception {
1201
1202 String[] oldValues = portletPreferences.getValues(key, null);
1203
1204 if (oldValues == null) {
1205 return;
1206 }
1207
1208 String[] newValues = new String[oldValues.length];
1209
1210 for (int i = 0; i < oldValues.length; i++) {
1211 String oldValue = oldValues[i];
1212
1213 String newValue = oldValue;
1214
1215 String[] primaryKeys = StringUtil.split(oldValue);
1216
1217 for (String primaryKey : primaryKeys) {
1218 if (!Validator.isNumber(primaryKey)) {
1219 break;
1220 }
1221
1222 long primaryKeyLong = GetterUtil.getLong(primaryKey);
1223
1224 String uuid = null;
1225
1226 if (className.equals(AssetCategory.class.getName())) {
1227 AssetCategory assetCategory =
1228 AssetCategoryLocalServiceUtil.fetchCategory(
1229 primaryKeyLong);
1230
1231 if (assetCategory != null) {
1232 uuid = assetCategory.getUuid();
1233
1234 portletDataContext.addReferenceElement(
1235 portlet, rootElement, assetCategory,
1236 AssetCategory.class,
1237 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
1238 }
1239 }
1240 else if (className.equals(AssetVocabulary.class.getName())) {
1241 AssetVocabulary assetVocabulary =
1242 AssetVocabularyLocalServiceUtil.fetchAssetVocabulary(
1243 primaryKeyLong);
1244
1245 if (assetVocabulary != null) {
1246 uuid = assetVocabulary.getUuid();
1247
1248 portletDataContext.addReferenceElement(
1249 portlet, rootElement, assetVocabulary,
1250 AssetVocabulary.class,
1251 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
1252 }
1253 }
1254 else if (className.equals(DDMStructure.class.getName())) {
1255 DDMStructure ddmStructure =
1256 DDMStructureLocalServiceUtil.fetchStructure(
1257 primaryKeyLong);
1258
1259 if (ddmStructure != null) {
1260 uuid = ddmStructure.getUuid();
1261
1262 portletDataContext.addReferenceElement(
1263 portlet, rootElement, ddmStructure,
1264 DDMStructure.class,
1265 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
1266 }
1267 }
1268 else if (className.equals(DLFileEntryType.class.getName())) {
1269 DLFileEntryType dlFileEntryType =
1270 DLFileEntryTypeLocalServiceUtil.fetchFileEntryType(
1271 primaryKeyLong);
1272
1273 if (dlFileEntryType != null) {
1274 uuid = dlFileEntryType.getUuid();
1275
1276 portletDataContext.addReferenceElement(
1277 portlet, rootElement, dlFileEntryType,
1278 DLFileEntryType.class,
1279 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
1280 }
1281 }
1282 else if (className.equals(Organization.class.getName())) {
1283 Organization organization =
1284 OrganizationLocalServiceUtil.fetchOrganization(
1285 primaryKeyLong);
1286
1287 if (organization != null) {
1288 uuid = organization.getUuid();
1289
1290 portletDataContext.addReferenceElement(
1291 portlet, rootElement, organization,
1292 Organization.class,
1293 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
1294 }
1295 }
1296
1297 if (Validator.isNull(uuid)) {
1298 if (_log.isWarnEnabled()) {
1299 _log.warn(
1300 "Unable to get UUID for class " + className +
1301 " with primary key " + primaryKeyLong);
1302 }
1303
1304 continue;
1305 }
1306
1307 newValue = StringUtil.replace(newValue, primaryKey, uuid);
1308 }
1309
1310 newValues[i] = newValue;
1311 }
1312
1313 portletPreferences.setValues(key, newValues);
1314 }
1315
1316 @Override
1317 public void updateImportPortletPreferencesClassPKs(
1318 PortletDataContext portletDataContext,
1319 PortletPreferences portletPreferences, String key, Class<?> clazz,
1320 long companyGroupId)
1321 throws Exception {
1322
1323 String[] oldValues = portletPreferences.getValues(key, null);
1324
1325 if (oldValues == null) {
1326 return;
1327 }
1328
1329 Map<Long, Long> primaryKeys =
1330 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(clazz);
1331
1332 String[] newValues = new String[oldValues.length];
1333
1334 for (int i = 0; i < oldValues.length; i++) {
1335 String oldValue = oldValues[i];
1336
1337 String newValue = oldValue;
1338
1339 String[] uuids = StringUtil.split(oldValue);
1340
1341 for (String uuid : uuids) {
1342 Long newPrimaryKey = null;
1343
1344 if (Validator.isNumber(uuid)) {
1345 long oldPrimaryKey = GetterUtil.getLong(uuid);
1346
1347 newPrimaryKey = MapUtil.getLong(
1348 primaryKeys, oldPrimaryKey, oldPrimaryKey);
1349 }
1350 else {
1351 String className = clazz.getName();
1352
1353 if (className.equals(AssetCategory.class.getName())) {
1354 AssetCategory assetCategory =
1355 AssetCategoryUtil.fetchByUUID_G(
1356 uuid, portletDataContext.getScopeGroupId());
1357
1358 if (assetCategory == null) {
1359 assetCategory = AssetCategoryUtil.fetchByUUID_G(
1360 uuid, companyGroupId);
1361 }
1362
1363 if (assetCategory != null) {
1364 newPrimaryKey = assetCategory.getCategoryId();
1365 }
1366 }
1367 else if (className.equals(
1368 AssetVocabulary.class.getName())) {
1369
1370 AssetVocabulary assetVocabulary =
1371 AssetVocabularyUtil.fetchByUUID_G(
1372 uuid, portletDataContext.getScopeGroupId());
1373
1374 if (assetVocabulary == null) {
1375 assetVocabulary = AssetVocabularyUtil.fetchByUUID_G(
1376 uuid, companyGroupId);
1377 }
1378
1379 if (assetVocabulary != null) {
1380 newPrimaryKey = assetVocabulary.getVocabularyId();
1381 }
1382 }
1383 else if (className.equals(DDMStructure.class.getName())) {
1384 DDMStructure ddmStructure =
1385 DDMStructureUtil.fetchByUUID_G(
1386 uuid, portletDataContext.getScopeGroupId());
1387
1388 if (ddmStructure == null) {
1389 ddmStructure = DDMStructureUtil.fetchByUUID_G(
1390 uuid, companyGroupId);
1391 }
1392
1393 if (ddmStructure != null) {
1394 newPrimaryKey = ddmStructure.getStructureId();
1395 }
1396 }
1397 else if (className.equals(
1398 DLFileEntryType.class.getName())) {
1399
1400 DLFileEntryType dlFileEntryType =
1401 DLFileEntryTypeUtil.fetchByUUID_G(
1402 uuid, portletDataContext.getScopeGroupId());
1403
1404 if (dlFileEntryType == null) {
1405 dlFileEntryType = DLFileEntryTypeUtil.fetchByUUID_G(
1406 uuid, companyGroupId);
1407 }
1408
1409 if (dlFileEntryType != null) {
1410 newPrimaryKey =
1411 dlFileEntryType.getFileEntryTypeId();
1412 }
1413 }
1414 else if (className.equals(Organization.class.getName())) {
1415 Organization organization =
1416 OrganizationUtil.fetchByUuid_C_First(
1417 uuid, portletDataContext.getCompanyId(), null);
1418
1419 if (organization != null) {
1420 newPrimaryKey = organization.getOrganizationId();
1421 }
1422 }
1423 }
1424
1425 if (Validator.isNull(newPrimaryKey)) {
1426 if (_log.isWarnEnabled()) {
1427 StringBundler sb = new StringBundler(8);
1428
1429 sb.append("Unable to get primary key for ");
1430 sb.append(clazz);
1431 sb.append(" with UUID ");
1432 sb.append(uuid);
1433 sb.append(" in company group ");
1434 sb.append(companyGroupId);
1435 sb.append(" or in group ");
1436 sb.append(portletDataContext.getScopeGroupId());
1437
1438 _log.warn(sb.toString());
1439 }
1440 }
1441 else {
1442 newValue = StringUtil.replace(
1443 newValue, uuid, newPrimaryKey.toString());
1444 }
1445 }
1446
1447 newValues[i] = newValue;
1448 }
1449
1450 portletPreferences.setValues(key, newValues);
1451 }
1452
1453 @Override
1454 public MissingReferences validateMissingReferences(
1455 long userId, long groupId, Map<String, String[]> parameterMap,
1456 File file)
1457 throws Exception {
1458
1459 final MissingReferences missingReferences = new MissingReferences();
1460
1461 Group group = GroupLocalServiceUtil.getGroup(groupId);
1462 String userIdStrategy = MapUtil.getString(
1463 parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
1464 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
1465
1466 final PortletDataContext portletDataContext =
1467 PortletDataContextFactoryUtil.createImportPortletDataContext(
1468 group.getCompanyId(), groupId, parameterMap,
1469 getUserIdStrategy(userId, userIdStrategy), zipReader);
1470
1471 SAXParser saxParser = new SAXParser();
1472
1473 ElementHandler elementHandler = new ElementHandler(
1474 new ElementProcessor() {
1475
1476 @Override
1477 public void processElement(Element element) {
1478 MissingReference missingReference =
1479 validateMissingReference(portletDataContext, element);
1480
1481 if (missingReference != null) {
1482 missingReferences.add(missingReference);
1483 }
1484 }
1485
1486 },
1487 new String[] {"missing-reference"});
1488
1489 saxParser.setContentHandler(elementHandler);
1490
1491 saxParser.parse(
1492 new InputSource(
1493 portletDataContext.getZipEntryAsInputStream("/manifest.xml")));
1494
1495 return missingReferences;
1496 }
1497
1498 @Override
1499 public void writeManifestSummary(
1500 Document document, ManifestSummary manifestSummary) {
1501
1502 Element rootElement = document.getRootElement();
1503
1504 Element manifestSummaryElement = rootElement.addElement(
1505 "manifest-summary");
1506
1507 for (String manifestSummaryKey :
1508 manifestSummary.getManifestSummaryKeys()) {
1509
1510 Element element = manifestSummaryElement.addElement("staged-model");
1511
1512 element.addAttribute("manifest-summary-key", manifestSummaryKey);
1513
1514 long modelAdditionCount = manifestSummary.getModelAdditionCount(
1515 manifestSummaryKey);
1516
1517 if (modelAdditionCount > 0) {
1518 element.addAttribute(
1519 "addition-count", String.valueOf(modelAdditionCount));
1520 }
1521
1522 long modelDeletionCount = manifestSummary.getModelDeletionCount(
1523 manifestSummaryKey);
1524
1525 if (modelDeletionCount > 0) {
1526 element.addAttribute(
1527 "deletion-count", String.valueOf(modelDeletionCount));
1528 }
1529 }
1530 }
1531
1532 protected Map<String, String[]> getDLReferenceParameters(
1533 PortletDataContext portletDataContext, String content, int beginPos,
1534 int endPos) {
1535
1536 boolean legacyURL = true;
1537 char[] stopChars = _DL_REFERENCE_LEGACY_STOP_CHARS;
1538
1539 if (content.startsWith("/documents/", beginPos)) {
1540 legacyURL = false;
1541 stopChars = _DL_REFERENCE_STOP_CHARS;
1542 }
1543
1544 endPos = StringUtil.indexOfAny(content, stopChars, beginPos, endPos);
1545
1546 if (endPos == -1) {
1547 return null;
1548 }
1549
1550 Map<String, String[]> map = new HashMap<String, String[]>();
1551
1552 String dlReference = content.substring(beginPos, endPos);
1553
1554 while (dlReference.contains(StringPool.AMPERSAND_ENCODED)) {
1555 dlReference = dlReference.replace(
1556 StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
1557 }
1558
1559 if (!legacyURL) {
1560 String[] pathArray = dlReference.split(StringPool.SLASH);
1561
1562 map.put("groupId", new String[] {pathArray[2]});
1563
1564 if (pathArray.length == 4) {
1565 map.put("uuid", new String[] {pathArray[3]});
1566 }
1567 else if (pathArray.length == 5) {
1568 map.put("folderId", new String[] {pathArray[3]});
1569 map.put(
1570 "title", new String[] {HttpUtil.decodeURL(pathArray[4])});
1571 }
1572 else if (pathArray.length > 5) {
1573 map.put("uuid", new String[] {pathArray[5]});
1574 }
1575 }
1576 else {
1577 dlReference = dlReference.substring(
1578 dlReference.indexOf(CharPool.QUESTION) + 1);
1579
1580 map = HttpUtil.parameterMapFromString(dlReference);
1581
1582 if (map.containsKey("img_id")) {
1583 map.put("image_id", map.get("img_id"));
1584 }
1585 else if (map.containsKey("i_id")) {
1586 map.put("image_id", map.get("i_id"));
1587 }
1588 }
1589
1590 map.put("endPos", new String[] {String.valueOf(endPos)});
1591
1592 String groupIdString = MapUtil.getString(map, "groupId");
1593
1594 if (groupIdString.equals("@group_id@")) {
1595 groupIdString = String.valueOf(
1596 portletDataContext.getScopeGroupId());
1597
1598 map.put("groupId", new String[] {groupIdString});
1599 }
1600
1601 return map;
1602 }
1603
1604 protected FileEntry getFileEntry(
1605 PortletDataContext portletDataContext, Map<String, String[]> map) {
1606
1607 if (map == null) {
1608 return null;
1609 }
1610
1611 FileEntry fileEntry = null;
1612
1613 try {
1614 String uuid = MapUtil.getString(map, "uuid");
1615 long groupId = MapUtil.getLong(map, "groupId");
1616
1617 if (Validator.isNotNull(uuid)) {
1618 fileEntry =
1619 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1620 uuid, groupId);
1621 }
1622 else {
1623 if (map.containsKey("folderId")) {
1624 long folderId = MapUtil.getLong(map, "folderId");
1625 String name = MapUtil.getString(map, "name");
1626 String title = MapUtil.getString(map, "title");
1627
1628 if (Validator.isNotNull(title)) {
1629 fileEntry = DLAppLocalServiceUtil.getFileEntry(
1630 groupId, folderId, title);
1631 }
1632 else {
1633 DLFileEntry dlFileEntry =
1634 DLFileEntryLocalServiceUtil.fetchFileEntryByName(
1635 groupId, folderId, name);
1636
1637 if (dlFileEntry != null) {
1638 fileEntry = DLAppLocalServiceUtil.getFileEntry(
1639 dlFileEntry.getFileEntryId());
1640 }
1641 }
1642 }
1643 else if (map.containsKey("image_id")) {
1644 DLFileEntry dlFileEntry =
1645 DLFileEntryLocalServiceUtil.fetchFileEntryByAnyImageId(
1646 MapUtil.getLong(map, "image_id"));
1647
1648 if (dlFileEntry != null) {
1649 fileEntry = DLAppLocalServiceUtil.getFileEntry(
1650 dlFileEntry.getFileEntryId());
1651 }
1652 }
1653 }
1654 }
1655 catch (Exception e) {
1656 if (_log.isDebugEnabled()) {
1657 _log.debug(e, e);
1658 }
1659 else if (_log.isWarnEnabled()) {
1660 _log.warn(e.getMessage());
1661 }
1662 }
1663
1664 return fileEntry;
1665 }
1666
1667 protected UserIdStrategy getUserIdStrategy(
1668 long userId, String userIdStrategy)
1669 throws Exception {
1670
1671 User user = UserLocalServiceUtil.getUserById(userId);
1672
1673 if (UserIdStrategy.ALWAYS_CURRENT_USER_ID.equals(userIdStrategy)) {
1674 return new AlwaysCurrentUserIdStrategy(user);
1675 }
1676
1677 return new CurrentUserIdStrategy(user);
1678 }
1679
1680 protected String replaceExportHostname(
1681 PortletDataContext portletDataContext, String url,
1682 StringBundler urlSB)
1683 throws PortalException, SystemException {
1684
1685 Group group = GroupLocalServiceUtil.getGroup(
1686 portletDataContext.getScopeGroupId());
1687
1688 if (!HttpUtil.hasProtocol(url) || !group.isStagingGroup()) {
1689 return url;
1690 }
1691
1692 boolean secure = HttpUtil.isSecure(url);
1693
1694 int portalPort = PortalUtil.getPortalPort(secure);
1695
1696 if (portalPort == -1) {
1697 return url;
1698 }
1699
1700 LayoutSet publicLayoutSet = group.getPublicLayoutSet();
1701
1702 String publicLayoutSetVirtualHostname =
1703 publicLayoutSet.getVirtualHostname();
1704
1705 String portalUrl = StringPool.BLANK;
1706
1707 if (Validator.isNotNull(publicLayoutSetVirtualHostname)) {
1708 portalUrl = PortalUtil.getPortalURL(
1709 publicLayoutSetVirtualHostname, portalPort, secure);
1710
1711 if (url.startsWith(portalUrl)) {
1712 if (secure) {
1713 urlSB.append(DATA_HANDLER_PUBLIC_LAYOUT_SET_SECURE_URL);
1714 }
1715 else {
1716 urlSB.append(DATA_HANDLER_PUBLIC_LAYOUT_SET_URL);
1717 }
1718
1719 return url.substring(portalUrl.length());
1720 }
1721 }
1722
1723 LayoutSet privateLayoutSet = group.getPrivateLayoutSet();
1724
1725 String privateLayoutSetVirtualHostname =
1726 privateLayoutSet.getVirtualHostname();
1727
1728 if (Validator.isNotNull(privateLayoutSetVirtualHostname)) {
1729 portalUrl = PortalUtil.getPortalURL(
1730 privateLayoutSetVirtualHostname, portalPort, secure);
1731
1732 if (url.startsWith(portalUrl)) {
1733 if (secure) {
1734 urlSB.append(DATA_HANDLER_PRIVATE_LAYOUT_SET_SECURE_URL);
1735 }
1736 else {
1737 urlSB.append(DATA_HANDLER_PRIVATE_LAYOUT_SET_URL);
1738 }
1739
1740 return url.substring(portalUrl.length());
1741 }
1742 }
1743
1744 Company company = CompanyLocalServiceUtil.getCompany(
1745 group.getCompanyId());
1746
1747 String companyVirtualHostname = company.getVirtualHostname();
1748
1749 if (Validator.isNotNull(companyVirtualHostname)) {
1750 portalUrl = PortalUtil.getPortalURL(
1751 companyVirtualHostname, portalPort, secure);
1752
1753 if (url.startsWith(portalUrl)) {
1754 if (secure) {
1755 urlSB.append(DATA_HANDLER_COMPANY_SECURE_URL);
1756 }
1757 else {
1758 urlSB.append(DATA_HANDLER_COMPANY_URL);
1759 }
1760
1761 return url.substring(portalUrl.length());
1762 }
1763 }
1764
1765 portalUrl = PortalUtil.getPortalURL("localhost", portalPort, secure);
1766
1767 if (url.startsWith(portalUrl)) {
1768 return url.substring(portalUrl.length());
1769 }
1770
1771 return url;
1772 }
1773
1774 protected MissingReference validateMissingReference(
1775 PortletDataContext portletDataContext, Element element) {
1776
1777 String className = element.attributeValue("class-name");
1778
1779 StagedModelDataHandler<?> stagedModelDataHandler =
1780 StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
1781 className);
1782
1783 if (!stagedModelDataHandler.validateReference(
1784 portletDataContext, element.getParent(), element)) {
1785
1786 return new MissingReference(element);
1787 }
1788
1789 return null;
1790 }
1791
1792 private static final char[] _DL_REFERENCE_LEGACY_STOP_CHARS = {
1793 CharPool.APOSTROPHE, CharPool.CLOSE_BRACKET, CharPool.CLOSE_CURLY_BRACE,
1794 CharPool.CLOSE_PARENTHESIS, CharPool.GREATER_THAN, CharPool.LESS_THAN,
1795 CharPool.PIPE, CharPool.QUOTE, CharPool.SPACE
1796 };
1797
1798 private static final char[] _DL_REFERENCE_STOP_CHARS = {
1799 CharPool.APOSTROPHE, CharPool.CLOSE_BRACKET, CharPool.CLOSE_CURLY_BRACE,
1800 CharPool.CLOSE_PARENTHESIS, CharPool.GREATER_THAN, CharPool.LESS_THAN,
1801 CharPool.PIPE, CharPool.QUESTION, CharPool.QUOTE, CharPool.SPACE
1802 };
1803
1804 private static final char[] _LAYOUT_REFERENCE_STOP_CHARS = {
1805 CharPool.APOSTROPHE, CharPool.CLOSE_BRACKET, CharPool.CLOSE_CURLY_BRACE,
1806 CharPool.CLOSE_PARENTHESIS, CharPool.GREATER_THAN, CharPool.LESS_THAN,
1807 CharPool.PIPE, CharPool.QUESTION, CharPool.QUOTE, CharPool.SPACE
1808 };
1809
1810 private static final String _PRIVATE_GROUP_SERVLET_MAPPING =
1811 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING +
1812 StringPool.SLASH;
1813
1814 private static final String _PRIVATE_USER_SERVLET_MAPPING =
1815 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING +
1816 StringPool.SLASH;
1817
1818 private static final String _PUBLIC_GROUP_SERVLET_MAPPING =
1819 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING +
1820 StringPool.SLASH;
1821
1822 private static Log _log = LogFactoryUtil.getLog(
1823 ExportImportHelperImpl.class);
1824
1825 private Pattern _exportLinksToLayoutPattern = Pattern.compile(
1826 "\\[([0-9]+)@(public|private\\-[a-z]*)\\]");
1827 private Pattern _importLinksToLayoutPattern = Pattern.compile(
1828 "\\[([0-9]+)@(public|private\\-[a-z]*)@(\\p{XDigit}{8}\\-" +
1829 "(?:\\p{XDigit}{4}\\-){3}\\p{XDigit}{12})@([^\\]]*)\\]");
1830
1831 private class ManifestSummaryElementProcessor implements ElementProcessor {
1832
1833 public ManifestSummaryElementProcessor(
1834 Group group, ManifestSummary manifestSummary) {
1835
1836 _group = group;
1837 _manifestSummary = manifestSummary;
1838 }
1839
1840 @Override
1841 public void processElement(Element element) {
1842 String elementName = element.getName();
1843
1844 if (elementName.equals("header")) {
1845 String exportDateString = element.attributeValue("export-date");
1846
1847 Date exportDate = GetterUtil.getDate(
1848 exportDateString,
1849 DateFormatFactoryUtil.getSimpleDateFormat(
1850 Time.RFC822_FORMAT));
1851
1852 _manifestSummary.setExportDate(exportDate);
1853 }
1854 else if (elementName.equals("portlet")) {
1855 String portletId = element.attributeValue("portlet-id");
1856
1857 Portlet portlet = null;
1858
1859 try {
1860 portlet = PortletLocalServiceUtil.getPortletById(
1861 _group.getCompanyId(), portletId);
1862 }
1863 catch (Exception e) {
1864 return;
1865 }
1866
1867 PortletDataHandler portletDataHandler =
1868 portlet.getPortletDataHandlerInstance();
1869
1870 String[] configurationPortletOptions = StringUtil.split(
1871 element.attributeValue("portlet-configuration"));
1872
1873 PortletDataHandlerControl[] portletDataHandlerControls =
1874 portletDataHandler.getImportConfigurationControls(
1875 configurationPortletOptions);
1876
1877 if (ArrayUtil.isNotEmpty(portletDataHandlerControls)) {
1878 _manifestSummary.addConfigurationPortlet(
1879 portlet, configurationPortletOptions);
1880 }
1881
1882 if (!(portletDataHandler instanceof
1883 DefaultConfigurationPortletDataHandler) &&
1884 GetterUtil.getBoolean(
1885 element.attributeValue("portlet-data"))) {
1886
1887 _manifestSummary.addDataPortlet(portlet);
1888 }
1889 }
1890 else if (elementName.equals("staged-model")) {
1891 String manifestSummaryKey = element.attributeValue(
1892 "manifest-summary-key");
1893
1894 long modelAdditionCount = GetterUtil.getLong(
1895 element.attributeValue("addition-count"));
1896
1897 _manifestSummary.addModelAdditionCount(
1898 manifestSummaryKey, modelAdditionCount);
1899
1900 long modelDeletionCount = GetterUtil.getLong(
1901 element.attributeValue("deletion-count"));
1902
1903 _manifestSummary.addModelDeletionCount(
1904 manifestSummaryKey, modelDeletionCount);
1905 }
1906 }
1907
1908 private Group _group;
1909 private ManifestSummary _manifestSummary;
1910
1911 }
1912
1913 }