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