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)
204 throws Exception {
205
206 Date startDate = null;
207 Date endDate = null;
208
209 String range = ParamUtil.getString(portletRequest, "range");
210
211 if (range.equals("dateRange")) {
212 Calendar startCalendar = getCalendar(
213 portletRequest, "startDate", true);
214
215 startDate = startCalendar.getTime();
216
217 Calendar endCalendar = getCalendar(portletRequest, "endDate", true);
218
219 endDate = endCalendar.getTime();
220 }
221 else if (range.equals("fromLastPublishDate")) {
222 if (Validator.isNotNull(portletId) && (plid > 0)) {
223 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
224
225 PortletPreferences preferences =
226 PortletPreferencesFactoryUtil.getPortletSetup(
227 layout, portletId, StringPool.BLANK);
228
229 long lastPublishDate = GetterUtil.getLong(
230 preferences.getValue(
231 "last-publish-date", StringPool.BLANK));
232
233 if (lastPublishDate > 0) {
234 endDate = new Date();
235
236 startDate = new Date(lastPublishDate);
237 }
238 }
239 else {
240 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
241 groupId, privateLayout);
242
243 long lastPublishDate = GetterUtil.getLong(
244 layoutSet.getSettingsProperty("last-publish-date"));
245
246 if (lastPublishDate > 0) {
247 endDate = new Date();
248
249 startDate = new Date(lastPublishDate);
250 }
251 }
252 }
253 else if (range.equals("last")) {
254 int rangeLast = ParamUtil.getInteger(portletRequest, "last");
255
256 Date now = new Date();
257
258 startDate = new Date(now.getTime() - (rangeLast * Time.HOUR));
259
260 endDate = now;
261 }
262
263 return new DateRange(startDate, endDate);
264 }
265
266 @Override
267 public Layout getExportableLayout(ThemeDisplay themeDisplay)
268 throws PortalException, SystemException {
269
270 Layout layout = themeDisplay.getLayout();
271
272 if (!layout.isTypeControlPanel()) {
273 return layout;
274 }
275
276 Group scopeGroup = themeDisplay.getScopeGroup();
277
278 if (scopeGroup.isLayout()) {
279 layout = LayoutLocalServiceUtil.getLayout(scopeGroup.getClassPK());
280 }
281 else if (!scopeGroup.isCompany()) {
282 long defaultPlid = LayoutLocalServiceUtil.getDefaultPlid(
283 themeDisplay.getSiteGroupId());
284
285 if (defaultPlid > 0) {
286 layout = LayoutLocalServiceUtil.getLayout(defaultPlid);
287 }
288 }
289
290 return layout;
291 }
292
293 @Override
294 public String getExportableRootPortletId(long companyId, String portletId)
295 throws Exception {
296
297 Portlet portlet = PortletLocalServiceUtil.getPortletById(
298 companyId, portletId);
299
300 if (portlet == null) {
301 return null;
302 }
303
304 return PortletConstants.getRootPortletId(portletId);
305 }
306
307 @Override
308 public Map<Long, Boolean> getLayoutIdMap(PortletRequest portletRequest)
309 throws Exception {
310
311 Map<Long, Boolean> layoutIdMap = new LinkedHashMap<Long, Boolean>();
312
313 String layoutIdsJSON = ParamUtil.getString(portletRequest, "layoutIds");
314
315 if (Validator.isNull(layoutIdsJSON)) {
316 return layoutIdMap;
317 }
318
319 JSONArray jsonArray = JSONFactoryUtil.createJSONArray(layoutIdsJSON);
320
321 for (int i = 0; i < jsonArray.length(); ++i) {
322 JSONObject jsonObject = jsonArray.getJSONObject(i);
323
324 long plid = jsonObject.getLong("plid");
325 boolean includeChildren = jsonObject.getBoolean("includeChildren");
326
327 layoutIdMap.put(plid, includeChildren);
328 }
329
330 return layoutIdMap;
331 }
332
333 @Override
334 public long[] getLayoutIds(List<Layout> layouts) {
335 long[] layoutIds = new long[layouts.size()];
336
337 for (int i = 0; i < layouts.size(); i++) {
338 Layout layout = layouts.get(i);
339
340 layoutIds[i] = layout.getLayoutId();
341 }
342
343 return layoutIds;
344 }
345
346 @Override
347 public ManifestSummary getManifestSummary(
348 long userId, long groupId, Map<String, String[]> parameterMap,
349 File file)
350 throws Exception {
351
352 final Group group = GroupLocalServiceUtil.getGroup(groupId);
353 String userIdStrategy = MapUtil.getString(
354 parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
355 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
356
357 PortletDataContext portletDataContext =
358 PortletDataContextFactoryUtil.createImportPortletDataContext(
359 group.getCompanyId(), groupId, parameterMap,
360 getUserIdStrategy(userId, userIdStrategy), zipReader);
361
362 final ManifestSummary manifestSummary = new ManifestSummary();
363
364 SAXParser saxParser = new SAXParser();
365
366 ElementHandler elementHandler = new ElementHandler(
367 new ManifestSummaryElementProcessor(group, manifestSummary),
368 new String[] {"header", "portlet", "staged-model"});
369
370 saxParser.setContentHandler(elementHandler);
371
372 InputStream is = portletDataContext.getZipEntryAsInputStream(
373 "/manifest.xml");
374
375 if (is == null) {
376 throw new LARFileException("manifest.xml is not in the LAR");
377 }
378
379 String manifestXMLContent = StringUtil.read(is);
380
381 saxParser.parse(new InputSource(new StringReader(manifestXMLContent)));
382
383 return manifestSummary;
384 }
385
386 @Override
387 public ManifestSummary getManifestSummary(
388 long userId, long groupId, Map<String, String[]> parameterMap,
389 FileEntry fileEntry)
390 throws Exception {
391
392 File file = FileUtil.createTempFile("lar");
393 InputStream inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
394 userId, fileEntry.getFileEntryId(), fileEntry.getVersion(), false);
395
396 ManifestSummary manifestSummary = null;
397
398 try {
399 FileUtil.write(file, inputStream);
400
401 manifestSummary = getManifestSummary(
402 userId, groupId, parameterMap, file);
403 }
404 finally {
405 StreamUtil.cleanUp(inputStream);
406
407 FileUtil.delete(file);
408 }
409
410 return manifestSummary;
411 }
412
413 @Override
414 public long getModelDeletionCount(
415 final PortletDataContext portletDataContext,
416 final StagedModelType stagedModelType)
417 throws PortalException, SystemException {
418
419 ActionableDynamicQuery actionableDynamicQuery =
420 new SystemEventActionableDynamicQuery() {
421
422 protected void addCreateDateProperty(DynamicQuery dynamicQuery) {
423 if (!portletDataContext.hasDateRange()) {
424 return;
425 }
426
427 Property createDateProperty = PropertyFactoryUtil.forName(
428 "createDate");
429
430 Date startDate = portletDataContext.getStartDate();
431
432 dynamicQuery.add(createDateProperty.ge(startDate));
433
434 Date endDate = portletDataContext.getEndDate();
435
436 dynamicQuery.add(createDateProperty.le(endDate));
437 }
438
439 @Override
440 protected void addCriteria(DynamicQuery dynamicQuery) {
441 Disjunction disjunction = RestrictionsFactoryUtil.disjunction();
442
443 Property groupIdProperty = PropertyFactoryUtil.forName(
444 "groupId");
445
446 disjunction.add(groupIdProperty.eq(0L));
447 disjunction.add(
448 groupIdProperty.eq(portletDataContext.getScopeGroupId()));
449
450 dynamicQuery.add(disjunction);
451
452 Property classNameIdProperty = PropertyFactoryUtil.forName(
453 "classNameId");
454
455 dynamicQuery.add(
456 classNameIdProperty.eq(stagedModelType.getClassNameId()));
457
458 Property referrerClassNameIdProperty =
459 PropertyFactoryUtil.forName("referrerClassNameId");
460
461 dynamicQuery.add(
462 referrerClassNameIdProperty.eq(
463 stagedModelType.getReferrerClassNameId()));
464
465 Property typeProperty = PropertyFactoryUtil.forName("type");
466
467 dynamicQuery.add(
468 typeProperty.eq(SystemEventConstants.TYPE_DELETE));
469
470 addCreateDateProperty(dynamicQuery);
471 }
472
473 @Override
474 protected void performAction(Object object) {
475 }
476
477 };
478
479 actionableDynamicQuery.setCompanyId(portletDataContext.getCompanyId());
480
481 return actionableDynamicQuery.performCount();
482 }
483
484 @Override
485 public FileEntry getTempFileEntry(
486 long groupId, long userId, String folderName)
487 throws PortalException, SystemException {
488
489 String[] tempFileEntryNames = LayoutServiceUtil.getTempFileEntryNames(
490 groupId, folderName);
491
492 if (tempFileEntryNames.length == 0) {
493 return null;
494 }
495
496 return TempFileUtil.getTempFile(
497 groupId, userId, tempFileEntryNames[0], folderName);
498 }
499
500 @Override
501 public String replaceExportContentReferences(
502 PortletDataContext portletDataContext,
503 StagedModel entityStagedModel, Element entityElement,
504 String content, boolean exportReferencedContent)
505 throws Exception {
506
507 content = ExportImportHelperUtil.replaceExportLayoutReferences(
508 portletDataContext, content, exportReferencedContent);
509 content = ExportImportHelperUtil.replaceExportLinksToLayouts(
510 portletDataContext, entityStagedModel, entityElement, content,
511 exportReferencedContent);
512
513 content = ExportImportHelperUtil.replaceExportDLReferences(
514 portletDataContext, entityStagedModel, entityElement, content,
515 exportReferencedContent);
516
517 Element groupElement = entityElement.getParent();
518
519 String groupElementName = groupElement.getName();
520
521 if (!groupElementName.equals(JournalArticle.class.getSimpleName())) {
522 content = StringUtil.replace(
523 content, StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
524 }
525
526 return content;
527 }
528
529 @Override
530 public String replaceExportDLReferences(
531 PortletDataContext portletDataContext,
532 StagedModel entityStagedModel, Element entityElement,
533 String content, boolean exportReferencedContent)
534 throws Exception {
535
536 Group group = GroupLocalServiceUtil.getGroup(
537 portletDataContext.getGroupId());
538
539 if (group.isStagingGroup()) {
540 group = group.getLiveGroup();
541 }
542
543 if (group.isStaged() && !group.isStagedRemotely() &&
544 !group.isStagedPortlet(PortletKeys.DOCUMENT_LIBRARY)) {
545
546 return content;
547 }
548
549 StringBuilder sb = new StringBuilder(content);
550
551 String contextPath = PortalUtil.getPathContext();
552
553 String[] patterns = {
554 contextPath.concat("/c/document_library/get_file?"),
555 contextPath.concat("/documents/"),
556 contextPath.concat("/image/image_gallery?")
557 };
558
559 int beginPos = -1;
560 int endPos = content.length();
561
562 while (true) {
563 beginPos = StringUtil.lastIndexOfAny(content, patterns, endPos);
564
565 if (beginPos == -1) {
566 break;
567 }
568
569 Map<String, String[]> dlReferenceParameters =
570 getDLReferenceParameters(
571 portletDataContext, content,
572 beginPos + contextPath.length(), endPos);
573
574 FileEntry fileEntry = getFileEntry(
575 portletDataContext, dlReferenceParameters);
576
577 if (fileEntry == null) {
578 endPos = beginPos - 1;
579
580 continue;
581 }
582
583 endPos = MapUtil.getInteger(dlReferenceParameters, "endPos");
584
585 try {
586 if (exportReferencedContent) {
587 StagedModelDataHandlerUtil.exportReferenceStagedModel(
588 portletDataContext, entityStagedModel, entityElement,
589 fileEntry, FileEntry.class,
590 PortletDataContext.REFERENCE_TYPE_DEPENDENCY);
591 }
592 else {
593 portletDataContext.addReferenceElement(
594 entityStagedModel, entityElement, fileEntry,
595 FileEntry.class,
596 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
597 }
598
599 String path = ExportImportPathUtil.getModelPath(fileEntry);
600
601 sb.replace(beginPos, endPos, "[$dl-reference=" + path + "$]");
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 Map<String, String[]> getDLReferenceParameters(
1511 PortletDataContext portletDataContext, String content, int beginPos,
1512 int endPos) {
1513
1514 boolean legacyURL = true;
1515 char[] stopChars = _DL_REFERENCE_LEGACY_STOP_CHARS;
1516
1517 if (content.startsWith("/documents/", beginPos)) {
1518 legacyURL = false;
1519 stopChars = _DL_REFERENCE_STOP_CHARS;
1520 }
1521
1522 endPos = StringUtil.indexOfAny(content, stopChars, beginPos, endPos);
1523
1524 if (endPos == -1) {
1525 return null;
1526 }
1527
1528 Map<String, String[]> map = new HashMap<String, String[]>();
1529
1530 String dlReference = content.substring(beginPos, endPos);
1531
1532 while (dlReference.contains(StringPool.AMPERSAND_ENCODED)) {
1533 dlReference = dlReference.replace(
1534 StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
1535 }
1536
1537 if (!legacyURL) {
1538 String[] pathArray = dlReference.split(StringPool.SLASH);
1539
1540 map.put("groupId", new String[] {pathArray[2]});
1541
1542 if (pathArray.length == 4) {
1543 map.put("uuid", new String[] {pathArray[3]});
1544 }
1545 else if (pathArray.length == 5) {
1546 map.put("folderId", new String[] {pathArray[3]});
1547 map.put(
1548 "title", new String[] {HttpUtil.decodeURL(pathArray[4])});
1549 }
1550 else if (pathArray.length > 5) {
1551 map.put("uuid", new String[] {pathArray[5]});
1552 }
1553 }
1554 else {
1555 dlReference = dlReference.substring(
1556 dlReference.indexOf(CharPool.QUESTION) + 1);
1557
1558 map = HttpUtil.parameterMapFromString(dlReference);
1559
1560 if (map.containsKey("img_id")) {
1561 map.put("image_id", map.get("img_id"));
1562 }
1563 else if (map.containsKey("i_id")) {
1564 map.put("image_id", map.get("i_id"));
1565 }
1566 }
1567
1568 map.put("endPos", new String[] {String.valueOf(endPos)});
1569
1570 String groupIdString = MapUtil.getString(map, "groupId");
1571
1572 if (groupIdString.equals("@group_id@")) {
1573 groupIdString = String.valueOf(
1574 portletDataContext.getScopeGroupId());
1575
1576 map.put("groupId", new String[] {groupIdString});
1577 }
1578
1579 return map;
1580 }
1581
1582 protected FileEntry getFileEntry(
1583 PortletDataContext portletDataContext, Map<String, String[]> map) {
1584
1585 if (map == null) {
1586 return null;
1587 }
1588
1589 FileEntry fileEntry = null;
1590
1591 try {
1592 String uuid = MapUtil.getString(map, "uuid");
1593 long groupId = MapUtil.getLong(map, "groupId");
1594
1595 if (Validator.isNotNull(uuid)) {
1596 fileEntry =
1597 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1598 uuid, groupId);
1599 }
1600 else {
1601 if (map.containsKey("folderId")) {
1602 long folderId = MapUtil.getLong(map, "folderId");
1603 String name = MapUtil.getString(map, "name");
1604 String title = MapUtil.getString(map, "title");
1605
1606 if (Validator.isNotNull(title)) {
1607 fileEntry = DLAppLocalServiceUtil.getFileEntry(
1608 groupId, folderId, title);
1609 }
1610 else {
1611 DLFileEntry dlFileEntry =
1612 DLFileEntryLocalServiceUtil.fetchFileEntryByName(
1613 groupId, folderId, name);
1614
1615 if (dlFileEntry != null) {
1616 fileEntry = DLAppLocalServiceUtil.getFileEntry(
1617 dlFileEntry.getFileEntryId());
1618 }
1619 }
1620 }
1621 else if (map.containsKey("image_id")) {
1622 DLFileEntry dlFileEntry =
1623 DLFileEntryLocalServiceUtil.fetchFileEntryByAnyImageId(
1624 MapUtil.getLong(map, "image_id"));
1625
1626 if (dlFileEntry != null) {
1627 fileEntry = DLAppLocalServiceUtil.getFileEntry(
1628 dlFileEntry.getFileEntryId());
1629 }
1630 }
1631 }
1632 }
1633 catch (Exception e) {
1634 if (_log.isDebugEnabled()) {
1635 _log.debug(e, e);
1636 }
1637 else if (_log.isWarnEnabled()) {
1638 _log.warn(e.getMessage());
1639 }
1640 }
1641
1642 return fileEntry;
1643 }
1644
1645 protected UserIdStrategy getUserIdStrategy(
1646 long userId, String userIdStrategy)
1647 throws Exception {
1648
1649 User user = UserLocalServiceUtil.getUserById(userId);
1650
1651 if (UserIdStrategy.ALWAYS_CURRENT_USER_ID.equals(userIdStrategy)) {
1652 return new AlwaysCurrentUserIdStrategy(user);
1653 }
1654
1655 return new CurrentUserIdStrategy(user);
1656 }
1657
1658 protected String replaceExportHostname(
1659 PortletDataContext portletDataContext, String url,
1660 StringBundler urlSB)
1661 throws PortalException, SystemException {
1662
1663 if (!HttpUtil.hasProtocol(url)) {
1664 return url;
1665 }
1666
1667 boolean secure = HttpUtil.isSecure(url);
1668
1669 int portalPort = PortalUtil.getPortalPort(secure);
1670
1671 if (portalPort == -1) {
1672 return url;
1673 }
1674
1675 Group group = GroupLocalServiceUtil.getGroup(
1676 portletDataContext.getScopeGroupId());
1677
1678 LayoutSet publicLayoutSet = group.getPublicLayoutSet();
1679
1680 String publicLayoutSetVirtualHostname =
1681 publicLayoutSet.getVirtualHostname();
1682
1683 String portalUrl = StringPool.BLANK;
1684
1685 if (Validator.isNotNull(publicLayoutSetVirtualHostname)) {
1686 portalUrl = PortalUtil.getPortalURL(
1687 publicLayoutSetVirtualHostname, portalPort, secure);
1688
1689 if (url.startsWith(portalUrl)) {
1690 if (secure) {
1691 urlSB.append(DATA_HANDLER_PUBLIC_LAYOUT_SET_SECURE_URL);
1692 }
1693 else {
1694 urlSB.append(DATA_HANDLER_PUBLIC_LAYOUT_SET_URL);
1695 }
1696
1697 return url.substring(portalUrl.length());
1698 }
1699 }
1700
1701 LayoutSet privateLayoutSet = group.getPrivateLayoutSet();
1702
1703 String privateLayoutSetVirtualHostname =
1704 privateLayoutSet.getVirtualHostname();
1705
1706 if (Validator.isNotNull(privateLayoutSetVirtualHostname)) {
1707 portalUrl = PortalUtil.getPortalURL(
1708 privateLayoutSetVirtualHostname, portalPort, secure);
1709
1710 if (url.startsWith(portalUrl)) {
1711 if (secure) {
1712 urlSB.append(DATA_HANDLER_PRIVATE_LAYOUT_SET_SECURE_URL);
1713 }
1714 else {
1715 urlSB.append(DATA_HANDLER_PRIVATE_LAYOUT_SET_URL);
1716 }
1717
1718 return url.substring(portalUrl.length());
1719 }
1720 }
1721
1722 Company company = CompanyLocalServiceUtil.getCompany(
1723 group.getCompanyId());
1724
1725 String companyVirtualHostname = company.getVirtualHostname();
1726
1727 if (Validator.isNotNull(companyVirtualHostname)) {
1728 portalUrl = PortalUtil.getPortalURL(
1729 companyVirtualHostname, portalPort, secure);
1730
1731 if (url.startsWith(portalUrl)) {
1732 if (secure) {
1733 urlSB.append(DATA_HANDLER_COMPANY_SECURE_URL);
1734 }
1735 else {
1736 urlSB.append(DATA_HANDLER_COMPANY_URL);
1737 }
1738
1739 return url.substring(portalUrl.length());
1740 }
1741 }
1742
1743 portalUrl = PortalUtil.getPortalURL("localhost", portalPort, secure);
1744
1745 if (url.startsWith(portalUrl)) {
1746 return url.substring(portalUrl.length());
1747 }
1748
1749 return url;
1750 }
1751
1752 protected MissingReference validateMissingReference(
1753 PortletDataContext portletDataContext, Element element) {
1754
1755 String className = element.attributeValue("class-name");
1756
1757 StagedModelDataHandler<?> stagedModelDataHandler =
1758 StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
1759 className);
1760
1761 if (!stagedModelDataHandler.validateReference(
1762 portletDataContext, element.getParent(), element)) {
1763
1764 return new MissingReference(element);
1765 }
1766
1767 return null;
1768 }
1769
1770 private static final char[] _DL_REFERENCE_LEGACY_STOP_CHARS = {
1771 CharPool.APOSTROPHE, CharPool.CLOSE_BRACKET, CharPool.CLOSE_CURLY_BRACE,
1772 CharPool.CLOSE_PARENTHESIS, CharPool.GREATER_THAN, CharPool.LESS_THAN,
1773 CharPool.PIPE, CharPool.QUOTE, CharPool.SPACE
1774 };
1775
1776 private static final char[] _DL_REFERENCE_STOP_CHARS = {
1777 CharPool.APOSTROPHE, CharPool.CLOSE_BRACKET, CharPool.CLOSE_CURLY_BRACE,
1778 CharPool.CLOSE_PARENTHESIS, CharPool.GREATER_THAN, CharPool.LESS_THAN,
1779 CharPool.PIPE, CharPool.QUESTION, CharPool.QUOTE, CharPool.SPACE
1780 };
1781
1782 private static final char[] _LAYOUT_REFERENCE_STOP_CHARS = {
1783 CharPool.APOSTROPHE, CharPool.CLOSE_BRACKET, CharPool.CLOSE_CURLY_BRACE,
1784 CharPool.CLOSE_PARENTHESIS, CharPool.GREATER_THAN, CharPool.LESS_THAN,
1785 CharPool.PIPE, CharPool.QUESTION, CharPool.QUOTE, CharPool.SPACE
1786 };
1787
1788 private static final String _PRIVATE_GROUP_SERVLET_MAPPING =
1789 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING +
1790 StringPool.SLASH;
1791
1792 private static final String _PRIVATE_USER_SERVLET_MAPPING =
1793 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING +
1794 StringPool.SLASH;
1795
1796 private static final String _PUBLIC_GROUP_SERVLET_MAPPING =
1797 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING +
1798 StringPool.SLASH;
1799
1800 private static Log _log = LogFactoryUtil.getLog(
1801 ExportImportHelperImpl.class);
1802
1803 private Pattern _exportLinksToLayoutPattern = Pattern.compile(
1804 "\\[([0-9]+)@(public|private\\-[a-z]*)\\]");
1805 private Pattern _importLinksToLayoutPattern = Pattern.compile(
1806 "\\[([0-9]+)@(public|private\\-[a-z]*)@(\\p{XDigit}{8}\\-" +
1807 "(?:\\p{XDigit}{4}\\-){3}\\p{XDigit}{12})@([^\\]]*)\\]");
1808
1809 private class ManifestSummaryElementProcessor implements ElementProcessor {
1810
1811 public ManifestSummaryElementProcessor(
1812 Group group, ManifestSummary manifestSummary) {
1813
1814 _group = group;
1815 _manifestSummary = manifestSummary;
1816 }
1817
1818 @Override
1819 public void processElement(Element element) {
1820 String elementName = element.getName();
1821
1822 if (elementName.equals("header")) {
1823 String exportDateString = element.attributeValue("export-date");
1824
1825 Date exportDate = GetterUtil.getDate(
1826 exportDateString,
1827 DateFormatFactoryUtil.getSimpleDateFormat(
1828 Time.RFC822_FORMAT));
1829
1830 _manifestSummary.setExportDate(exportDate);
1831 }
1832 else if (elementName.equals("portlet")) {
1833 String portletId = element.attributeValue("portlet-id");
1834
1835 Portlet portlet = null;
1836
1837 try {
1838 portlet = PortletLocalServiceUtil.getPortletById(
1839 _group.getCompanyId(), portletId);
1840 }
1841 catch (Exception e) {
1842 return;
1843 }
1844
1845 PortletDataHandler portletDataHandler =
1846 portlet.getPortletDataHandlerInstance();
1847
1848 String[] configurationPortletOptions = StringUtil.split(
1849 element.attributeValue("portlet-configuration"));
1850
1851 PortletDataHandlerControl[] portletDataHandlerControls =
1852 portletDataHandler.getImportConfigurationControls(
1853 configurationPortletOptions);
1854
1855 if (ArrayUtil.isNotEmpty(portletDataHandlerControls)) {
1856 _manifestSummary.addConfigurationPortlet(
1857 portlet, configurationPortletOptions);
1858 }
1859
1860 if (!(portletDataHandler instanceof
1861 DefaultConfigurationPortletDataHandler) &&
1862 GetterUtil.getBoolean(
1863 element.attributeValue("portlet-data"))) {
1864
1865 _manifestSummary.addDataPortlet(portlet);
1866 }
1867 }
1868 else if (elementName.equals("staged-model")) {
1869 String manifestSummaryKey = element.attributeValue(
1870 "manifest-summary-key");
1871
1872 long modelAdditionCount = GetterUtil.getLong(
1873 element.attributeValue("addition-count"));
1874
1875 _manifestSummary.addModelAdditionCount(
1876 manifestSummaryKey, modelAdditionCount);
1877
1878 long modelDeletionCount = GetterUtil.getLong(
1879 element.attributeValue("deletion-count"));
1880
1881 _manifestSummary.addModelDeletionCount(
1882 manifestSummaryKey, modelDeletionCount);
1883 }
1884 }
1885
1886 private Group _group;
1887 private ManifestSummary _manifestSummary;
1888
1889 }
1890
1891 }