Merges the page control files and their corresponding bodies into a single files.<p>

@throws CmsImportExportException if something goes wrong
@throws CmsXmlException if the page file could not be unmarshalled
767120
private void mergePageFiles() throws CmsXmlException, CmsImportExportException {

        try {
            // check if the template property exists. If not, create it.
            try {
                m_cms.readPropertyDefinition(CmsPropertyDefinition.PROPERTY_TEMPLATE);
            } catch (CmsException e) {
                // the template propertydefintion does not exist. So create it.
                m_cms.createPropertyDefinition(CmsPropertyDefinition.PROPERTY_TEMPLATE);
            }

            // copy all propertydefinitions of the old page to the new page
            List<CmsPropertyDefinition> definitions = m_cms.readAllPropertyDefinitions();

            Iterator<CmsPropertyDefinition> j = definitions.iterator();
            while (j.hasNext()) {
                CmsPropertyDefinition definition = j.next();
                // check if this propertydef already exits
                try {
                    m_cms.readPropertyDefinition(definition.getName());
                } catch (Exception e) {
                    m_cms.createPropertyDefinition(definition.getName());
                }
            }
        } catch (CmsException e) {

            CmsMessageContainer message = Messages.get().container(
                Messages.ERR_IMPORTEXPORT_ERROR_COPYING_PROPERTY_DEFINITIONS_0);
            if (LOG.isDebugEnabled()) {
                LOG.debug(message.key(), e);
            }

            throw new CmsImportExportException(message);
        }

        // iterate through the list of all page controlfiles found during the import process
        int size = m_pageStorage.size();
        m_report.println(Messages.get().container(Messages.RPT_MERGE_START_0), I_CmsReport.FORMAT_HEADLINE);
        Iterator<String> i = m_pageStorage.iterator();
        int counter = 1;
        while (i.hasNext()) {
            String resname = i.next();
            // adjust the resourcename if nescessary
            if (!resname.startsWith("/")) {
                resname = "/" + resname;
            }

            m_report.print(
                org.opencms.report.Messages.get().container(
                    org.opencms.report.Messages.RPT_SUCCESSION_2,
                    String.valueOf(counter),
                    String.valueOf(size)),
                I_CmsReport.FORMAT_NOTE);
            m_report.print(Messages.get().container(Messages.RPT_MERGE_0), I_CmsReport.FORMAT_NOTE);
            m_report.print(
                org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_ARGUMENT_1, resname));

            mergePageFile(resname);
            if (LOG.isInfoEnabled()) {
                LOG.info(
                    Messages.get().getBundle().key(
                        Messages.LOG_MERGING_3,
                        String.valueOf(counter),
                        String.valueOf(size),
                        resname));
            }

            counter++;

        }
        // free mem
        m_pageStorage.clear();

    }
