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.portlet.dynamicdatamapping.lar;
016    
017    import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
018    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.lar.BasePortletDataHandler;
021    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
022    import com.liferay.portal.kernel.lar.PortletDataContext;
023    import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
024    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.repository.model.FileEntry;
028    import com.liferay.portal.kernel.util.ArrayUtil;
029    import com.liferay.portal.kernel.util.CharPool;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.HttpUtil;
032    import com.liferay.portal.kernel.util.MapUtil;
033    import com.liferay.portal.kernel.util.StringBundler;
034    import com.liferay.portal.kernel.util.StringPool;
035    import com.liferay.portal.kernel.util.StringUtil;
036    import com.liferay.portal.kernel.util.Validator;
037    import com.liferay.portal.kernel.xml.Element;
038    import com.liferay.portal.model.Group;
039    import com.liferay.portal.model.Layout;
040    import com.liferay.portal.model.RepositoryEntry;
041    import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
042    import com.liferay.portal.service.GroupLocalServiceUtil;
043    import com.liferay.portal.service.LayoutLocalServiceUtil;
044    import com.liferay.portal.util.PortalUtil;
045    import com.liferay.portal.util.PortletKeys;
046    import com.liferay.portal.util.PropsValues;
047    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
048    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
049    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
050    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
051    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
052    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
053    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
054    import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMStructureActionableDynamicQuery;
055    import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMTemplateActionableDynamicQuery;
056    
057    import java.util.ArrayList;
058    import java.util.HashMap;
059    import java.util.List;
060    import java.util.Map;
061    import java.util.regex.Matcher;
062    import java.util.regex.Pattern;
063    
064    import javax.portlet.PortletPreferences;
065    
066    /**
067     * @author Marcellus Tavares
068     * @author Juan Fernández
069     */
070    public class DDMPortletDataHandler extends BasePortletDataHandler {
071    
072            public static final String NAMESPACE = "dynamic_data_mapping";
073    
074            public static String exportReferencedContent(
075                            PortletDataContext portletDataContext,
076                            Element dlFileEntryTypesElement, Element dlFoldersElement,
077                            Element dlFileEntriesElement, Element dlFileRanksElement,
078                            Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
079                            Element entityElement, String content)
080                    throws Exception {
081    
082                    content = exportDLFileEntries(
083                            portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
084                            dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
085                            dlRepositoryEntriesElement, entityElement, content, false);
086                    content = exportLayoutFriendlyURLs(portletDataContext, content);
087                    content = exportLinksToLayout(portletDataContext, content);
088    
089                    String entityElementName = entityElement.getName();
090    
091                    if (!entityElementName.equals("article")) {
092                            content = StringUtil.replace(
093                                    content, StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
094                    }
095    
096                    return content;
097            }
098    
099            public DDMPortletDataHandler() {
100                    setAlwaysExportable(true);
101                    setDataLocalized(true);
102                    setExportControls(
103                            new PortletDataHandlerBoolean(NAMESPACE, "structures", true, true),
104                            new PortletDataHandlerBoolean(NAMESPACE, "templates"));
105            }
106    
107            protected static String exportDLFileEntries(
108                            PortletDataContext portletDataContext,
109                            Element dlFileEntryTypesElement, Element dlFoldersElement,
110                            Element dlFileEntriesElement, Element dlFileRanksElement,
111                            Element dlRepositoriesElement, Element dlRepositoryEntriesElement,
112                            Element entityElement, String content, boolean checkDateRange)
113                    throws Exception {
114    
115                    Group group = GroupLocalServiceUtil.getGroup(
116                            portletDataContext.getGroupId());
117    
118                    if (group.isStagingGroup()) {
119                            group = group.getLiveGroup();
120                    }
121    
122                    if (group.isStaged() && !group.isStagedRemotely() &&
123                            !group.isStagedPortlet(PortletKeys.DOCUMENT_LIBRARY)) {
124    
125                            return content;
126                    }
127    
128                    StringBuilder sb = new StringBuilder(content);
129    
130                    int beginPos = content.length();
131                    int currentLocation = -1;
132    
133                    boolean legacyURL = true;
134    
135                    while (true) {
136                            String contextPath = PortalUtil.getPathContext();
137    
138                            currentLocation = content.lastIndexOf(
139                                    contextPath.concat("/c/document_library/get_file?"), beginPos);
140    
141                            if (currentLocation == -1) {
142                                    currentLocation = content.lastIndexOf(
143                                            contextPath.concat("/image/image_gallery?"), beginPos);
144                            }
145    
146                            if (currentLocation == -1) {
147                                    currentLocation = content.lastIndexOf(
148                                            contextPath.concat("/documents/"), beginPos);
149    
150                                    legacyURL = false;
151                            }
152    
153                            if (currentLocation == -1) {
154                                    return sb.toString();
155                            }
156    
157                            beginPos = currentLocation + contextPath.length();
158    
159                            int endPos1 = content.indexOf(CharPool.APOSTROPHE, beginPos);
160                            int endPos2 = content.indexOf(CharPool.CLOSE_BRACKET, beginPos);
161                            int endPos3 = content.indexOf(CharPool.CLOSE_CURLY_BRACE, beginPos);
162                            int endPos4 = content.indexOf(CharPool.CLOSE_PARENTHESIS, beginPos);
163                            int endPos5 = content.indexOf(CharPool.LESS_THAN, beginPos);
164                            int endPos6 = content.indexOf(CharPool.QUESTION, beginPos);
165                            int endPos7 = content.indexOf(CharPool.QUOTE, beginPos);
166                            int endPos8 = content.indexOf(CharPool.SPACE, beginPos);
167    
168                            int endPos = endPos1;
169    
170                            if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
171                                    endPos = endPos2;
172                            }
173    
174                            if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
175                                    endPos = endPos3;
176                            }
177    
178                            if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
179                                    endPos = endPos4;
180                            }
181    
182                            if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
183                                    endPos = endPos5;
184                            }
185    
186                            if ((endPos == -1) ||
187                                    ((endPos6 != -1) && (endPos6 < endPos) && !legacyURL)) {
188    
189                                    endPos = endPos6;
190                            }
191    
192                            if ((endPos == -1) || ((endPos7 != -1) && (endPos7 < endPos))) {
193                                    endPos = endPos7;
194                            }
195    
196                            if ((endPos == -1) || ((endPos8 != -1) && (endPos8 < endPos))) {
197                                    endPos = endPos8;
198                            }
199    
200                            if ((beginPos == -1) || (endPos == -1)) {
201                                    break;
202                            }
203    
204                            try {
205                                    String oldParameters = content.substring(beginPos, endPos);
206    
207                                    while (oldParameters.contains(StringPool.AMPERSAND_ENCODED)) {
208                                            oldParameters = oldParameters.replace(
209                                                    StringPool.AMPERSAND_ENCODED, StringPool.AMPERSAND);
210                                    }
211    
212                                    Map<String, String[]> map = new HashMap<String, String[]>();
213    
214                                    if (oldParameters.startsWith("/documents/")) {
215                                            String[] pathArray = oldParameters.split(StringPool.SLASH);
216    
217                                            map.put("groupId", new String[] {pathArray[2]});
218    
219                                            if (pathArray.length == 4) {
220                                                    map.put("uuid", new String[] {pathArray[3]});
221                                            }
222                                            else if (pathArray.length == 5) {
223                                                    map.put("folderId", new String[] {pathArray[3]});
224    
225                                                    String title = HttpUtil.decodeURL(pathArray[4]);
226    
227                                                    int pos = title.indexOf(StringPool.QUESTION);
228    
229                                                    if (pos != -1) {
230                                                            title = title.substring(0, pos);
231                                                    }
232    
233                                                    map.put("title", new String[] {title});
234                                            }
235                                            else if (pathArray.length > 5) {
236                                                    String uuid = pathArray[5];
237    
238                                                    int pos = uuid.indexOf(StringPool.QUESTION);
239    
240                                                    if (pos != -1) {
241                                                            uuid = uuid.substring(0, pos);
242                                                    }
243    
244                                                    map.put("uuid", new String[] {uuid});
245                                            }
246                                    }
247                                    else {
248                                            oldParameters = oldParameters.substring(
249                                                    oldParameters.indexOf(CharPool.QUESTION) + 1);
250    
251                                            map = HttpUtil.parameterMapFromString(oldParameters);
252                                    }
253    
254                                    FileEntry fileEntry = null;
255    
256                                    String uuid = MapUtil.getString(map, "uuid");
257    
258                                    if (Validator.isNotNull(uuid)) {
259                                            String groupIdString = MapUtil.getString(map, "groupId");
260    
261                                            long groupId = GetterUtil.getLong(groupIdString);
262    
263                                            if (groupIdString.equals("@group_id@")) {
264                                                    groupId = portletDataContext.getScopeGroupId();
265                                            }
266    
267                                            fileEntry =
268                                                    DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
269                                                            uuid, groupId);
270                                    }
271                                    else {
272                                            String folderIdString = MapUtil.getString(map, "folderId");
273    
274                                            if (Validator.isNotNull(folderIdString)) {
275                                                    long folderId = GetterUtil.getLong(folderIdString);
276                                                    String name = MapUtil.getString(map, "name");
277                                                    String title = MapUtil.getString(map, "title");
278    
279                                                    String groupIdString = MapUtil.getString(
280                                                            map, "groupId");
281    
282                                                    long groupId = GetterUtil.getLong(groupIdString);
283    
284                                                    if (groupIdString.equals("@group_id@")) {
285                                                            groupId = portletDataContext.getScopeGroupId();
286                                                    }
287    
288                                                    if (Validator.isNotNull(title)) {
289                                                            fileEntry = DLAppLocalServiceUtil.getFileEntry(
290                                                                    groupId, folderId, title);
291                                                    }
292                                                    else {
293                                                            DLFileEntry dlFileEntry =
294                                                                    DLFileEntryLocalServiceUtil.getFileEntryByName(
295                                                                            groupId, folderId, name);
296    
297                                                            fileEntry = new LiferayFileEntry(dlFileEntry);
298                                                    }
299                                            }
300                                            else if (map.containsKey("image_id") ||
301                                                             map.containsKey("img_id") ||
302                                                             map.containsKey("i_id")) {
303    
304                                                    long imageId = MapUtil.getLong(map, "image_id");
305    
306                                                    if (imageId <= 0) {
307                                                            imageId = MapUtil.getLong(map, "img_id");
308    
309                                                            if (imageId <= 0) {
310                                                                    imageId = MapUtil.getLong(map, "i_id");
311                                                            }
312                                                    }
313    
314                                                    DLFileEntry dlFileEntry =
315                                                            DLFileEntryLocalServiceUtil.
316                                                                    fetchFileEntryByAnyImageId(imageId);
317    
318                                                    if (dlFileEntry != null) {
319                                                            fileEntry = new LiferayFileEntry(dlFileEntry);
320                                                    }
321                                            }
322                                    }
323    
324                                    if (fileEntry == null) {
325                                            beginPos--;
326    
327                                            continue;
328                                    }
329    
330                                    beginPos = currentLocation;
331    
332                                    StagedModelDataHandlerUtil.exportStagedModel(
333                                            portletDataContext, fileEntry);
334    
335                                    Element dlReferenceElement = entityElement.addElement(
336                                            "dl-reference");
337    
338                                    dlReferenceElement.addAttribute(
339                                            "default-repository",
340                                            String.valueOf(fileEntry.isDefaultRepository()));
341    
342                                    String path = null;
343    
344                                    if (fileEntry.isDefaultRepository()) {
345                                            path = ExportImportPathUtil.getModelPath(
346                                                    (DLFileEntry)fileEntry.getModel());
347    
348                                    }
349                                    else {
350                                            path = ExportImportPathUtil.getModelPath(
351                                                    (RepositoryEntry)fileEntry.getModel());
352                                    }
353    
354                                    dlReferenceElement.addAttribute("path", path);
355    
356                                    String dlReference = "[$dl-reference=" + path + "$]";
357    
358                                    sb.replace(beginPos, endPos, dlReference);
359                            }
360                            catch (Exception e) {
361                                    if (_log.isDebugEnabled()) {
362                                            _log.debug(e, e);
363                                    }
364                                    else if (_log.isWarnEnabled()) {
365                                            _log.warn(e.getMessage());
366                                    }
367                            }
368    
369                            beginPos--;
370                    }
371    
372                    return sb.toString();
373            }
374    
375            protected static String exportLayoutFriendlyURLs(
376                    PortletDataContext portletDataContext, String content) {
377    
378                    Group group = null;
379    
380                    try {
381                            group = GroupLocalServiceUtil.getGroup(
382                                    portletDataContext.getScopeGroupId());
383                    }
384                    catch (Exception e) {
385                            if (_log.isWarnEnabled()) {
386                                    _log.warn(e);
387                            }
388    
389                            return content;
390                    }
391    
392                    StringBuilder sb = new StringBuilder(content);
393    
394                    String privateGroupServletMapping =
395                            PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
396                    String privateUserServletMapping =
397                            PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
398                    String publicServletMapping =
399                            PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
400    
401                    String portalContextPath = PortalUtil.getPathContext();
402    
403                    if (Validator.isNotNull(portalContextPath)) {
404                            privateGroupServletMapping = portalContextPath.concat(
405                                    privateGroupServletMapping);
406                            privateUserServletMapping = portalContextPath.concat(
407                                    privateUserServletMapping);
408                            publicServletMapping = portalContextPath.concat(
409                                    publicServletMapping);
410                    }
411    
412                    String href = "href=";
413    
414                    int beginPos = content.length();
415    
416                    while (true) {
417                            int hrefLength = href.length();
418    
419                            beginPos = content.lastIndexOf(href, beginPos);
420    
421                            if (beginPos == -1) {
422                                    break;
423                            }
424    
425                            char c = content.charAt(beginPos + hrefLength);
426    
427                            if ((c == CharPool.APOSTROPHE) || (c == CharPool.QUOTE)) {
428                                    hrefLength++;
429                            }
430    
431                            int endPos1 = content.indexOf(
432                                    CharPool.APOSTROPHE, beginPos + hrefLength);
433                            int endPos2 = content.indexOf(
434                                    CharPool.CLOSE_BRACKET, beginPos + hrefLength);
435                            int endPos3 = content.indexOf(
436                                    CharPool.CLOSE_CURLY_BRACE, beginPos + hrefLength);
437                            int endPos4 = content.indexOf(
438                                    CharPool.CLOSE_PARENTHESIS, beginPos + hrefLength);
439                            int endPos5 = content.indexOf(
440                                    CharPool.LESS_THAN, beginPos + hrefLength);
441                            int endPos6 = content.indexOf(
442                                    CharPool.QUESTION, beginPos + hrefLength);
443                            int endPos7 = content.indexOf(
444                                    CharPool.QUOTE, beginPos + hrefLength);
445                            int endPos8 = content.indexOf(
446                                    CharPool.SPACE, beginPos + hrefLength);
447    
448                            int endPos = endPos1;
449    
450                            if ((endPos == -1) || ((endPos2 != -1) && (endPos2 < endPos))) {
451                                    endPos = endPos2;
452                            }
453    
454                            if ((endPos == -1) || ((endPos3 != -1) && (endPos3 < endPos))) {
455                                    endPos = endPos3;
456                            }
457    
458                            if ((endPos == -1) || ((endPos4 != -1) && (endPos4 < endPos))) {
459                                    endPos = endPos4;
460                            }
461    
462                            if ((endPos == -1) || ((endPos5 != -1) && (endPos5 < endPos))) {
463                                    endPos = endPos5;
464                            }
465    
466                            if ((endPos == -1) || ((endPos6 != -1) && (endPos6 < endPos))) {
467                                    endPos = endPos6;
468                            }
469    
470                            if ((endPos == -1) || ((endPos7 != -1) && (endPos7 < endPos))) {
471                                    endPos = endPos7;
472                            }
473    
474                            if ((endPos == -1) || ((endPos8 != -1) && (endPos8 < endPos))) {
475                                    endPos = endPos8;
476                            }
477    
478                            if (endPos == -1) {
479                                    beginPos--;
480    
481                                    continue;
482                            }
483    
484                            String url = content.substring(beginPos + hrefLength, endPos);
485    
486                            if (!url.startsWith(privateGroupServletMapping) &&
487                                    !url.startsWith(privateUserServletMapping) &&
488                                    !url.startsWith(publicServletMapping)) {
489    
490                                    beginPos--;
491    
492                                    continue;
493                            }
494    
495                            int contextLength = 0;
496    
497                            if (Validator.isNotNull(portalContextPath)) {
498                                    contextLength = portalContextPath.length();
499                            }
500    
501                            int beginGroupPos = content.indexOf(
502                                    CharPool.SLASH, beginPos + hrefLength + contextLength + 1);
503    
504                            if (beginGroupPos == -1) {
505                                    beginPos--;
506    
507                                    continue;
508                            }
509    
510                            int endGroupPos = content.indexOf(
511                                    CharPool.SLASH, beginGroupPos + 1);
512    
513                            if (endGroupPos == -1) {
514                                    beginPos--;
515    
516                                    continue;
517                            }
518    
519                            String groupFriendlyURL = content.substring(
520                                    beginGroupPos, endGroupPos);
521    
522                            if (groupFriendlyURL.equals(group.getFriendlyURL())) {
523                                    sb.replace(
524                                            beginGroupPos, endGroupPos,
525                                            "@data_handler_group_friendly_url@");
526                            }
527    
528                            String dataHandlerServletMapping = StringPool.BLANK;
529    
530                            if (url.startsWith(privateGroupServletMapping)) {
531                                    dataHandlerServletMapping =
532                                            "@data_handler_private_group_servlet_mapping@";
533                            }
534                            else if (url.startsWith(privateUserServletMapping)) {
535                                    dataHandlerServletMapping =
536                                            "@data_handler_private_user_servlet_mapping@";
537                            }
538                            else {
539                                    dataHandlerServletMapping =
540                                            "@data_handler_public_servlet_mapping@";
541                            }
542    
543                            sb.replace(
544                                    beginPos + hrefLength, beginGroupPos,
545                                    dataHandlerServletMapping);
546    
547                            beginPos--;
548                    }
549    
550                    return sb.toString();
551            }
552    
553            protected static String exportLinksToLayout(
554                            PortletDataContext portletDataContext, String content)
555                    throws Exception {
556    
557                    List<String> oldLinksToLayout = new ArrayList<String>();
558                    List<String> newLinksToLayout = new ArrayList<String>();
559    
560                    Matcher matcher = _exportLinksToLayoutPattern.matcher(content);
561    
562                    while (matcher.find()) {
563                            long layoutId = GetterUtil.getLong(matcher.group(1));
564    
565                            String type = matcher.group(2);
566    
567                            boolean privateLayout = type.startsWith("private");
568    
569                            try {
570                                    Layout layout = LayoutLocalServiceUtil.getLayout(
571                                            portletDataContext.getScopeGroupId(), privateLayout,
572                                            layoutId);
573    
574                                    String oldLinkToLayout = matcher.group(0);
575    
576                                    StringBundler sb = new StringBundler(5);
577    
578                                    sb.append(type);
579                                    sb.append(StringPool.AT);
580                                    sb.append(layout.getUuid());
581                                    sb.append(StringPool.AT);
582                                    sb.append(layout.getFriendlyURL());
583    
584                                    String newLinkToLayout = StringUtil.replace(
585                                            oldLinkToLayout, type, sb.toString());
586    
587                                    oldLinksToLayout.add(oldLinkToLayout);
588                                    newLinksToLayout.add(newLinkToLayout);
589                            }
590                            catch (Exception e) {
591                                    if (_log.isDebugEnabled() || _log.isWarnEnabled()) {
592                                            String message =
593                                                    "Unable to get layout with ID " + layoutId +
594                                                            " in group " + portletDataContext.getScopeGroupId();
595    
596                                            if (_log.isWarnEnabled()) {
597                                                    _log.warn(message);
598                                            }
599                                            else {
600                                                    _log.debug(message, e);
601                                            }
602                                    }
603                            }
604                    }
605    
606                    content = StringUtil.replace(
607                            content, ArrayUtil.toStringArray(oldLinksToLayout.toArray()),
608                            ArrayUtil.toStringArray(newLinksToLayout.toArray()));
609    
610                    return content;
611            }
612    
613            @Override
614            protected PortletPreferences doDeleteData(
615                            PortletDataContext portletDataContext, String portletId,
616                            PortletPreferences portletPreferences)
617                    throws Exception {
618    
619                    if (portletDataContext.addPrimaryKey(
620                                    DDMPortletDataHandler.class, "deleteData")) {
621    
622                            return portletPreferences;
623                    }
624    
625                    DDMTemplateLocalServiceUtil.deleteTemplates(
626                            portletDataContext.getScopeGroupId());
627    
628                    DDMStructureLocalServiceUtil.deleteStructures(
629                            portletDataContext.getScopeGroupId());
630    
631                    return portletPreferences;
632            }
633    
634            @Override
635            protected String doExportData(
636                            final PortletDataContext portletDataContext, String portletId,
637                            PortletPreferences portletPreferences)
638                    throws Exception {
639    
640                    portletDataContext.addPermissions(
641                            "com.liferay.portlet.dynamicdatamapping",
642                            portletDataContext.getScopeGroupId());
643    
644                    Element rootElement = addExportDataRootElement(portletDataContext);
645    
646                    rootElement.addAttribute(
647                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
648    
649                    ActionableDynamicQuery structureActionableDynamicQuery =
650                            new DDMStructureActionableDynamicQuery() {
651    
652                            @Override
653                            protected void addCriteria(DynamicQuery dynamicQuery) {
654                                    portletDataContext.addDateRangeCriteria(
655                                            dynamicQuery, "modifiedDate");
656                            }
657    
658                            @Override
659                            protected void performAction(Object object) throws PortalException {
660                                    DDMStructure structure = (DDMStructure)object;
661    
662                                    StagedModelDataHandlerUtil.exportStagedModel(
663                                            portletDataContext, structure);
664                            }
665    
666                    };
667    
668                    structureActionableDynamicQuery.setGroupId(
669                            portletDataContext.getScopeGroupId());
670    
671                    structureActionableDynamicQuery.performActions();
672    
673                    ActionableDynamicQuery templateActionableDynamicQuery =
674                            new DDMTemplateActionableDynamicQuery() {
675    
676                            @Override
677                            protected void addCriteria(DynamicQuery dynamicQuery) {
678                                    portletDataContext.addDateRangeCriteria(
679                                            dynamicQuery, "modifiedDate");
680                            }
681    
682                            @Override
683                            protected void performAction(Object object) throws PortalException {
684                                    DDMTemplate template = (DDMTemplate)object;
685    
686                                    StagedModelDataHandlerUtil.exportStagedModel(
687                                            portletDataContext, template);
688                            }
689    
690                    };
691    
692                    templateActionableDynamicQuery.setGroupId(
693                            portletDataContext.getScopeGroupId());
694    
695                    templateActionableDynamicQuery.performActions();
696    
697                    return getExportDataRootElementString(rootElement);
698            }
699    
700            @Override
701            protected PortletPreferences doImportData(
702                            PortletDataContext portletDataContext, String portletId,
703                            PortletPreferences portletPreferences, String data)
704                    throws Exception {
705    
706                    portletDataContext.importPermissions(
707                            "com.liferay.portlet.dynamicdatamapping",
708                            portletDataContext.getSourceGroupId(),
709                            portletDataContext.getScopeGroupId());
710    
711                    Element structuresElement =
712                            portletDataContext.getImportDataGroupElement(DDMStructure.class);
713    
714                    List<Element> structureElements = structuresElement.elements();
715    
716                    for (Element structureElement : structureElements) {
717                            StagedModelDataHandlerUtil.importStagedModel(
718                                    portletDataContext, structureElement);
719                    }
720    
721                    if (portletDataContext.getBooleanParameter(NAMESPACE, "templates")) {
722                            Element templatesElement =
723                                    portletDataContext.getImportDataGroupElement(DDMTemplate.class);
724    
725                            List<Element> templateElements = templatesElement.elements();
726    
727                            for (Element templateElement : templateElements) {
728                                    StagedModelDataHandlerUtil.importStagedModel(
729                                            portletDataContext, templateElement);
730                            }
731                    }
732    
733                    return portletPreferences;
734            }
735    
736            private static Log _log = LogFactoryUtil.getLog(
737                    DDMPortletDataHandler.class);
738    
739            private static Pattern _exportLinksToLayoutPattern = Pattern.compile(
740                    "\\[([0-9]+)@(public|private\\-[a-z]*)\\]");
741    
742    }