<commit_before>/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.editors.usergenerated;

import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsResource;
import org.opencms.file.types.I_CmsResourceType;
import org.opencms.lock.CmsLock;
import org.opencms.main.CmsException;
import org.opencms.main.CmsIllegalStateException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.report.CmsLogReport;
import org.opencms.security.CmsPermissionViolationException;
import org.opencms.util.CmsMacroResolver;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;
import org.opencms.xml.CmsXmlException;
import org.opencms.xml.CmsXmlUtils;
import org.opencms.xml.content.CmsXmlContent;
import org.opencms.xml.content.CmsXmlContentErrorHandler;
import org.opencms.xml.content.CmsXmlContentFactory;
import org.opencms.xml.types.I_CmsXmlContentValue;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.logging.Log;

import com.google.common.collect.Maps;

/**
 * A form editing session is required to create and edit contents from the web front-end.<p>
 */
public class CmsFormSession {

    /**
     * Compares XPaths.<p>
     */
    protected static class PathComparator implements Comparator<String> {

        /**
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(String o1, String o2) {

            int result = -1;
            if (o1 == null) {
                result = 1;
            } else if (o2 == null) {
                result = -1;
            } else {
                String[] o1Elements = o1.split("/");
                String[] o2Elements = o2.split("/");
                // compare the path elements
                for (int i = 0; i < o1Elements.length; i++) {
                    String o1Name = CmsXmlUtils.removeXpathIndex(o1Elements[i]);
                    String o2Name = CmsXmlUtils.removeXpathIndex(o2Elements[i]);
                    if (o1Name.equals(o2Name)) {
                        // in case of the same path name, check the indices
                        int o1Index = CmsXmlUtils.getXpathIndexInt(o1Elements[i]);
                        int o2Index = CmsXmlUtils.getXpathIndexInt(o2Elements[i]);
                        if (o1Index != o2Index) {
                            result = o2Index - o1Index;
                            break;
                        } else if (i == (o2Elements.length - 1)) {
                            // in case this is the last element of o2's path
                            result = 1;
                            break;
                        }
                    } else {
                        result = o1Name.compareTo(o2Name);
                        break;
                    }
                }
            }

            return result;
        }
    }

    /** The form upload helper. */
    private CmsFormUploadHelper m_uploadHelper = new CmsFormUploadHelper();

    /** The log instance for this class. */
    private static final Log LOG = CmsLog.getLog(CmsFormSession.class);

    /** The edit context. */
    private CmsObject m_cms;

    /** The form configuration. */
    private CmsFormConfiguration m_configuration;

    /** The resource being edited. */
    private CmsResource m_editResource;

    /** The Admin-privileged CMS context. */
    private CmsObject m_adminCms;

    /** True if the session is finished. */
    private boolean m_finished;

    /** Previously uploaded resources, indexed by field names. */
    private Map<String, CmsResource> m_uploadResourcesByField = Maps.newHashMap();

    /** Flag which indicates whether the project and its resources should be deleted when the session is destroyed. */
    private boolean m_requiresCleanup = true;

    /** 
     * Constructor.<p>
     * 
     * @param cms the cms context
     * @param configuration the form configuration
     * 
     * @throws CmsException if creating the session project fails
     */
    public CmsFormSession(CmsObject cms, CmsFormConfiguration configuration)
    throws CmsException {

        this(cms, cms, configuration);
    }

    /** 
     * Constructor.<p>
     * 
     * @param adminCms the cms context with admin privileges 
     * @param cms the cms context
     * @param configuration the form configuration
     * 
     * @throws CmsException if creating the session project fails
     */
    public CmsFormSession(CmsObject adminCms, CmsObject cms, CmsFormConfiguration configuration)
    throws CmsException {

        m_adminCms = adminCms;
        m_configuration = configuration;
        if (cms.getRequestContext().getCurrentUser().isGuestUser() && m_configuration.getUserForGuests().isPresent()) {
            m_cms = OpenCms.initCmsObject(m_configuration.getUserForGuests().get().getName());
            m_cms.getRequestContext().setSiteRoot(cms.getRequestContext().getSiteRoot());
        } else {
            m_cms = OpenCms.initCmsObject(cms);
        }
        CmsProject project = m_adminCms.createProject(
            generateProjectName(),
            "User generated content project",
            m_configuration.getProjectGroup().getName(),
            m_configuration.getProjectGroup().getName());
        project.setDeleteAfterPublishing(true);
        m_adminCms.writeProject(project);
        m_cms.getRequestContext().setCurrentProject(project);
    }