261092
public CmsFile correctXmlStructure(CmsObject cms) throws CmsXmlException {

        // apply XSD schema translation
        Attribute schema = m_document.getRootElement().attribute(
            I_CmsXmlSchemaType.XSI_NAMESPACE_ATTRIBUTE_NO_SCHEMA_LOCATION);
        if (schema != null) {
            String schemaLocation = schema.getValue();
            String translatedSchema = OpenCms.getResourceManager().getXsdTranslator().translateResource(schemaLocation);
            if (!schemaLocation.equals(translatedSchema)) {
                schema.setValue(translatedSchema);
            }
        }
        updateLocaleNodeSorting();

        // iterate over all locales
        Iterator<Locale> i = m_locales.iterator();
        while (i.hasNext()) {
            Locale locale = i.next();
            List<String> names = getNames(locale);
            List<I_CmsXmlContentValue> validValues = new ArrayList<I_CmsXmlContentValue>();

            // iterate over all nodes per language
            Iterator<String> j = names.iterator();
            while (j.hasNext()) {

                // this step is required for values that need a processing of their content
                // an example for this is the HTML value that does link replacement
                String name = j.next();
                I_CmsXmlContentValue value = getValue(name, locale);
                if (value.isSimpleType()) {
                    String content = value.getStringValue(cms);
                    value.setStringValue(cms, content);
                }

                // save valid elements for later check
                validValues.add(value);
            }

            if (isAutoCorrectionEnabled()) {
                // full correction of XML
                if (validValues.size() < 1) {
                    // no valid element was in the content
                    if (hasLocale(locale)) {
                        // remove the old locale entirely, as there was no valid element
                        removeLocale(locale);
                    }
                    // add a new default locale, this will also generate the default XML as required
                    addLocale(cms, locale);
                } else {
                    // there is at least one valid element in the content

                    List<Element> roots = new ArrayList<Element>();
                    List<CmsXmlContentDefinition> rootCds = new ArrayList<CmsXmlContentDefinition>();
                    List<Element> validElements = new ArrayList<Element>();

                    // gather all XML content definitions and their parent nodes
                    Iterator<I_CmsXmlContentValue> it = validValues.iterator();
                    while (it.hasNext()) {
                        // collect all root elements, also for the nested content definitions
                        I_CmsXmlContentValue value = it.next();
                        Element element = value.getElement();
                        validElements.add(element);
                        if (element.supportsParent()) {
                            // get the parent XML node
                            Element root = element.getParent();
                            if ((root != null) && !roots.contains(root)) {
                                // this is a parent node we do not have already in our storage
                                CmsXmlContentDefinition rcd = value.getContentDefinition();
                                if (rcd != null) {
                                    // this value has a valid XML content definition
                                    roots.add(root);
                                    rootCds.add(rcd);
                                } else {
                                    // no valid content definition for the XML value
                                    throw new CmsXmlException(
                                        Messages.get().container(
                                            Messages.ERR_CORRECT_NO_CONTENT_DEF_3,
                                            value.getName(),
                                            value.getTypeName(),
                                            value.getPath()));
                                }
                            }
                        }
                    }

                    for (int le = 0; le < roots.size(); le++) {
                        // iterate all XML content root nodes and correct each XML subtree

                        Element root = roots.get(le);
                        CmsXmlContentDefinition cd = rootCds.get(le);

                        // step 1: first sort the nodes according to the schema, this takes care of re-ordered elements
                        List<List<Element>> nodeLists = new ArrayList<List<Element>>();
                        boolean isMultipleChoice = cd.getSequenceType() == CmsXmlContentDefinition.SequenceType.MULTIPLE_CHOICE;

                        // if it's a multiple choice element, the child elements must not be sorted into their types,
                        // but must keep their original order
                        if (isMultipleChoice) {
                            List<Element> nodeList = new ArrayList<Element>();
                            List<Element> elements = CmsXmlGenericWrapper.elements(root);
                            Set<String> typeNames = cd.getSchemaTypes();
                            for (Element element : elements) {
                                // check if the node type is still in the definition
                                if (typeNames.contains(element.getName())) {
                                    nodeList.add(element);
                                }
                            }
                            checkMaxOccurs(nodeList, cd.getChoiceMaxOccurs(), cd.getTypeName());
                            nodeLists.add(nodeList);
                        }
                        // if it's a sequence, the children are sorted according to the sequence type definition
                        else {
                            for (I_CmsXmlSchemaType type : cd.getTypeSequence()) {
                                List<Element> elements = CmsXmlGenericWrapper.elements(root, type.getName());
                                checkMaxOccurs(elements, type.getMaxOccurs(), type.getTypeName());
                                nodeLists.add(elements);
                            }
                        }

                        // step 2: clear the list of nodes (this will remove all invalid nodes)
                        List<Element> nodeList = CmsXmlGenericWrapper.elements(root);
                        nodeList.clear();
                        Iterator<List<Element>> in = nodeLists.iterator();
                        while (in.hasNext()) {
                            // now add all valid nodes in the right order
                            List<Element> elements = in.next();
                            nodeList.addAll(elements);
                        }

                        // step 3: now append the missing elements according to the XML content definition
                        cd.addDefaultXml(cms, this, root, locale);
                    }
                }
            }
            initDocument();
        }

        // write the modified XML back to the VFS file
        if (m_file != null) {
            // make sure the file object is available
            m_file.setContents(marshal());
        }
        return m_file;
    }
282561
protected void doLoadNextFile() throws CmsException {

        super.doLoadNextResource();
        if (m_resource == null) {
            return;
        }

        // upgrade the resource to a file
        CmsFile file = m_cms.readFile(m_resource);

        // unmarshal the XML content from the resource, don't use unmarshal(CmsObject, CmsResource)
        // as no support for getting the historic version that has been cached by a CmsHistoryResourceHandler
        // will come from there!
        m_content = CmsXmlContentFactory.unmarshal(m_cms, file, pageContext.getRequest());

        // check if locale is available
        m_contentLocale = m_locale;
        if (!m_content.hasLocale(m_contentLocale)) {
            Iterator<Locale> it = OpenCms.getLocaleManager().getDefaultLocales().iterator();
            while (it.hasNext()) {
                Locale locale = it.next();
                if (m_content.hasLocale(locale)) {
                    // found a matching locale
                    m_contentLocale = locale;
                    break;
                }
            }
        }
    }
