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