    /**
     * Constructor. For test purposes only.<p>
     * <commit_msg>Fixing issue with cms object initialization for guest users.<commit_after>/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.editors.usergenerated;

import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsResource;
import org.opencms.file.types.I_CmsResourceType;
import org.opencms.lock.CmsLock;
import org.opencms.main.CmsContextInfo;
import org.opencms.main.CmsException;
import org.opencms.main.CmsIllegalStateException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.report.CmsLogReport;
import org.opencms.security.CmsPermissionViolationException;
import org.opencms.util.CmsMacroResolver;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;
import org.opencms.xml.CmsXmlException;
import org.opencms.xml.CmsXmlUtils;
import org.opencms.xml.content.CmsXmlContent;
import org.opencms.xml.content.CmsXmlContentErrorHandler;
import org.opencms.xml.content.CmsXmlContentFactory;
import org.opencms.xml.types.I_CmsXmlContentValue;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.logging.Log;

import com.google.common.collect.Maps;

/**
 * A form editing session is required to create and edit contents from the web front-end.<p>
 */
public class CmsFormSession {

    /**
     * Compares XPaths.<p>
     */
    protected static class PathComparator implements Comparator<String> {

        /**
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(String o1, String o2) {

            int result = -1;
            if (o1 == null) {
                result = 1;
            } else if (o2 == null) {
                result = -1;
            } else {
                String[] o1Elements = o1.split("/");
                String[] o2Elements = o2.split("/");
                // compare the path elements
                for (int i = 0; i < o1Elements.length; i++) {
                    String o1Name = CmsXmlUtils.removeXpathIndex(o1Elements[i]);
                    String o2Name = CmsXmlUtils.removeXpathIndex(o2Elements[i]);
                    if (o1Name.equals(o2Name)) {
                        // in case of the same path name, check the indices
                        int o1Index = CmsXmlUtils.getXpathIndexInt(o1Elements[i]);
                        int o2Index = CmsXmlUtils.getXpathIndexInt(o2Elements[i]);
                        if (o1Index != o2Index) {
                            result = o2Index - o1Index;
                            break;
                        } else if (i == (o2Elements.length - 1)) {
                            // in case this is the last element of o2's path
                            result = 1;
                            break;
                        }
                    } else {
                        result = o1Name.compareTo(o2Name);
                        break;
                    }
                }
            }

            return result;
        }
    }

    /** The form upload helper. */
    private CmsFormUploadHelper m_uploadHelper = new CmsFormUploadHelper();

    /** The log instance for this class. */
    private static final Log LOG = CmsLog.getLog(CmsFormSession.class);

    /** The edit context. */
    private CmsObject m_cms;

    /** The form configuration. */
    private CmsFormConfiguration m_configuration;

    /** The resource being edited. */
    private CmsResource m_editResource;

    /** The Admin-privileged CMS context. */
    private CmsObject m_adminCms;

    /** True if the session is finished. */
    private boolean m_finished;

    /** Previously uploaded resources, indexed by field names. */
    private Map<String, CmsResource> m_uploadResourcesByField = Maps.newHashMap();

    /** Flag which indicates whether the project and its resources should be deleted when the session is destroyed. */
    private boolean m_requiresCleanup = true;

    /** 
     * Constructor.<p>
     * 
     * @param cms the cms context
     * @param configuration the form configuration
     * 
     * @throws CmsException if creating the session project fails
     */
    public CmsFormSession(CmsObject cms, CmsFormConfiguration configuration)
    throws CmsException {

        this(cms, cms, configuration);
    }

    /** 
     * Constructor.<p>
     * 
     * @param adminCms the cms context with admin privileges 
     * @param cms the cms context
     * @param configuration the form configuration
     * 
     * @throws CmsException if creating the session project fails
     */
    public CmsFormSession(CmsObject adminCms, CmsObject cms, CmsFormConfiguration configuration)
    throws CmsException {

        m_adminCms = adminCms;
        m_configuration = configuration;
        if (cms.getRequestContext().getCurrentUser().isGuestUser() && m_configuration.getUserForGuests().isPresent()) {
            m_cms = OpenCms.initCmsObject(CmsFormModuleAction.getAdminCms(), new CmsContextInfo(
                m_configuration.getUserForGuests().get().getName()));
            m_cms.getRequestContext().setSiteRoot(cms.getRequestContext().getSiteRoot());
        } else {
            m_cms = OpenCms.initCmsObject(cms);
        }
        CmsProject project = m_adminCms.createProject(
            generateProjectName(),
            "User generated content project",
            m_configuration.getProjectGroup().getName(),
            m_configuration.getProjectGroup().getName());
        project.setDeleteAfterPublishing(true);
        m_adminCms.writeProject(project);
        m_cms.getRequestContext().setCurrentProject(project);
    }

    /**
     * Constructor. For test purposes only.<p>
     * 
{'fraction_non_alphanumeric': 0.09060717637715689, 'fraction_numerical': 0.00707530142227998, 'mean_word_length': 2.458676654182272, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2496638', 'n_tokens_mistral': 3938, 'n_tokens_neox': 3809, 'n_words': 1075}