945095
public static Map<String, String> mergeDefaults(
        CmsObject cms,
        Map<String, CmsXmlContentProperty> propertyConfig,
        Map<String, String> properties) {

        Map<String, String> result = new HashMap<String, String>();
        if (propertyConfig != null) {
            for (Map.Entry<String, CmsXmlContentProperty> entry : propertyConfig.entrySet()) {
                CmsXmlContentProperty prop = entry.getValue();
                String value = getPropValueIds(cms, prop.getType(), prop.getDefault());
                if (value != null) {
                    result.put(entry.getKey(), value);
                }
            }
        }
        result.putAll(properties);
        return result;
    }
361207
public void importRelations(CmsObject cms) throws CmsException {

        for (CmsResourceImportData resData : m_moduleData.getResourceData()) {
            if (!resData.getRelations().isEmpty()) {
                CmsResource importResource = resData.getImportResource();
                if (importResource != null) {
                    importResource = cms.readResource(importResource.getStructureId(), CmsResourceFilter.ALL);
                    updateRelations(cms, importResource, resData.getRelations());
                }
            }
        }

    }
533575
public CmsFileInput createFileInput() {

        // remove the current file input field and add a new one
        CmsFileInput previous = m_fileInput;
        if (m_fileInput != null) {
            m_fileInput.getElement().getStyle().setDisplay(Display.NONE);
        }
        m_fileInput = new CmsFileInput();
        m_fileInput.addChangeHandler(new ChangeHandler() {

            public void onChange(ChangeEvent event) {

                CmsDomUtil.ensureMouseOut(m_main.getElement());
                m_buttonHandler.onChange(m_fileInput);
            }
        });
        m_buttonHandler.initializeFileInput(m_fileInput);
        m_main.add(m_fileInput);
        return previous;
    }
328193
public void importResources(String importFile, String importPath) throws Exception {

        CmsImportParameters params = new CmsImportParameters(
            OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf(importFile),
            importPath,
            true);

        OpenCms.getImportExportManager().importData(
            m_cms,
            new CmsShellReport(m_cms.getRequestContext().getLocale()),
            params);
    }
211596
public void initPage() throws CmsException {

        if ((m_page == null) && (m_cms != null)) {
            String requestUri = m_cms.getRequestContext().getUri();
            // get the container page itself, checking the history first
            CmsResource pageResource = (CmsResource)CmsHistoryResourceHandler.getHistoryResource(m_request);
            if (pageResource == null) {
                pageResource = m_cms.readResource(requestUri);
            }
            m_page = getPage(pageResource);
            m_page = CmsTemplateMapper.get(m_request).transformContainerpageBean(
                m_cms,
                m_page,
                pageResource.getRootPath());

        }
    }
172437
private List<File> getContainerPagesToPurge(CmsObject cms, CmsUUID targetId) {

        try {
            List<File> purgePages = new ArrayList<File>();
            List<CmsRelation> relations = cms.readRelations(CmsRelationFilter.relationsToStructureId(targetId));
            for (CmsRelation relation : relations) {
                CmsResource source = null;
                try {
                    source = relation.getSource(cms, CmsResourceFilter.ALL);
                } catch (CmsPermissionViolationException e) {
                    // export user can't read the file
                    continue;
                }
                if (CmsResourceTypeXmlContainerPage.isContainerPage(source)) {

                    // purge pages directly containing the content

                    String vfsName = source.getRootPath();
                    String rfsName = OpenCms.getStaticExportManager().getRfsName(cms, vfsName);
                    String exportPath = CmsFileUtil.normalizePath(
                        OpenCms.getStaticExportManager().getExportPath(vfsName));
                    String rfsExportFileName = exportPath
                        + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length());
                    File file = new File(rfsExportFileName);
                    purgePages.add(file);
                } else if (targetId.equals(source.getStructureId())
                    && OpenCms.getResourceManager().getResourceType(source.getTypeId()).getTypeName().equals(
                        CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME)) {
                    LOG.warn(
                        Messages.get().getBundle().key(
                            Messages.LOG_WARN_ELEMENT_GROUP_REFERENCES_SELF_1,
                            source.getRootPath()));
                } else if (OpenCms.getResourceManager().getResourceType(source.getTypeId()).getTypeName().equals(
                    CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME)) {
                    // purge pages containing group containers containing the content

                    purgePages.addAll(getContainerPagesToPurge(cms, source.getStructureId()));
                }
            }
            return purgePages;
        } catch (CmsException e) {
            LOG.error(e.getLocalizedMessage(), e);
            return Collections.emptyList();
        }
    }
