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