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 if (stagedModelType.getReferrerClassNameId() >= 0) {
459 Property referrerClassNameIdProperty =
460 PropertyFactoryUtil.forName("referrerClassNameId");
461
462 dynamicQuery.add(
463 referrerClassNameIdProperty.eq(
464 stagedModelType.getReferrerClassNameId()));
465 }
466
467 Property typeProperty = PropertyFactoryUtil.forName("type");
468
469 dynamicQuery.add(
470 typeProperty.eq(SystemEventConstants.TYPE_DELETE));
471
472 addCreateDateProperty(dynamicQuery);
473 }
474
475 @Override
476 protected void performAction(Object object) {
477 }
478
479 };
480
481 actionableDynamicQuery.setCompanyId(portletDataContext.getCompanyId());
482
483 return actionableDynamicQuery.performCount();
484 }
485
486 @Override
487 public FileEntry getTempFileEntry(
488 long groupId, long userId, String folderName)
489 throws PortalException, SystemException {
490
491 String[] tempFileEntryNames = LayoutServiceUtil.getTempFileEntryNames(
492 groupId, folderName);
493
494 if (tempFileEntryNames.length == 0) {
495 return null;
496 }
497
498 return TempFileUtil.getTempFile(
499 groupId, userId, tempFileEntryNames[0], folderName);
500 }
501
502 @Override
503 public String replaceExportContentReferences(
504 PortletDataContext portletDataContext,
505 StagedModel entityStagedModel, Element entityElement,
506 String content, boolean exportReferencedContent)
507 throws Exception {
508
509 content = ExportImportHelperUtil.replaceExportLayoutReferences(
510 portletDataContext, content, exportReferencedContent);
511 content = ExportImportHelperUtil.replaceExportLinksToLayouts(
512 portletDataContext, entityStagedModel, entityElement, content,
513 exportReferencedContent);
514
515 content = ExportImportHelperUtil.replaceExportDLReferences(
516 portletDataContext, entityStagedModel, entityElement, content,
517 exportReferencedContent);
518
519 Element groupElement = entityElement.getParent();
520
521 String groupElementName = groupElement.getName();
522
523 if (!groupElementName.equals(JournalArticle.class.getSimpleName())) {
524 content = StringUtil.replace(
525 content, StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
526 }
527
528 return content;
529 }
530
531 @Override
532 public String replaceExportDLReferences(
533 PortletDataContext portletDataContext,
534 StagedModel entityStagedModel, Element entityElement,
535 String content, boolean exportReferencedContent)
536 throws Exception {
537
538 Group group = GroupLocalServiceUtil.getGroup(
539 portletDataContext.getGroupId());
540
541 if (group.isStagingGroup()) {
542 group = group.getLiveGroup();
543 }
544
545 if (group.isStaged() && !group.isStagedRemotely() &&
546 !group.isStagedPortlet(PortletKeys.DOCUMENT_LIBRARY)) {
547
548 return content;
549 }
550
551 StringBuilder sb = new StringBuilder(content);
552
553 String contextPath = PortalUtil.getPathContext();
554
555 String[] patterns = {
556 contextPath.concat("/c/document_library/get_file?"),
557 contextPath.concat("/documents/"),
558 contextPath.concat("/image/image_gallery?")
559 };
560
561 int beginPos = -1;
562 int endPos = content.length();
563
564 while (true) {
565 beginPos = StringUtil.lastIndexOfAny(content, patterns, endPos);
566
567 if (beginPos == -1) {
568 break;
569 }
570
571 Map<String, String[]> dlReferenceParameters =
572 getDLReferenceParameters(
573 portletDataContext, content,
574 beginPos + contextPath.length(), endPos);
575
576 FileEntry fileEntry = getFileEntry(
577 portletDataContext, dlReferenceParameters);
578
579 if (fileEntry == null) {
580 endPos = beginPos - 1;
581
582 continue;
583 }
584
585 endPos = MapUtil.getInteger(dlReferenceParameters, "endPos");
586
587 try {
588 if (exportReferencedContent) {
589 StagedModelDataHandlerUtil.exportReferenceStagedModel(
590 portletDataContext, entityStagedModel, entityElement,
591 fileEntry, FileEntry.class,
592 PortletDataContext.REFERENCE_TYPE_DEPENDENCY);
593 }
594 else {
595 portletDataContext.addReferenceElement(
596 entityStagedModel, entityElement, fileEntry,
597 FileEntry.class,
598 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
599 }
600
601 String path = ExportImportPathUtil.getModelPath(fileEntry);
602
603 sb.replace(beginPos, endPos, "[$dl-reference=" + path + "$]");
604 }
605 catch (Exception e) {
606 if (_log.isDebugEnabled()) {
607 _log.debug(e, e);
608 }
609 else if (_log.isWarnEnabled()) {
610 _log.warn(e.getMessage());
611 }
612 }
613
614 endPos = beginPos - 1;
615 }
616
617 return sb.toString();
618 }
619
620 @Override
621 public String replaceExportLayoutReferences(
622 PortletDataContext portletDataContext, String content,
623 boolean exportReferencedContent)
624 throws Exception {
625
626 Group group = GroupLocalServiceUtil.getGroup(
627 portletDataContext.getScopeGroupId());
628
629 StringBuilder sb = new StringBuilder(content);
630
631 String[] patterns = {"href=", "[["};
632
633 int beginPos = -1;
634 int endPos = content.length();
635 int offset = 0;
636
637 while (true) {
638 if (beginPos > -1) {
639 endPos = beginPos - 1;
640 }
641
642 beginPos = StringUtil.lastIndexOfAny(content, patterns, endPos);
643
644 if (beginPos == -1) {
645 break;
646 }
647
648 if (content.startsWith("href=", beginPos)) {
649 offset = 5;
650
651 char c = content.charAt(beginPos + offset);
652
653 if ((c == CharPool.APOSTROPHE) || (c == CharPool.QUOTE)) {
654 offset++;
655 }
656 }
657 else if (content.charAt(beginPos) == CharPool.OPEN_BRACKET) {
658 offset = 2;
659 }
660
661 endPos = StringUtil.indexOfAny(
662 content, _LAYOUT_REFERENCE_STOP_CHARS, beginPos + offset,
663 endPos);
664
665 if (endPos == -1) {
666 continue;
667 }
668
669 String url = content.substring(beginPos + offset, endPos);
670
671 StringBundler urlSB = new StringBundler(5);
672
673 try {
674 url = replaceExportHostname(portletDataContext, url, urlSB);
675
676 if (!url.startsWith(StringPool.SLASH)) {
677 continue;
678 }
679
680 String pathContext = PortalUtil.getPathContext();
681
682 if (pathContext.length() > 1) {
683 if (!url.startsWith(pathContext)) {
684 continue;
685 }
686
687 urlSB.append(DATA_HANDLER_PATH_CONTEXT);
688
689 url = url.substring(pathContext.length());
690 }
691
692 if (!url.startsWith(StringPool.SLASH)) {
693 continue;
694 }
695
696 int pos = url.indexOf(StringPool.SLASH, 1);
697
698 String localePath = StringPool.BLANK;
699
700 Locale locale = null;
701
702 if (pos != -1) {
703 localePath = url.substring(0, pos);
704
705 locale = LocaleUtil.fromLanguageId(
706 localePath.substring(1), true, false);
707 }
708
709 if (locale != null) {
710 String urlWithoutLocale = url.substring(
711 localePath.length());
712
713 if (urlWithoutLocale.startsWith(
714 _PRIVATE_GROUP_SERVLET_MAPPING) ||
715 urlWithoutLocale.startsWith(
716 _PRIVATE_USER_SERVLET_MAPPING) ||
717 urlWithoutLocale.startsWith(
718 _PUBLIC_GROUP_SERVLET_MAPPING)) {
719
720 urlSB.append(localePath);
721
722 url = urlWithoutLocale;
723 }
724 }
725
726 if (url.startsWith(_PRIVATE_GROUP_SERVLET_MAPPING)) {
727 urlSB.append(DATA_HANDLER_PRIVATE_GROUP_SERVLET_MAPPING);
728
729 url = url.substring(
730 _PRIVATE_GROUP_SERVLET_MAPPING.length() - 1);
731 }
732 else if (url.startsWith(_PRIVATE_USER_SERVLET_MAPPING)) {
733 urlSB.append(DATA_HANDLER_PRIVATE_USER_SERVLET_MAPPING);
734
735 url = url.substring(
736 _PRIVATE_USER_SERVLET_MAPPING.length() - 1);
737 }
738 else if (url.startsWith(_PUBLIC_GROUP_SERVLET_MAPPING)) {
739 urlSB.append(DATA_HANDLER_PUBLIC_SERVLET_MAPPING);
740
741 url = url.substring(
742 _PUBLIC_GROUP_SERVLET_MAPPING.length() - 1);
743 }
744 else {
745 String urlSBString = urlSB.toString();
746
747 LayoutSet layoutSet = null;
748
749 if (urlSBString.contains(
750 DATA_HANDLER_PUBLIC_LAYOUT_SET_SECURE_URL) ||
751 urlSBString.contains(
752 DATA_HANDLER_PUBLIC_LAYOUT_SET_URL)) {
753
754 layoutSet = group.getPublicLayoutSet();
755 }
756 else if (urlSBString.contains(
757 DATA_HANDLER_PRIVATE_LAYOUT_SET_SECURE_URL) ||
758 urlSBString.contains(
759 DATA_HANDLER_PRIVATE_LAYOUT_SET_URL)) {
760
761 layoutSet = group.getPrivateLayoutSet();
762 }
763
764 if (layoutSet == null) {
765 continue;
766 }
767
768 boolean privateLayout = layoutSet.isPrivateLayout();
769
770 LayoutFriendlyURL layoutFriendlyUrl =
771 LayoutFriendlyURLLocalServiceUtil.
772 fetchFirstLayoutFriendlyURL(
773 group.getGroupId(), privateLayout, url);
774
775 if (layoutFriendlyUrl == null) {
776 continue;
777 }
778
779 if (privateLayout) {
780 if (group.isUser()) {
781 urlSB.append(
782 DATA_HANDLER_PRIVATE_USER_SERVLET_MAPPING);
783 }
784 else {
785 urlSB.append(
786 DATA_HANDLER_PRIVATE_GROUP_SERVLET_MAPPING);
787 }
788 }
789 else {
790 urlSB.append(DATA_HANDLER_PUBLIC_SERVLET_MAPPING);
791 }
792
793 urlSB.append(DATA_HANDLER_GROUP_FRIENDLY_URL);
794
795 continue;
796 }
797
798 String groupFriendlyURL = group.getFriendlyURL();
799
800 if (url.equals(groupFriendlyURL) ||
801 url.startsWith(groupFriendlyURL + StringPool.SLASH)) {
802
803 urlSB.append(DATA_HANDLER_GROUP_FRIENDLY_URL);
804
805 url = url.substring(groupFriendlyURL.length());
806 }
807 }
808 finally {
809 if (urlSB.length() > 0) {
810 urlSB.append(url);
811
812 url = urlSB.toString();
813 }
814
815 sb.replace(beginPos + offset, endPos, url);
816 }
817 }
818
819 return sb.toString();
820 }
821
822 @Override
823 public String replaceExportLinksToLayouts(
824 PortletDataContext portletDataContext,
825 StagedModel entityStagedModel, Element entityElement,
826 String content, boolean exportReferencedContent)
827 throws Exception {
828
829 List<String> oldLinksToLayout = new ArrayList<String>();
830 List<String> newLinksToLayout = new ArrayList<String>();
831
832 Matcher matcher = _exportLinksToLayoutPattern.matcher(content);
833
834 while (matcher.find()) {
835 long layoutId = GetterUtil.getLong(matcher.group(1));
836
837 String type = matcher.group(2);
838
839 boolean privateLayout = type.startsWith("private");
840
841 try {
842 Layout layout = LayoutLocalServiceUtil.getLayout(
843 portletDataContext.getScopeGroupId(), privateLayout,
844 layoutId);
845
846 String oldLinkToLayout = matcher.group(0);
847
848 StringBundler sb = new StringBundler(5);
849
850 sb.append(type);
851 sb.append(StringPool.AT);
852 sb.append(layout.getUuid());
853 sb.append(StringPool.AT);
854 sb.append(layout.getFriendlyURL());
855
856 String newLinkToLayout = StringUtil.replace(
857 oldLinkToLayout, type, sb.toString());
858
859 oldLinksToLayout.add(oldLinkToLayout);
860 newLinksToLayout.add(newLinkToLayout);
861
862 if (exportReferencedContent) {
863 StagedModelDataHandlerUtil.exportReferenceStagedModel(
864 portletDataContext, entityStagedModel, layout,
865 PortletDataContext.REFERENCE_TYPE_DEPENDENCY);
866 }
867 else {
868 portletDataContext.addReferenceElement(
869 entityStagedModel, entityElement, layout,
870 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
871 }
872 }
873 catch (Exception e) {
874 if (_log.isDebugEnabled() || _log.isWarnEnabled()) {
875 String message =
876 "Unable to get layout with ID " + layoutId +
877 " in group " + portletDataContext.getScopeGroupId();
878
879 if (_log.isWarnEnabled()) {
880 _log.warn(message);
881 }
882 else {
883 _log.debug(message, e);
884 }
885 }
886 }
887 }
888
889 content = StringUtil.replace(
890 content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
891 ArrayUtil.toStringArray(newLinksToLayout.toArray()));
892
893 return content;
894 }
895
896 @Override
897 public String replaceImportContentReferences(
898 PortletDataContext portletDataContext, Element entityElement,
899 String content, boolean importReferencedContent)
900 throws Exception {
901
902 content = ExportImportHelperUtil.replaceImportLayoutReferences(
903 portletDataContext, content, importReferencedContent);
904 content = ExportImportHelperUtil.replaceImportLinksToLayouts(
905 portletDataContext, content, importReferencedContent);
906
907 content = ExportImportHelperUtil.replaceImportDLReferences(
908 portletDataContext, entityElement, content,
909 importReferencedContent);
910
911 return content;
912 }
913
914 @Override
915 public String replaceImportDLReferences(
916 PortletDataContext portletDataContext, Element entityElement,
917 String content, boolean importReferencedContent)
918 throws Exception {
919
920 List<Element> referenceDataElements =
921 portletDataContext.getReferenceDataElements(
922 entityElement, FileEntry.class,
923 PortletDataContext.REFERENCE_TYPE_DEPENDENCY);
924
925 for (Element referenceDataElement : referenceDataElements) {
926 String fileEntryUUID = referenceDataElement.attributeValue("uuid");
927
928 if (fileEntryUUID == null) {
929 continue;
930 }
931
932 String path = referenceDataElement.attributeValue("path");
933
934 if (!content.contains("[$dl-reference=" + path + "$]")) {
935 continue;
936 }
937
938 FileEntry fileEntry =
939 (FileEntry)portletDataContext.getZipEntryAsObject(path);
940
941 StagedModelDataHandlerUtil.importStagedModel(
942 portletDataContext, fileEntry);
943
944 Map<Long, Long> fileEntryIds =
945 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
946 DLFileEntry.class);
947
948 long importedFileEntryId = MapUtil.getLong(
949 fileEntryIds, fileEntry.getFileEntryId(),
950 fileEntry.getFileEntryId());
951
952 FileEntry importedFileEntry = null;
953
954 try {
955 importedFileEntry = DLAppLocalServiceUtil.getFileEntry(
956 importedFileEntryId);
957 }
958 catch (NoSuchFileEntryException nsfee) {
959 if (_log.isWarnEnabled()) {
960 _log.warn("Unable to reference " + path);
961 }
962
963 continue;
964 }
965
966 String url = DLUtil.getPreviewURL(
967 importedFileEntry, importedFileEntry.getFileVersion(), null,
968 StringPool.BLANK, false, false);
969
970 content = StringUtil.replace(
971 content, "[$dl-reference=" + path + "$]", url);
972 }
973
974 return content;
975 }
976
977 @Override
978 public String replaceImportLayoutReferences(
979 PortletDataContext portletDataContext, String content,
980 boolean importReferencedContent)
981 throws Exception {
982
983 String companyPortalURL = StringPool.BLANK;
984 String privateLayoutSetPortalURL = StringPool.BLANK;
985 String publicLayoutSetPortalURL = StringPool.BLANK;
986
987 Group group = GroupLocalServiceUtil.getGroup(
988 portletDataContext.getScopeGroupId());
989
990 Company company = CompanyLocalServiceUtil.getCompany(
991 group.getCompanyId());
992
993 LayoutSet privateLayoutSet = group.getPrivateLayoutSet();
994 LayoutSet publicLayoutSet = group.getPublicLayoutSet();
995
996 int portalPort = PortalUtil.getPortalPort(false);
997
998 if (portalPort != -1) {
999 if (Validator.isNotNull(company.getVirtualHostname())) {
1000 companyPortalURL = PortalUtil.getPortalURL(
1001 company.getVirtualHostname(), portalPort, false);
1002 }
1003
1004 if (Validator.isNotNull(privateLayoutSet.getVirtualHostname())) {
1005 privateLayoutSetPortalURL = PortalUtil.getPortalURL(
1006 privateLayoutSet.getVirtualHostname(), portalPort, false);
1007 }
1008
1009 if (Validator.isNotNull(publicLayoutSet.getVirtualHostname())) {
1010 publicLayoutSetPortalURL = PortalUtil.getPortalURL(
1011 publicLayoutSet.getVirtualHostname(), portalPort, false);
1012 }
1013 }
1014
1015 int securePortalPort = PortalUtil.getPortalPort(true);
1016
1017 String companySecurePortalURL = StringPool.BLANK;
1018 String privateLayoutSetSecurePortalURL = StringPool.BLANK;
1019 String publicLayoutSetSecurePortalURL = StringPool.BLANK;
1020
1021 if (securePortalPort != -1) {
1022 if (Validator.isNotNull(company.getVirtualHostname())) {
1023 companySecurePortalURL = PortalUtil.getPortalURL(
1024 company.getVirtualHostname(), securePortalPort, true);
1025 }
1026
1027 if (Validator.isNotNull(privateLayoutSet.getVirtualHostname())) {
1028 privateLayoutSetSecurePortalURL = PortalUtil.getPortalURL(
1029 privateLayoutSet.getVirtualHostname(), securePortalPort,
1030 true);
1031 }
1032
1033 if (Validator.isNotNull(publicLayoutSet.getVirtualHostname())) {
1034 publicLayoutSetSecurePortalURL = PortalUtil.getPortalURL(
1035 publicLayoutSet.getVirtualHostname(), securePortalPort,
1036 true);
1037 }
1038 }
1039
1040 content = StringUtil.replace(
1041 content, DATA_HANDLER_COMPANY_SECURE_URL, companySecurePortalURL);
1042 content = StringUtil.replace(
1043 content, DATA_HANDLER_COMPANY_URL, companyPortalURL);
1044 content = StringUtil.replace(
1045 content, DATA_HANDLER_GROUP_FRIENDLY_URL, group.getFriendlyURL());
1046 content = StringUtil.replace(
1047 content, DATA_HANDLER_PATH_CONTEXT, PortalUtil.getPathContext());
1048 content = StringUtil.replace(
1049 content, DATA_HANDLER_PRIVATE_GROUP_SERVLET_MAPPING,
1050 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING);
1051 content = StringUtil.replace(
1052 content, DATA_HANDLER_PRIVATE_LAYOUT_SET_SECURE_URL,
1053 privateLayoutSetSecurePortalURL);
1054 content = StringUtil.replace(
1055 content, DATA_HANDLER_PRIVATE_LAYOUT_SET_URL,
1056 privateLayoutSetPortalURL);
1057 content = StringUtil.replace(
1058 content, DATA_HANDLER_PRIVATE_USER_SERVLET_MAPPING,
1059 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING);
1060 content = StringUtil.replace(
1061 content, DATA_HANDLER_PUBLIC_LAYOUT_SET_SECURE_URL,
1062 publicLayoutSetSecurePortalURL);
1063 content = StringUtil.replace(
1064 content, DATA_HANDLER_PUBLIC_LAYOUT_SET_URL,
1065 publicLayoutSetPortalURL);
1066 content = StringUtil.replace(
1067 content, DATA_HANDLER_PUBLIC_SERVLET_MAPPING,
1068 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING);
1069
1070 return content;
1071 }
1072
1073 @Override
1074 public String replaceImportLinksToLayouts(
1075 PortletDataContext portletDataContext, String content,
1076 boolean importReferencedContent)
1077 throws Exception {
1078
1079 List<String> oldLinksToLayout = new ArrayList<String>();
1080 List<String> newLinksToLayout = new ArrayList<String>();
1081
1082 Matcher matcher = _importLinksToLayoutPattern.matcher(content);
1083
1084 while (matcher.find()) {
1085 long oldLayoutId = GetterUtil.getLong(matcher.group(1));
1086
1087 long newLayoutId = oldLayoutId;
1088
1089 String type = matcher.group(2);
1090
1091 boolean privateLayout = type.startsWith("private");
1092
1093 String layoutUuid = matcher.group(3);
1094 String friendlyURL = matcher.group(4);
1095
1096 try {
1097 Layout layout =
1098 LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
1099 layoutUuid, portletDataContext.getScopeGroupId(),
1100 privateLayout);
1101
1102 if (layout == null) {
1103 layout = LayoutLocalServiceUtil.fetchLayoutByFriendlyURL(
1104 portletDataContext.getScopeGroupId(), privateLayout,
1105 friendlyURL);
1106 }
1107
1108 if (layout == null) {
1109 layout = LayoutLocalServiceUtil.fetchLayout(
1110 portletDataContext.getScopeGroupId(), privateLayout,
1111 oldLayoutId);
1112 }
1113
1114 if (layout == null) {
1115 if (_log.isWarnEnabled()) {
1116 StringBundler sb = new StringBundler(9);
1117
1118 sb.append("Unable to get layout with UUID ");
1119 sb.append(layoutUuid);
1120 sb.append(", friendly URL ");
1121 sb.append(friendlyURL);
1122 sb.append(", or ");
1123 sb.append("layoutId ");
1124 sb.append(oldLayoutId);
1125 sb.append(" in group ");
1126 sb.append(portletDataContext.getScopeGroupId());
1127
1128 _log.warn(sb.toString());
1129 }
1130 }
1131 else {
1132 newLayoutId = layout.getLayoutId();
1133 }
1134 }
1135 catch (SystemException se) {
1136 if (_log.isDebugEnabled() || _log.isWarnEnabled()) {
1137 String message =
1138 "Unable to get layout in group " +
1139 portletDataContext.getScopeGroupId();
1140
1141 if (_log.isWarnEnabled()) {
1142 _log.warn(message);
1143 }
1144 else {
1145 _log.debug(message, se);
1146 }
1147 }
1148 }
1149
1150 String oldLinkToLayout = matcher.group(0);
1151
1152 StringBundler sb = new StringBundler(4);
1153
1154 sb.append(StringPool.AT);
1155 sb.append(layoutUuid);
1156 sb.append(StringPool.AT);
1157 sb.append(friendlyURL);
1158
1159 String newLinkToLayout = StringUtil.replace(
1160 oldLinkToLayout,
1161 new String[] {sb.toString(), String.valueOf(oldLayoutId)},
1162 new String[] {StringPool.BLANK, String.valueOf(newLayoutId)});
1163
1164 oldLinksToLayout.add(oldLinkToLayout);
1165 newLinksToLayout.add(newLinkToLayout);
1166 }
1167
1168 content = StringUtil.replace(
1169 content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
1170 ArrayUtil.toStringArray(newLinksToLayout.toArray()));
1171
1172 return content;
1173 }
1174
1175 @Override
1176 public void updateExportPortletPreferencesClassPKs(
1177 PortletDataContext portletDataContext, Portlet portlet,
1178 PortletPreferences portletPreferences, String key, String className,
1179 Element rootElement)
1180 throws Exception {
1181
1182 String[] oldValues = portletPreferences.getValues(key, null);
1183
1184 if (oldValues == null) {
1185 return;
1186 }
1187
1188 String[] newValues = new String[oldValues.length];
1189
1190 for (int i = 0; i < oldValues.length; i++) {
1191 String oldValue = oldValues[i];
1192
1193 String newValue = oldValue;
1194
1195 String[] primaryKeys = StringUtil.split(oldValue);
1196
1197 for (String primaryKey : primaryKeys) {
1198 if (!Validator.isNumber(primaryKey)) {
1199 break;
1200 }
1201
1202 long primaryKeyLong = GetterUtil.getLong(primaryKey);
1203
1204 String uuid = null;
1205
1206 if (className.equals(AssetCategory.class.getName())) {
1207 AssetCategory assetCategory =
1208 AssetCategoryLocalServiceUtil.fetchCategory(
1209 primaryKeyLong);
1210
1211 if (assetCategory != null) {
1212 uuid = assetCategory.getUuid();
1213
1214 portletDataContext.addReferenceElement(
1215 portlet, rootElement, assetCategory,
1216 AssetCategory.class,
1217 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
1218 }
1219 }
1220 else if (className.equals(AssetVocabulary.class.getName())) {
1221 AssetVocabulary assetVocabulary =
1222 AssetVocabularyLocalServiceUtil.fetchAssetVocabulary(
1223 primaryKeyLong);
1224
1225 if (assetVocabulary != null) {
1226 uuid = assetVocabulary.getUuid();
1227
1228 portletDataContext.addReferenceElement(
1229 portlet, rootElement, assetVocabulary,
1230 AssetVocabulary.class,
1231 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
1232 }
1233 }
1234 else if (className.equals(DDMStructure.class.getName())) {
1235 DDMStructure ddmStructure =
1236 DDMStructureLocalServiceUtil.fetchStructure(
1237 primaryKeyLong);
1238
1239 if (ddmStructure != null) {
1240 uuid = ddmStructure.getUuid();
1241
1242 portletDataContext.addReferenceElement(
1243 portlet, rootElement, ddmStructure,
1244 DDMStructure.class,
1245 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
1246 }
1247 }
1248 else if (className.equals(DLFileEntryType.class.getName())) {
1249 DLFileEntryType dlFileEntryType =
1250 DLFileEntryTypeLocalServiceUtil.fetchFileEntryType(
1251 primaryKeyLong);
1252
1253 if (dlFileEntryType != null) {
1254 uuid = dlFileEntryType.getUuid();
1255
1256 portletDataContext.addReferenceElement(
1257 portlet, rootElement, dlFileEntryType,
1258 DLFileEntryType.class,
1259 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
1260 }
1261 }
1262 else if (className.equals(Organization.class.getName())) {
1263 Organization organization =
1264 OrganizationLocalServiceUtil.fetchOrganization(
1265 primaryKeyLong);
1266
1267 if (organization != null) {
1268 uuid = organization.getUuid();
1269
1270 portletDataContext.addReferenceElement(
1271 portlet, rootElement, organization,
1272 Organization.class,
1273 PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
1274 }
1275 }
1276
1277 if (Validator.isNull(uuid)) {
1278 if (_log.isWarnEnabled()) {
1279 _log.warn(
1280 "Unable to get UUID for class " + className +
1281 " with primary key " + primaryKeyLong);
1282 }
1283
1284 continue;
1285 }
1286
1287 newValue = StringUtil.replace(newValue, primaryKey, uuid);
1288 }
1289
1290 newValues[i] = newValue;
1291 }
1292
1293 portletPreferences.setValues(key, newValues);
1294 }
1295
1296 @Override
1297 public void updateImportPortletPreferencesClassPKs(
1298 PortletDataContext portletDataContext,
1299 PortletPreferences portletPreferences, String key, Class<?> clazz,
1300 long companyGroupId)
1301 throws Exception {
1302
1303 String[] oldValues = portletPreferences.getValues(key, null);
1304
1305 if (oldValues == null) {
1306 return;
1307 }
1308
1309 Map<Long, Long> primaryKeys =
1310 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(clazz);
1311
1312 String[] newValues = new String[oldValues.length];
1313
1314 for (int i = 0; i < oldValues.length; i++) {
1315 String oldValue = oldValues[i];
1316
1317 String newValue = oldValue;
1318
1319 String[] uuids = StringUtil.split(oldValue);
1320
1321 for (String uuid : uuids) {
1322 Long newPrimaryKey = null;
1323
1324 if (Validator.isNumber(uuid)) {
1325 long oldPrimaryKey = GetterUtil.getLong(uuid);
1326
1327 newPrimaryKey = MapUtil.getLong(
1328 primaryKeys, oldPrimaryKey, oldPrimaryKey);
1329 }
1330 else {
1331 String className = clazz.getName();
1332
1333 if (className.equals(AssetCategory.class.getName())) {
1334 AssetCategory assetCategory =
1335 AssetCategoryUtil.fetchByUUID_G(
1336 uuid, portletDataContext.getScopeGroupId());
1337
1338 if (assetCategory == null) {
1339 assetCategory = AssetCategoryUtil.fetchByUUID_G(
1340 uuid, companyGroupId);
1341 }
1342
1343 if (assetCategory != null) {
1344 newPrimaryKey = assetCategory.getCategoryId();
1345 }
1346 }
1347 else if (className.equals(
1348 AssetVocabulary.class.getName())) {
1349
1350 AssetVocabulary assetVocabulary =
1351 AssetVocabularyUtil.fetchByUUID_G(
1352 uuid, portletDataContext.getScopeGroupId());
1353
1354 if (assetVocabulary == null) {
1355 assetVocabulary = AssetVocabularyUtil.fetchByUUID_G(
1356 uuid, companyGroupId);
1357 }
1358
1359 if (assetVocabulary != null) {
1360 newPrimaryKey = assetVocabulary.getVocabularyId();
1361 }
1362 }
1363 else if (className.equals(DDMStructure.class.getName())) {
1364 DDMStructure ddmStructure =
1365 DDMStructureUtil.fetchByUUID_G(
1366 uuid, portletDataContext.getScopeGroupId());
1367
1368 if (ddmStructure == null) {
1369 ddmStructure = DDMStructureUtil.fetchByUUID_G(
1370 uuid, companyGroupId);
1371 }
1372
1373 if (ddmStructure != null) {
1374 newPrimaryKey = ddmStructure.getStructureId();
1375 }
1376 }
1377 else if (className.equals(
1378 DLFileEntryType.class.getName())) {
1379
1380 DLFileEntryType dlFileEntryType =
1381 DLFileEntryTypeUtil.fetchByUUID_G(
1382 uuid, portletDataContext.getScopeGroupId());
1383
1384 if (dlFileEntryType == null) {
1385 dlFileEntryType = DLFileEntryTypeUtil.fetchByUUID_G(
1386 uuid, companyGroupId);
1387 }
1388
1389 if (dlFileEntryType != null) {
1390 newPrimaryKey =
1391 dlFileEntryType.getFileEntryTypeId();
1392 }
1393 }
1394 else if (className.equals(Organization.class.getName())) {
1395 Organization organization =
1396 OrganizationUtil.fetchByUuid_C_First(
1397 uuid, portletDataContext.getCompanyId(), null);
1398
1399 if (organization != null) {
1400 newPrimaryKey = organization.getOrganizationId();
1401 }
1402 }
1403 }
1404
1405 if (Validator.isNull(newPrimaryKey)) {
1406 if (_log.isWarnEnabled()) {
1407 StringBundler sb = new StringBundler(8);
1408
1409 sb.append("Unable to get primary key for ");
1410 sb.append(clazz);
1411 sb.append(" with UUID ");
1412 sb.append(uuid);
1413 sb.append(" in company group ");
1414 sb.append(companyGroupId);
1415 sb.append(" or in group ");
1416 sb.append(portletDataContext.getScopeGroupId());
1417
1418 _log.warn(sb.toString());
1419 }
1420 }
1421 else {
1422 newValue = StringUtil.replace(
1423 newValue, uuid, newPrimaryKey.toString());
1424 }
1425 }
1426
1427 newValues[i] = newValue;
1428 }
1429
1430 portletPreferences.setValues(key, newValues);
1431 }
1432
1433 @Override
1434 public MissingReferences validateMissingReferences(
1435 long userId, long groupId, Map<String, String[]> parameterMap,
1436 File file)
1437 throws Exception {
1438
1439 final MissingReferences missingReferences = new MissingReferences();
1440
1441 Group group = GroupLocalServiceUtil.getGroup(groupId);
1442 String userIdStrategy = MapUtil.getString(
1443 parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
1444 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
1445
1446 final PortletDataContext portletDataContext =
1447 PortletDataContextFactoryUtil.createImportPortletDataContext(
1448 group.getCompanyId(), groupId, parameterMap,
1449 getUserIdStrategy(userId, userIdStrategy), zipReader);
1450
1451 SAXParser saxParser = new SAXParser();
1452
1453 ElementHandler elementHandler = new ElementHandler(
1454 new ElementProcessor() {
1455
1456 @Override
1457 public void processElement(Element element) {
1458 MissingReference missingReference =
1459 validateMissingReference(portletDataContext, element);
1460
1461 if (missingReference != null) {
1462 missingReferences.add(missingReference);
1463 }
1464 }
1465
1466 },
1467 new String[] {"missing-reference"});
1468
1469 saxParser.setContentHandler(elementHandler);
1470
1471 saxParser.parse(
1472 new InputSource(
1473 portletDataContext.getZipEntryAsInputStream("/manifest.xml")));
1474
1475 return missingReferences;
1476 }
1477
1478 @Override
1479 public void writeManifestSummary(
1480 Document document, ManifestSummary manifestSummary) {
1481
1482 Element rootElement = document.getRootElement();
1483
1484 Element manifestSummaryElement = rootElement.addElement(
1485 "manifest-summary");
1486
1487 for (String manifestSummaryKey :
1488 manifestSummary.getManifestSummaryKeys()) {
1489
1490 Element element = manifestSummaryElement.addElement("staged-model");
1491
1492 element.addAttribute("manifest-summary-key", manifestSummaryKey);
1493
1494 long modelAdditionCount = manifestSummary.getModelAdditionCount(
1495 manifestSummaryKey);
1496
1497 if (modelAdditionCount > 0) {
1498 element.addAttribute(
1499 "addition-count", String.valueOf(modelAdditionCount));
1500 }
1501
1502 long modelDeletionCount = manifestSummary.getModelDeletionCount(
1503 manifestSummaryKey);
1504
1505 if (modelDeletionCount > 0) {
1506 element.addAttribute(
1507 "deletion-count", String.valueOf(modelDeletionCount));
1508 }
1509 }
1510 }
1511
1512 protected Map<String, String[]> getDLReferenceParameters(
1513 PortletDataContext portletDataContext, String content, int beginPos,
1514 int endPos) {
1515
1516 boolean legacyURL = true;
1517 char[] stopChars = _DL_REFERENCE_LEGACY_STOP_CHARS;
1518
1519 if (content.startsWith("/documents/", beginPos)) {
1520 legacyURL = false;
1521 stopChars = _DL_REFERENCE_STOP_CHARS;
1522 }
1523
1524 endPos = StringUtil.indexOfAny(content, stopChars, beginPos, endPos);
1525
1526 if (endPos == -1) {
1527 return null;
1528 }
1529
1530 Map<String, String[]> map = new HashMap<String, String[]>();
1531
1532 String dlReference = content.substring(beginPos, endPos);
1533
1534 while (dlReference.contains(StringPool.AMPERSAND_ENCODED)) {
1535 dlReference = dlReference.replace(
1536 StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
1537 }
1538
1539 if (!legacyURL) {
1540 String[] pathArray = dlReference.split(StringPool.SLASH);
1541
1542 map.put("groupId", new String[] {pathArray[2]});
1543
1544 if (pathArray.length == 4) {
1545 map.put("uuid", new String[] {pathArray[3]});
1546 }
1547 else if (pathArray.length == 5) {
1548 map.put("folderId", new String[] {pathArray[3]});
1549 map.put(
1550 "title", new String[] {HttpUtil.decodeURL(pathArray[4])});
1551 }
1552 else if (pathArray.length > 5) {
1553 map.put("uuid", new String[] {pathArray[5]});
1554 }
1555 }
1556 else {
1557 dlReference = dlReference.substring(
1558 dlReference.indexOf(CharPool.QUESTION) + 1);
1559
1560 map = HttpUtil.parameterMapFromString(dlReference);
1561
1562 if (map.containsKey("img_id")) {
1563 map.put("image_id", map.get("img_id"));
1564 }
1565 else if (map.containsKey("i_id")) {
1566 map.put("image_id", map.get("i_id"));
1567 }
1568 }
1569
1570 map.put("endPos", new String[] {String.valueOf(endPos)});
1571
1572 String groupIdString = MapUtil.getString(map, "groupId");
1573
1574 if (groupIdString.equals("@group_id@")) {
1575 groupIdString = String.valueOf(
1576 portletDataContext.getScopeGroupId());
1577
1578 map.put("groupId", new String[] {groupIdString});
1579 }
1580
1581 return map;
1582 }
1583
1584 protected FileEntry getFileEntry(
1585 PortletDataContext portletDataContext, Map<String, String[]> map) {
1586
1587 if (map == null) {
1588 return null;
1589 }
1590
1591 FileEntry fileEntry = null;
1592
1593 try {
1594 String uuid = MapUtil.getString(map, "uuid");
1595 long groupId = MapUtil.getLong(map, "groupId");
1596
1597 if (Validator.isNotNull(uuid)) {
1598 fileEntry =
1599 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1600 uuid, groupId);
1601 }
1602 else {
1603 if (map.containsKey("folderId")) {
1604 long folderId = MapUtil.getLong(map, "folderId");
1605 String name = MapUtil.getString(map, "name");
1606 String title = MapUtil.getString(map, "title");
1607
1608 if (Validator.isNotNull(title)) {
1609 fileEntry = DLAppLocalServiceUtil.getFileEntry(
1610 groupId, folderId, title);
1611 }
1612 else {
1613 DLFileEntry dlFileEntry =
1614 DLFileEntryLocalServiceUtil.fetchFileEntryByName(
1615 groupId, folderId, name);
1616
1617 if (dlFileEntry != null) {
1618 fileEntry = DLAppLocalServiceUtil.getFileEntry(
1619 dlFileEntry.getFileEntryId());
1620 }
1621 }
1622 }
1623 else if (map.containsKey("image_id")) {
1624 DLFileEntry dlFileEntry =
1625 DLFileEntryLocalServiceUtil.fetchFileEntryByAnyImageId(
1626 MapUtil.getLong(map, "image_id"));
1627
1628 if (dlFileEntry != null) {
1629 fileEntry = DLAppLocalServiceUtil.getFileEntry(
1630 dlFileEntry.getFileEntryId());
1631 }
1632 }
1633 }
1634 }
1635 catch (Exception e) {
1636 if (_log.isDebugEnabled()) {
1637 _log.debug(e, e);
1638 }
1639 else if (_log.isWarnEnabled()) {
1640 _log.warn(e.getMessage());
1641 }
1642 }
1643
1644 return fileEntry;
1645 }
1646
1647 protected UserIdStrategy getUserIdStrategy(
1648 long userId, String userIdStrategy)
1649 throws Exception {
1650
1651 User user = UserLocalServiceUtil.getUserById(userId);
1652
1653 if (UserIdStrategy.ALWAYS_CURRENT_USER_ID.equals(userIdStrategy)) {
1654 return new AlwaysCurrentUserIdStrategy(user);
1655 }
1656
1657 return new CurrentUserIdStrategy(user);
1658 }
1659
1660 protected String replaceExportHostname(
1661 PortletDataContext portletDataContext, String url,
1662 StringBundler urlSB)
1663 throws PortalException, SystemException {
1664
1665 if (!HttpUtil.hasProtocol(url)) {
1666 return url;
1667 }
1668
1669 boolean secure = HttpUtil.isSecure(url);
1670
1671 int portalPort = PortalUtil.getPortalPort(secure);
1672
1673 if (portalPort == -1) {
1674 return url;
1675 }
1676
1677 Group group = GroupLocalServiceUtil.getGroup(
1678 portletDataContext.getScopeGroupId());
1679
1680 LayoutSet publicLayoutSet = group.getPublicLayoutSet();
1681
1682 String publicLayoutSetVirtualHostname =
1683 publicLayoutSet.getVirtualHostname();
1684
1685 String portalUrl = StringPool.BLANK;
1686
1687 if (Validator.isNotNull(publicLayoutSetVirtualHostname)) {
1688 portalUrl = PortalUtil.getPortalURL(
1689 publicLayoutSetVirtualHostname, portalPort, secure);
1690
1691 if (url.startsWith(portalUrl)) {
1692 if (secure) {
1693 urlSB.append(DATA_HANDLER_PUBLIC_LAYOUT_SET_SECURE_URL);
1694 }
1695 else {
1696 urlSB.append(DATA_HANDLER_PUBLIC_LAYOUT_SET_URL);
1697 }
1698
1699 return url.substring(portalUrl.length());
1700 }
1701 }
1702
1703 LayoutSet privateLayoutSet = group.getPrivateLayoutSet();
1704
1705 String privateLayoutSetVirtualHostname =
1706 privateLayoutSet.getVirtualHostname();
1707
1708 if (Validator.isNotNull(privateLayoutSetVirtualHostname)) {
1709 portalUrl = PortalUtil.getPortalURL(
1710 privateLayoutSetVirtualHostname, portalPort, secure);
1711
1712 if (url.startsWith(portalUrl)) {
1713 if (secure) {
1714 urlSB.append(DATA_HANDLER_PRIVATE_LAYOUT_SET_SECURE_URL);
1715 }
1716 else {
1717 urlSB.append(DATA_HANDLER_PRIVATE_LAYOUT_SET_URL);
1718 }
1719
1720 return url.substring(portalUrl.length());
1721 }
1722 }
1723
1724 Company company = CompanyLocalServiceUtil.getCompany(
1725 group.getCompanyId());
1726
1727 String companyVirtualHostname = company.getVirtualHostname();
1728
1729 if (Validator.isNotNull(companyVirtualHostname)) {
1730 portalUrl = PortalUtil.getPortalURL(
1731 companyVirtualHostname, portalPort, secure);
1732
1733 if (url.startsWith(portalUrl)) {
1734 if (secure) {
1735 urlSB.append(DATA_HANDLER_COMPANY_SECURE_URL);
1736 }
1737 else {
1738 urlSB.append(DATA_HANDLER_COMPANY_URL);
1739 }
1740
1741 return url.substring(portalUrl.length());
1742 }
1743 }
1744
1745 portalUrl = PortalUtil.getPortalURL("localhost", portalPort, secure);
1746
1747 if (url.startsWith(portalUrl)) {
1748 return url.substring(portalUrl.length());
1749 }
1750
1751 return url;
1752 }
1753
1754 protected MissingReference validateMissingReference(
1755 PortletDataContext portletDataContext, Element element) {
1756
1757 String className = element.attributeValue("class-name");
1758
1759 StagedModelDataHandler<?> stagedModelDataHandler =
1760 StagedModelDataHandlerRegistryUtil.getStagedModelDataHandler(
1761 className);
1762
1763 if (!stagedModelDataHandler.validateReference(
1764 portletDataContext, element.getParent(), element)) {
1765
1766 return new MissingReference(element);
1767 }
1768
1769 return null;
1770 }
1771
1772 private static final char[] _DL_REFERENCE_LEGACY_STOP_CHARS = {
1773 CharPool.APOSTROPHE, CharPool.CLOSE_BRACKET, CharPool.CLOSE_CURLY_BRACE,
1774 CharPool.CLOSE_PARENTHESIS, CharPool.GREATER_THAN, CharPool.LESS_THAN,
1775 CharPool.PIPE, CharPool.QUOTE, CharPool.SPACE
1776 };
1777
1778 private static final char[] _DL_REFERENCE_STOP_CHARS = {
1779 CharPool.APOSTROPHE, CharPool.CLOSE_BRACKET, CharPool.CLOSE_CURLY_BRACE,
1780 CharPool.CLOSE_PARENTHESIS, CharPool.GREATER_THAN, CharPool.LESS_THAN,
1781 CharPool.PIPE, CharPool.QUESTION, CharPool.QUOTE, CharPool.SPACE
1782 };
1783
1784 private static final char[] _LAYOUT_REFERENCE_STOP_CHARS = {
1785 CharPool.APOSTROPHE, CharPool.CLOSE_BRACKET, CharPool.CLOSE_CURLY_BRACE,
1786 CharPool.CLOSE_PARENTHESIS, CharPool.GREATER_THAN, CharPool.LESS_THAN,
1787 CharPool.PIPE, CharPool.QUESTION, CharPool.QUOTE, CharPool.SPACE
1788 };
1789
1790 private static final String _PRIVATE_GROUP_SERVLET_MAPPING =
1791 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING +
1792 StringPool.SLASH;
1793
1794 private static final String _PRIVATE_USER_SERVLET_MAPPING =
1795 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING +
1796 StringPool.SLASH;
1797
1798 private static final String _PUBLIC_GROUP_SERVLET_MAPPING =
1799 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING +
1800 StringPool.SLASH;
1801
1802 private static Log _log = LogFactoryUtil.getLog(
1803 ExportImportHelperImpl.class);
1804
1805 private Pattern _exportLinksToLayoutPattern = Pattern.compile(
1806 "\\[([0-9]+)@(public|private\\-[a-z]*)\\]");
1807 private Pattern _importLinksToLayoutPattern = Pattern.compile(
1808 "\\[([0-9]+)@(public|private\\-[a-z]*)@(\\p{XDigit}{8}\\-" +
1809 "(?:\\p{XDigit}{4}\\-){3}\\p{XDigit}{12})@([^\\]]*)\\]");
1810
1811 private class ManifestSummaryElementProcessor implements ElementProcessor {
1812
1813 public ManifestSummaryElementProcessor(
1814 Group group, ManifestSummary manifestSummary) {
1815
1816 _group = group;
1817 _manifestSummary = manifestSummary;
1818 }
1819
1820 @Override
1821 public void processElement(Element element) {
1822 String elementName = element.getName();
1823
1824 if (elementName.equals("header")) {
1825 String exportDateString = element.attributeValue("export-date");
1826
1827 Date exportDate = GetterUtil.getDate(
1828 exportDateString,
1829 DateFormatFactoryUtil.getSimpleDateFormat(
1830 Time.RFC822_FORMAT));
1831
1832 _manifestSummary.setExportDate(exportDate);
1833 }
1834 else if (elementName.equals("portlet")) {
1835 String portletId = element.attributeValue("portlet-id");
1836
1837 Portlet portlet = null;
1838
1839 try {
1840 portlet = PortletLocalServiceUtil.getPortletById(
1841 _group.getCompanyId(), portletId);
1842 }
1843 catch (Exception e) {
1844 return;
1845 }
1846
1847 PortletDataHandler portletDataHandler =
1848 portlet.getPortletDataHandlerInstance();
1849
1850 String[] configurationPortletOptions = StringUtil.split(
1851 element.attributeValue("portlet-configuration"));
1852
1853 PortletDataHandlerControl[] portletDataHandlerControls =
1854 portletDataHandler.getImportConfigurationControls(
1855 configurationPortletOptions);
1856
1857 if (ArrayUtil.isNotEmpty(portletDataHandlerControls)) {
1858 _manifestSummary.addConfigurationPortlet(
1859 portlet, configurationPortletOptions);
1860 }
1861
1862 if (!(portletDataHandler instanceof
1863 DefaultConfigurationPortletDataHandler) &&
1864 GetterUtil.getBoolean(
1865 element.attributeValue("portlet-data"))) {
1866
1867 _manifestSummary.addDataPortlet(portlet);
1868 }
1869 }
1870 else if (elementName.equals("staged-model")) {
1871 String manifestSummaryKey = element.attributeValue(
1872 "manifest-summary-key");
1873
1874 long modelAdditionCount = GetterUtil.getLong(
1875 element.attributeValue("addition-count"));
1876
1877 _manifestSummary.addModelAdditionCount(
1878 manifestSummaryKey, modelAdditionCount);
1879
1880 long modelDeletionCount = GetterUtil.getLong(
1881 element.attributeValue("deletion-count"));
1882
1883 _manifestSummary.addModelDeletionCount(
1884 manifestSummaryKey, modelDeletionCount);
1885 }
1886 }
1887
1888 private Group _group;
1889 private ManifestSummary _manifestSummary;
1890
1891 }
1892
1893 }