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