1046046
private void setupComboBoxFile() {

        m_target.setInputPrompt(CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_EXPORT_FILE_NAME_EMPTY_0));
        m_target.setNewItemsAllowed(true);
        List<String> files = CmsDbManager.getFileListFromServer(true);
        for (String file : files) {
            m_target.addItem(file);
        }
    }
1075930
@SuppressWarnings("unchecked")
    protected void importUsers() throws CmsImportExportException {

        List<Node> userNodes;
        List<Node> groupNodes;
        List<String> userGroups;
        Element currentElement, currentGroup;
        Map<String, Object> userInfo = null;
        String name, description, flags, password, firstname, lastname, email, address, pwd, infoNode, defaultGroup;
        // try to get the import resource
        //getImportResource();
        try {
            // getAll user nodes
            userNodes = m_docXml.selectNodes("//" + A_CmsImport.N_USERDATA);
            // walk threw all groups in manifest
            for (int i = 0; i < userNodes.size(); i++) {
                currentElement = (Element)userNodes.get(i);
                name = getChildElementTextValue(currentElement, A_CmsImport.N_NAME);
                name = OpenCms.getImportExportManager().translateUser(name);
                // decode passwords using base 64 decoder
                pwd = getChildElementTextValue(currentElement, A_CmsImport.N_PASSWORD);
                password = new String(Base64.decodeBase64(pwd.trim().getBytes()));
                description = getChildElementTextValue(currentElement, A_CmsImport.N_DESCRIPTION);
                flags = getChildElementTextValue(currentElement, A_CmsImport.N_FLAGS);
                firstname = getChildElementTextValue(currentElement, A_CmsImport.N_FIRSTNAME);
                lastname = getChildElementTextValue(currentElement, A_CmsImport.N_LASTNAME);
                email = getChildElementTextValue(currentElement, A_CmsImport.N_EMAIL);
                address = getChildElementTextValue(currentElement, A_CmsImport.N_TAG_ADDRESS);
                defaultGroup = getChildElementTextValue(currentElement, A_CmsImport.N_DEFAULTGROUP);
                // get the userinfo and put it into the additional info map
                infoNode = getChildElementTextValue(currentElement, A_CmsImport.N_USERINFO);
                try {
                    // read the userinfo from the dat-file
                    byte[] value = getFileBytes(infoNode);
                    // deserialize the object
                    ByteArrayInputStream bin = new ByteArrayInputStream(value);
                    ObjectInputStream oin = new ObjectInputStream(bin);
                    userInfo = (Map<String, Object>)oin.readObject();
                } catch (IOException ioex) {
                    m_report.println(ioex);
                } catch (ClassCastException ccex) {
                    m_report.println(ccex);
                } catch (ClassNotFoundException cnfex) {
                    m_report.println(cnfex);
                }
                // in case the user info could not be parsed create a new map
                if (userInfo == null) {
                    userInfo = new HashMap<String, Object>();
                }
                // get the groups of the user and put them into the list
                groupNodes = currentElement.selectNodes("*/" + A_CmsImport.N_GROUPNAME);
                userGroups = new ArrayList<String>();
                for (int j = 0; j < groupNodes.size(); j++) {
                    currentGroup = (Element)groupNodes.get(j);
                    String userInGroup = getChildElementTextValue(currentGroup, A_CmsImport.N_NAME);
                    userInGroup = OpenCms.getImportExportManager().translateGroup(userInGroup);
                    userGroups.add(userInGroup);
                }

                if (CmsStringUtil.isNotEmpty(defaultGroup)) {
                    userInfo.put(CmsUserSettings.ADDITIONAL_INFO_DEFAULTGROUP, defaultGroup);
                }

                if (description != null) {
                    userInfo.put(CmsUserSettings.ADDITIONAL_INFO_DESCRIPTION, description);
                }
                if (address != null) {
                    userInfo.put(CmsUserSettings.ADDITIONAL_INFO_ADDRESS, address);
                }
                // import this user
                importUser(name, flags, password, firstname, lastname, email, 0, userInfo, userGroups);
            }
        } catch (CmsImportExportException e) {
            throw e;
        } catch (Exception e) {
            m_report.println(e);
            CmsMessageContainer message = Messages.get().container(Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_USERS_0);
            if (LOG.isDebugEnabled()) {
                LOG.debug(message.key(), e);
            }
            throw new CmsImportExportException(message, e);
        }
    }
