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