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