797148
public void upgradeContent(CmsObject cms) throws CmsException {

        if (m_content == null) {
            m_content = cms.readFile(m_resource).getContents();
        }
    }
825816
protected void saveData() throws CmsException {

        CmsObject cms = m_context.getCms();
        for (CmsResource resource : m_context.getResources()) {
            CmsLockActionRecord actionRecord = null;
            try {
                actionRecord = CmsLockUtil.ensureLock(m_context.getCms(), resource);

                String secureValue = (String)m_secureField.getValue();
                String exportValue = (String)m_exportField.getValue();
                String exportname = m_exportNameField.getValue();
                CmsProperty secureProp = new CmsProperty(CmsPropertyDefinition.PROPERTY_SECURE, secureValue, null);
                CmsProperty exportProp = new CmsProperty(CmsPropertyDefinition.PROPERTY_EXPORT, exportValue, null);
                CmsProperty exportNameProp = new CmsProperty(
                    CmsPropertyDefinition.PROPERTY_EXPORTNAME,
                    exportname,
                    null);
                boolean internal = m_internalField.getValue().booleanValue();

                cms.writePropertyObjects(resource, Arrays.asList(secureProp, exportProp, exportNameProp));
                resource.setInternal(internal);
                cms.writeResource(resource);
            } finally {
                if ((actionRecord != null) && (actionRecord.getChange() == LockChange.locked)) {
                    try {
                        cms.unlockResource(resource);
                    } catch (CmsLockException e) {
                        LOG.warn(e.getLocalizedMessage(), e);
                    }
                }
            }
        }
    }
491797
@Override
  public void merge(MergeState mergeState) throws IOException {
    final List<Fields> fields = new ArrayList<>();
    final List<ReaderSlice> slices = new ArrayList<>();

    int docBase = 0;

    for (int readerIndex = 0; readerIndex < mergeState.fieldsProducers.length; readerIndex++) {
      final FieldsProducer f = mergeState.fieldsProducers[readerIndex];

      final int maxDoc = mergeState.maxDocs[readerIndex];
      f.checkIntegrity();
      slices.add(new ReaderSlice(docBase, maxDoc, readerIndex));
      fields.add(f);
      docBase += maxDoc;
    }

    Fields mergedFields = new MappedMultiFields(mergeState,
        new MultiFields(fields.toArray(Fields.EMPTY_ARRAY),
            slices.toArray(ReaderSlice.EMPTY_ARRAY)));
    write(mergedFields);
  }
540928
protected void importGroups() throws CmsImportExportException {

        List<Node> groupNodes;
        Element currentElement;
        String name, description, flags, parentgroup;
        try {
            // getAll group nodes
            groupNodes = m_docXml.selectNodes("//" + A_CmsImport.N_GROUPDATA);
            // walk through all groups in manifest
            for (int i = 0; i < groupNodes.size(); i++) {
                currentElement = (Element)groupNodes.get(i);
                name = getChildElementTextValue(currentElement, A_CmsImport.N_NAME);
                name = OpenCms.getImportExportManager().translateGroup(name);
                description = getChildElementTextValue(currentElement, A_CmsImport.N_DESCRIPTION);
                flags = getChildElementTextValue(currentElement, A_CmsImport.N_FLAGS);
                parentgroup = getChildElementTextValue(currentElement, A_CmsImport.N_PARENTGROUP);
                if ((parentgroup != null) && (parentgroup.length() > 0)) {
                    parentgroup = OpenCms.getImportExportManager().translateGroup(parentgroup);
                }
                // import this group

                importGroup(name, description, flags, parentgroup);
            }

            // now try to import the groups in the stack
            while (!m_groupsToCreate.empty()) {
                Stack<Map<String, String>> tempStack = m_groupsToCreate;
                m_groupsToCreate = new Stack<Map<String, String>>();
                while (tempStack.size() > 0) {
                    Map<String, String> groupdata = tempStack.pop();
                    name = groupdata.get(A_CmsImport.N_NAME);
                    description = groupdata.get(A_CmsImport.N_DESCRIPTION);
                    flags = groupdata.get(A_CmsImport.N_FLAGS);
                    parentgroup = groupdata.get(A_CmsImport.N_PARENTGROUP);
                    // try to import the group
                    importGroup(name, description, flags, parentgroup);
                }
            }
        } catch (CmsImportExportException e) {

            throw e;
        } catch (Exception e) {

            m_report.println(e);

            CmsMessageContainer message = Messages.get().container(Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_GROUPS_0);
            if (LOG.isDebugEnabled()) {
                LOG.debug(message.key(), e);
            }

            throw new CmsImportExportException(message, e);
        }
    }
