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