@Override
  protected void doExportStagedModel(PortletDataContext portletDataContext, WikiPage page)
      throws Exception {

    Element pageElement = portletDataContext.getExportDataElement(page);

    StagedModelDataHandlerUtil.exportReferenceStagedModel(
        portletDataContext, page, page.getNode(), PortletDataContext.REFERENCE_TYPE_PARENT);

    String content =
        _wikiPageExportImportContentProcessor.replaceExportContentReferences(
            portletDataContext,
            page,
            page.getContent(),
            portletDataContext.getBooleanParameter("wiki", "referenced-content"),
            true);

    page.setContent(content);

    if (page.isHead()) {
      for (FileEntry fileEntry : page.getAttachmentsFileEntries()) {
        StagedModelDataHandlerUtil.exportReferenceStagedModel(
            portletDataContext, page, fileEntry, PortletDataContext.REFERENCE_TYPE_WEAK);
      }
    }

    WikiPageResource pageResource =
        _wikiPageResourceLocalService.getPageResource(page.getResourcePrimKey());

    pageElement.addAttribute("page-resource-uuid", pageResource.getUuid());

    portletDataContext.addClassedModel(pageElement, ExportImportPathUtil.getModelPath(page), page);
  }
  @Override
  protected PortletPreferences doImportData(
      PortletDataContext portletDataContext,
      String portletId,
      PortletPreferences portletPreferences,
      String data)
      throws Exception {

    portletDataContext.importPortletPermissions(DDLPermission.RESOURCE_NAME);

    if (portletDataContext.getBooleanParameter(NAMESPACE, "data-definitions")) {

      Element ddmStructuresElement =
          portletDataContext.getImportDataGroupElement(DDMStructure.class);

      List<Element> ddmStructureElements = ddmStructuresElement.elements();

      for (Element ddmStructureElement : ddmStructureElements) {
        StagedModelDataHandlerUtil.importStagedModel(portletDataContext, ddmStructureElement);
      }

      Element ddmTemplatesElement = portletDataContext.getImportDataGroupElement(DDMTemplate.class);

      List<Element> ddmTemplateElements = ddmTemplatesElement.elements();

      for (Element ddmTemplateElement : ddmTemplateElements) {
        StagedModelDataHandlerUtil.importStagedModel(portletDataContext, ddmTemplateElement);
      }
    }

    if (portletDataContext.getBooleanParameter(NAMESPACE, "record-sets")) {
      Element recordSetsElement = portletDataContext.getImportDataGroupElement(DDLRecordSet.class);

      List<Element> recordSetElements = recordSetsElement.elements();

      for (Element recordSetElement : recordSetElements) {
        StagedModelDataHandlerUtil.importStagedModel(portletDataContext, recordSetElement);
      }
    }

    if (portletDataContext.getBooleanParameter(NAMESPACE, "records")) {
      Element recordsElement = portletDataContext.getImportDataGroupElement(DDLRecord.class);

      List<Element> recordElements = recordsElement.elements();

      for (Element recordElement : recordElements) {
        StagedModelDataHandlerUtil.importStagedModel(portletDataContext, recordElement);
      }
    }

    return portletPreferences;
  }
  @Override
  protected PortletPreferences doImportData(
      PortletDataContext portletDataContext,
      String portletId,
      PortletPreferences portletPreferences,
      String data)
      throws Exception {

    portletDataContext.importPortletPermissions(MBPermission.RESOURCE_NAME);

    if (portletDataContext.getBooleanParameter(NAMESPACE, "messages")) {
      Element categoriesElement = portletDataContext.getImportDataGroupElement(MBCategory.class);

      List<Element> categoryElements = categoriesElement.elements();

      for (Element categoryElement : categoryElements) {
        StagedModelDataHandlerUtil.importStagedModel(portletDataContext, categoryElement);
      }

      Element messagesElement = portletDataContext.getImportDataGroupElement(MBMessage.class);

      List<Element> messageElements = messagesElement.elements();

      for (Element messageElement : messageElements) {
        StagedModelDataHandlerUtil.importStagedModel(portletDataContext, messageElement);
      }
    }

    if (portletDataContext.getBooleanParameter(NAMESPACE, "thread-flags")) {
      Element threadFlagsElement = portletDataContext.getImportDataGroupElement(MBThreadFlag.class);

      List<Element> threadFlagElements = threadFlagsElement.elements();

      for (Element threadFlagElement : threadFlagElements) {
        StagedModelDataHandlerUtil.importStagedModel(portletDataContext, threadFlagElement);
      }
    }

    if (portletDataContext.getBooleanParameter(NAMESPACE, "user-bans")) {
      Element userBansElement = portletDataContext.getImportDataGroupElement(MBBan.class);

      List<Element> userBanElements = userBansElement.elements();

      for (Element userBanElement : userBanElements) {
        StagedModelDataHandlerUtil.importStagedModel(portletDataContext, userBanElement);
      }
    }

    return null;
  }
  protected void importAssetLinks(PortletDataContext portletDataContext) throws Exception {

    String xml =
        portletDataContext.getZipEntryAsString(
            ExportImportPathUtil.getSourceRootPath(portletDataContext) + "/links.xml");

    if (xml == null) {
      return;
    }

    Element importDataRootElement = portletDataContext.getImportDataRootElement();

    try {
      Document document = SAXReaderUtil.read(xml);

      Element rootElement = document.getRootElement();

      portletDataContext.setImportDataRootElement(rootElement);

      Element linksElement = portletDataContext.getImportDataGroupElement(StagedAssetLink.class);

      List<Element> linkElements = linksElement.elements();

      for (Element linkElement : linkElements) {
        StagedModelDataHandlerUtil.importStagedModel(portletDataContext, linkElement);
      }
    } finally {
      portletDataContext.setImportDataRootElement(importDataRootElement);
    }
  }
  @Override
  protected void doExportStagedModel(
      PortletDataContext portletDataContext, MDRRuleGroupInstance ruleGroupInstance)
      throws Exception {

    MDRRuleGroup ruleGroup =
        _mdrRuleGroupLocalService.getRuleGroup(ruleGroupInstance.getRuleGroupId());

    StagedModelDataHandlerUtil.exportReferenceStagedModel(
        portletDataContext, ruleGroupInstance, ruleGroup, PortletDataContext.REFERENCE_TYPE_PARENT);

    Element ruleGroupInstanceElement = portletDataContext.getExportDataElement(ruleGroupInstance);

    String className = ruleGroupInstance.getClassName();

    if (className.equals(Layout.class.getName())) {
      Layout layout = _layoutLocalService.getLayout(ruleGroupInstance.getClassPK());

      ruleGroupInstanceElement.addAttribute("layout-uuid", layout.getUuid());
    }

    portletDataContext.addClassedModel(
        ruleGroupInstanceElement,
        ExportImportPathUtil.getModelPath(ruleGroupInstance),
        ruleGroupInstance);
  }
  protected void importLayoutPrototypes(
      PortletDataContext portletDataContext, LayoutSetPrototype layoutSetPrototype)
      throws PortletDataException {

    List<Element> layoutPrototypeElements =
        portletDataContext.getReferenceDataElements(layoutSetPrototype, LayoutPrototype.class);

    for (Element layoutPrototypeElement : layoutPrototypeElements) {
      StagedModelDataHandlerUtil.importStagedModel(portletDataContext, layoutPrototypeElement);
    }
  }
  @Override
  protected void doExportStagedModel(PortletDataContext portletDataContext, Calendar calendar)
      throws Exception {

    StagedModelDataHandlerUtil.exportReferenceStagedModel(
        portletDataContext,
        calendar,
        calendar.getCalendarResource(),
        PortletDataContext.REFERENCE_TYPE_STRONG);

    Element calendarElement = portletDataContext.getExportDataElement(calendar);

    portletDataContext.addClassedModel(
        calendarElement, ExportImportPathUtil.getModelPath(calendar), calendar);
  }
  protected void exportLayout(
      PortletDataContext portletDataContext, long[] layoutIds, Layout layout) throws Exception {

    if (!ArrayUtil.contains(layoutIds, layout.getLayoutId())) {
      Element layoutElement = portletDataContext.getExportDataElement(layout);

      layoutElement.addAttribute(Constants.ACTION, Constants.SKIP);

      return;
    }

    if (!prepareLayoutStagingHandler(portletDataContext, layout)) {
      return;
    }

    StagedModelDataHandlerUtil.exportStagedModel(portletDataContext, layout);
  }
  protected void exportLayoutPrototypes(
      PortletDataContext portletDataContext,
      LayoutSetPrototype layoutSetPrototype,
      Element layoutSetPrototypeElement)
      throws Exception {

    DynamicQuery dynamicQuery = _layoutLocalService.dynamicQuery();

    Property groupIdProperty = PropertyFactoryUtil.forName("groupId");

    dynamicQuery.add(groupIdProperty.eq(layoutSetPrototype.getGroupId()));

    Conjunction conjunction = RestrictionsFactoryUtil.conjunction();

    Property layoutPrototypeUuidProperty = PropertyFactoryUtil.forName("layoutPrototypeUuid");

    conjunction.add(layoutPrototypeUuidProperty.isNotNull());
    conjunction.add(layoutPrototypeUuidProperty.ne(StringPool.BLANK));

    dynamicQuery.add(conjunction);

    List<Layout> layouts = _layoutLocalService.dynamicQuery(dynamicQuery);

    boolean exportLayoutPrototypes =
        portletDataContext.getBooleanParameter("layout_set_prototypes", "page-templates");

    for (Layout layout : layouts) {
      String layoutPrototypeUuid = layout.getLayoutPrototypeUuid();

      LayoutPrototype layoutPrototype =
          _layoutPrototypeLocalService.getLayoutPrototypeByUuidAndCompanyId(
              layoutPrototypeUuid, portletDataContext.getCompanyId());

      portletDataContext.addReferenceElement(
          layout,
          layoutSetPrototypeElement,
          layoutPrototype,
          PortletDataContext.REFERENCE_TYPE_DEPENDENCY,
          !exportLayoutPrototypes);

      if (exportLayoutPrototypes) {
        StagedModelDataHandlerUtil.exportStagedModel(portletDataContext, layoutPrototype);
      }
    }
  }
  @Override
  protected String doExportData(
      final PortletDataContext portletDataContext,
      String portletId,
      PortletPreferences portletPreferences)
      throws Exception {

    portletDataContext.addPortletPermissions(DDLPermission.RESOURCE_NAME);

    Element rootElement = addExportDataRootElement(portletDataContext);

    if (portletDataContext.getBooleanParameter(NAMESPACE, "data-definitions")) {

      List<DDMTemplate> ddmTemplates = new ArrayList<>();

      ActionableDynamicQuery ddmStructureActionableDynamicQuery =
          getDDMStructureActionableDynamicQuery(portletDataContext, ddmTemplates);

      ddmStructureActionableDynamicQuery.performActions();

      for (DDMTemplate ddmTemplate : ddmTemplates) {
        StagedModelDataHandlerUtil.exportStagedModel(portletDataContext, ddmTemplate);
      }
    }

    if (portletDataContext.getBooleanParameter(NAMESPACE, "record-sets")) {
      ActionableDynamicQuery recordSetActionableDynamicQuery =
          _ddlRecordSetLocalService.getExportActionableDynamicQuery(portletDataContext);

      recordSetActionableDynamicQuery.performActions();
    }

    if (portletDataContext.getBooleanParameter(NAMESPACE, "records")) {
      ActionableDynamicQuery recordActionableDynamicQuery =
          getRecordActionableDynamicQuery(portletDataContext);

      recordActionableDynamicQuery.performActions();
    }

    return getExportDataRootElementString(rootElement);
  }
  @Override
  protected void doExportStagedModel(PortletDataContext portletDataContext, MDRAction action)
      throws Exception {

    MDRRuleGroupInstance ruleGroupInstance =
        _mdrRuleGroupInstanceLocalService.getRuleGroupInstance(action.getRuleGroupInstanceId());

    StagedModelDataHandlerUtil.exportReferenceStagedModel(
        portletDataContext, action, ruleGroupInstance, PortletDataContext.REFERENCE_TYPE_PARENT);

    Element actionElement = portletDataContext.getExportDataElement(action);

    String type = action.getType();

    if (type.equals(SiteRedirectActionHandler.class.getName())) {
      UnicodeProperties typeSettingsProperties = action.getTypeSettingsProperties();

      long plid = GetterUtil.getLong(typeSettingsProperties.getProperty("plid"));

      try {
        Layout layout = _layoutLocalService.getLayout(plid);

        actionElement.addAttribute("layout-uuid", layout.getUuid());
      } catch (Exception e) {
        if (_log.isWarnEnabled()) {
          _log.warn(
              "Unable to set the layout uuid of layout "
                  + plid
                  + ". Site redirect may not match after import.",
              e);
        }
      }
    }

    portletDataContext.addClassedModel(
        actionElement, ExportImportPathUtil.getModelPath(action), action);
  }
    @Override
    public void transform(DDMFormFieldValue ddmFormFieldValue) throws PortalException {

      Value value = ddmFormFieldValue.getValue();

      for (Locale locale : value.getAvailableLocales()) {
        String valueString = value.getString(locale);

        JSONObject jsonObject = JSONFactoryUtil.createJSONObject(valueString);

        long groupId = GetterUtil.getLong(jsonObject.get("groupId"));
        String uuid = jsonObject.getString("uuid");

        if ((groupId == 0) || Validator.isNull(uuid)) {
          continue;
        }

        FileEntry fileEntry = _dlAppService.getFileEntryByUuidAndGroupId(uuid, groupId);

        if (_exportReferencedContent) {
          StagedModelDataHandlerUtil.exportReferenceStagedModel(
              _portletDataContext,
              _stagedModel,
              fileEntry,
              _portletDataContext.REFERENCE_TYPE_DEPENDENCY);
        } else {
          Element entityElement = _portletDataContext.getExportDataElement(_stagedModel);

          _portletDataContext.addReferenceElement(
              _stagedModel,
              entityElement,
              fileEntry,
              PortletDataContext.REFERENCE_TYPE_DEPENDENCY,
              true);
        }
      }
    }
  @Override
  protected void performAction(Object object) throws PortalException {
    RepositoryEntry stagedModel = (RepositoryEntry) object;

    StagedModelDataHandlerUtil.exportStagedModel(_portletDataContext, stagedModel);
  }
  @Test
  public void testTypeLinkToLayout() throws Exception {
    initExport();

    Map<String, List<StagedModel>> dependentStagedModelsMap = new HashMap<>();

    Layout linkedLayout = LayoutTestUtil.addLayout(stagingGroup);

    List<LayoutFriendlyURL> linkedLayoutFriendlyURLs =
        LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLs(linkedLayout.getPlid());

    addDependentStagedModel(dependentStagedModelsMap, Layout.class, linkedLayout);

    addDependentLayoutFriendlyURLs(dependentStagedModelsMap, linkedLayout);

    Layout layout =
        LayoutTestUtil.addTypeLinkToLayoutLayout(
            stagingGroup.getGroupId(), linkedLayout.getLayoutId());

    List<LayoutFriendlyURL> layoutFriendlyURLs =
        LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLs(layout.getPlid());

    addDependentLayoutFriendlyURLs(dependentStagedModelsMap, layout);

    StagedModelDataHandlerUtil.exportStagedModel(portletDataContext, layout);

    validateExport(portletDataContext, layout, dependentStagedModelsMap);

    initImport();

    ExportImportLifecycleManagerUtil.fireExportImportLifecycleEvent(
        ExportImportLifecycleConstants.EVENT_LAYOUT_IMPORT_STARTED,
        ExportImportLifecycleConstants.PROCESS_FLAG_LAYOUT_STAGING_IN_PROCESS,
        PortletDataContextFactoryUtil.clonePortletDataContext(portletDataContext));

    Layout exportedLayout = (Layout) readExportedStagedModel(layout);

    StagedModelDataHandlerUtil.importStagedModel(portletDataContext, exportedLayout);

    Layout exportedLinkedLayout = (Layout) readExportedStagedModel(linkedLayout);

    StagedModelDataHandlerUtil.importStagedModel(portletDataContext, exportedLinkedLayout);

    ExportImportLifecycleManagerUtil.fireExportImportLifecycleEvent(
        ExportImportLifecycleConstants.EVENT_LAYOUT_IMPORT_SUCCEEDED,
        ExportImportLifecycleConstants.PROCESS_FLAG_LAYOUT_STAGING_IN_PROCESS,
        PortletDataContextFactoryUtil.clonePortletDataContext(portletDataContext));

    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
        linkedLayout.getUuid(), liveGroup.getGroupId(), false);

    LayoutFriendlyURL linkedLayoutFriendlyURL = linkedLayoutFriendlyURLs.get(0);

    LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLByUuidAndGroupId(
        linkedLayoutFriendlyURL.getUuid(), liveGroup.getGroupId());

    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
        layout.getUuid(), liveGroup.getGroupId(), false);

    LayoutFriendlyURL layoutFriendlyURL = layoutFriendlyURLs.get(0);

    LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLByUuidAndGroupId(
        layoutFriendlyURL.getUuid(), liveGroup.getGroupId());
  }
  @Override
  protected void performAction(Object object) throws PortalException {
    MBBan stagedModel = (MBBan) object;

    StagedModelDataHandlerUtil.exportStagedModel(_portletDataContext, stagedModel);
  }