420160
@SuppressWarnings("null")
    private void init(CmsObject cms) throws Exception {

        CmsFile configFile = cms.readFile(m_resource);
        CmsXmlContent content = CmsXmlContentFactory.unmarshal(cms, configFile);
        m_title = content.getValue(N_TITLE, CmsConfigurationReader.DEFAULT_LOCALE).getStringValue(cms);
        I_CmsXmlContentValue titleKey = content.getValue(N_TITLE_KEY, CmsConfigurationReader.DEFAULT_LOCALE);
        if ((titleKey != null) && CmsStringUtil.isNotEmptyOrWhitespaceOnly(titleKey.getStringValue(cms))) {
            m_titleKey = titleKey.getStringValue(cms);
        }
        I_CmsXmlContentValue orderVal = content.getValue(N_ORDER, CmsConfigurationReader.DEFAULT_LOCALE);
        if (orderVal != null) {
            try {
                m_order = Integer.parseInt(orderVal.getStringValue(cms));
            } catch (Exception e) {
                LOG.error(e.getLocalizedMessage(), e);
                m_order = DEFAULT_ORDER;
            }
        } else {
            m_order = DEFAULT_ORDER;
        }

        I_CmsXmlContentValue parentView = content.getValue("Parent", CmsConfigurationReader.DEFAULT_LOCALE);
        if (parentView != null) {
            CmsUUID parentViewId = null;
            try {
                CmsXmlVarLinkValue elementViewValue = (CmsXmlVarLinkValue)parentView;
                String stringValue = elementViewValue.getStringValue(cms);
                if (CmsStringUtil.isEmpty(stringValue)) {
                    parentViewId = CmsUUID.getNullUUID();
                } else if (stringValue.equals(PARENT_NONE)) {
                    parentViewId = null;
                } else if (stringValue.startsWith(CmsConfigurationReader.VIEW_SCHEME)) {
                    parentViewId = new CmsUUID(stringValue.substring(CmsConfigurationReader.VIEW_SCHEME.length()));
                } else {
                    parentViewId = elementViewValue.getLink(cms).getStructureId();
                }
            } catch (Exception e) {
                LOG.error(e.getLocalizedMessage(), e);
            }
            m_parentViewId = parentViewId;
        }

    }
492127
protected void performSaveContent(String body, Locale locale) throws CmsException {

        // prepare the content for saving
        String content = prepareContent(true);

        String contentConversion = m_page.getConversion();
        // check if cleanup was selected in the editor, we have to add the cleanup parameter
        if (EDITOR_CLEANUP.equals(getParamAction())) {
            if ((contentConversion == null) || (contentConversion.equals(CmsHtmlConverter.PARAM_DISABLED))) {
                // if the current conversion mode is "false" only, we have to remove the "false" value and set it to "cleanup", as "false" will be stronger than all other values
                contentConversion = CmsHtmlConverter.PARAM_WORD;
            } else {
                // add "cleanup" to the already existing values
                contentConversion += ";" + CmsHtmlConverter.PARAM_WORD;
            }
        }
        m_page.setConversion(contentConversion);

        // create the element if necessary and if content is present
        if (!m_page.hasValue(body, locale) && !"".equals(content)) {
            m_page.addValue(body, locale);
        }

        // get the enabled state of the element
        boolean enabled = m_page.isEnabled(body, locale);

        // set the element data
        if (m_page.hasValue(body, locale)) {
            m_page.setStringValue(getCms(), body, locale, content);
        }

        // write the file
        m_file.setContents(m_page.marshal());
        m_file = getCms().writeFile(m_file);

        // content might have been modified during write operation
        m_page = CmsXmlPageFactory.unmarshal(getCms(), m_file);
        if (m_page.hasValue(body, locale)) {
            getCms().getRequestContext().setAttribute(CmsRequestContext.ATTRIBUTE_EDITOR, Boolean.TRUE);
            content = m_page.getStringValue(getCms(), body, locale);
            if (content == null) {
                content = "";
            }
            setParamContent(content);
            prepareContent(false);
            m_page.setEnabled(body, locale, enabled);
        }
    }