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