<commit_before>/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This 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 software 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.xpn.xwiki.store;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.suigeneris.jrcs.rcs.Version;
import org.xwiki.component.annotation.Component;

import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.doc.XWikiDocumentArchive;
import com.xpn.xwiki.doc.rcs.XWikiRCSNodeContent;
import com.xpn.xwiki.doc.rcs.XWikiRCSNodeId;
import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;

/**
 * Realization of {@link XWikiVersioningStoreInterface} for Hibernate-based storage.
 * 
 * @version $Id$
 */
@Component
public class XWikiHibernateVersioningStore extends XWikiHibernateBaseStore implements XWikiVersioningStoreInterface
{
    /** Logger. */
    private static final Log LOG = LogFactory.getLog(XWikiHibernateVersioningStore.class);

    /** Colon symbol. */
    private static final String COLON = ":";

    /**
     * This allows to initialize our storage engine. The hibernate config file path is taken from xwiki.cfg or directly
     * in the WEB-INF directory.
     * 
     * @param xwiki The xwiki object
     * @param context The current context
     * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
     */
    @Deprecated
    public XWikiHibernateVersioningStore(XWiki xwiki, XWikiContext context)
    {
        super(xwiki, context);
    }

    /**
     * Initialize the storage engine with a specific path This is used for tests.
     * 
     * @param hibpath path to hibernate.hbm.xml file
     * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
     */
    @Deprecated
    public XWikiHibernateVersioningStore(String hibpath)
    {
        super(hibpath);
    }

    /**
     * @see #XWikiHibernateVersioningStore(XWiki, XWikiContext)
     * @param context The current context
     * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
     */
    @Deprecated
    public XWikiHibernateVersioningStore(XWikiContext context)
    {
        this(context.getWiki(), context);
    }

    /**
     * Empty constructor needed for component manager.
     */
    public XWikiHibernateVersioningStore()
    {
    }

    /**
     * {@inheritDoc}
     */
    public Version[] getXWikiDocVersions(XWikiDocument doc, XWikiContext context) throws XWikiException
    {
        try {
            XWikiDocumentArchive archive = getXWikiDocumentArchive(doc, context);
            if (archive == null) {
                return new Version[0];
            }
            Collection<XWikiRCSNodeInfo> nodes = archive.getNodes();
            Version[] versions = new Version[nodes.size()];
            Iterator<XWikiRCSNodeInfo> it = nodes.iterator();
            for (int i = 0; i < versions.length; i++) {
                XWikiRCSNodeInfo node = it.next();
                versions[versions.length - 1 - i] = node.getId().getVersion();
            }
            return versions;
        } catch (Exception e) {
            Object[] args = {doc.getFullName()};
            throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
                XWikiException.ERROR_XWIKI_STORE_HIBERNATE_READING_REVISIONS,
                "Exception while reading document {0} revisions", e, args);
        }
    }

    /**
     * {@inheritDoc}
     */
    public XWikiDocumentArchive getXWikiDocumentArchive(XWikiDocument doc, XWikiContext context) throws XWikiException
    {
        String key = ((doc.getDatabase() == null) ? "xwiki" : doc.getDatabase()) + COLON + doc.getFullName();
        if (!"".equals(doc.getLanguage())) {
            key = key + COLON + doc.getLanguage();
        }

        synchronized (key) {
            archiveDoc = context.getDocumentArchive(key);
            if (archiveDoc == null) {
                String db = context.getDatabase();
                try {
                    if (doc.getDatabase() != null) {
                        context.setDatabase(doc.getDatabase());
                    }
                    archiveDoc = new XWikiDocumentArchive(doc.getId());
                    loadXWikiDocArchive(archiveDoc, true, context);
                    doc.setDocumentArchive(archiveDoc);
                } finally {
                    context.setDatabase(db);
                }
                // This will also make sure that the Archive has a strong reference
                // and will not be discarded as long as the context exists.
                context.addDocumentArchive(key, archiveDoc);
            }
            return archiveDoc;
        }<commit_msg>XWIKI-4265: Invocation of com.xpn.xwiki.doc.XWikiDocument#getPreviousVersion produce a NullPointerException  Removed a call which caused an infinite loop. Oops, forgot to add back a declaration.<commit_after>/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This 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 software 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.xpn.xwiki.store;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.suigeneris.jrcs.rcs.Version;
import org.xwiki.component.annotation.Component;

import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.doc.XWikiDocumentArchive;
import com.xpn.xwiki.doc.rcs.XWikiRCSNodeContent;
import com.xpn.xwiki.doc.rcs.XWikiRCSNodeId;
import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;

/**
 * Realization of {@link XWikiVersioningStoreInterface} for Hibernate-based storage.
 * 
 * @version $Id$
 */
@Component
public class XWikiHibernateVersioningStore extends XWikiHibernateBaseStore implements XWikiVersioningStoreInterface
{
    /** Logger. */
    private static final Log LOG = LogFactory.getLog(XWikiHibernateVersioningStore.class);

    /** Colon symbol. */
    private static final String COLON = ":";

    /**
     * This allows to initialize our storage engine. The hibernate config file path is taken from xwiki.cfg or directly
     * in the WEB-INF directory.
     * 
     * @param xwiki The xwiki object
     * @param context The current context
     * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
     */
    @Deprecated
    public XWikiHibernateVersioningStore(XWiki xwiki, XWikiContext context)
    {
        super(xwiki, context);
    }

    /**
     * Initialize the storage engine with a specific path This is used for tests.
     * 
     * @param hibpath path to hibernate.hbm.xml file
     * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
     */
    @Deprecated
    public XWikiHibernateVersioningStore(String hibpath)
    {
        super(hibpath);
    }

    /**
     * @see #XWikiHibernateVersioningStore(XWiki, XWikiContext)
     * @param context The current context
     * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
     */
    @Deprecated
    public XWikiHibernateVersioningStore(XWikiContext context)
    {
        this(context.getWiki(), context);
    }

    /**
     * Empty constructor needed for component manager.
     */
    public XWikiHibernateVersioningStore()
    {
    }

    /**
     * {@inheritDoc}
     */
    public Version[] getXWikiDocVersions(XWikiDocument doc, XWikiContext context) throws XWikiException
    {
        try {
            XWikiDocumentArchive archive = getXWikiDocumentArchive(doc, context);
            if (archive == null) {
                return new Version[0];
            }
            Collection<XWikiRCSNodeInfo> nodes = archive.getNodes();
            Version[] versions = new Version[nodes.size()];
            Iterator<XWikiRCSNodeInfo> it = nodes.iterator();
            for (int i = 0; i < versions.length; i++) {
                XWikiRCSNodeInfo node = it.next();
                versions[versions.length - 1 - i] = node.getId().getVersion();
            }
            return versions;
        } catch (Exception e) {
            Object[] args = {doc.getFullName()};
            throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
                XWikiException.ERROR_XWIKI_STORE_HIBERNATE_READING_REVISIONS,
                "Exception while reading document {0} revisions", e, args);
        }
    }

    /**
     * {@inheritDoc}
     */
    public XWikiDocumentArchive getXWikiDocumentArchive(XWikiDocument doc, XWikiContext context) throws XWikiException
    {
        String key = ((doc.getDatabase() == null) ? "xwiki" : doc.getDatabase()) + COLON + doc.getFullName();
        if (!"".equals(doc.getLanguage())) {
            key = key + COLON + doc.getLanguage();
        }

        synchronized (key) {
            XWikiDocumentArchive archiveDoc = context.getDocumentArchive(key);
            if (archiveDoc == null) {
                String db = context.getDatabase();
                try {
                    if (doc.getDatabase() != null) {
                        context.setDatabase(doc.getDatabase());
                    }
                    archiveDoc = new XWikiDocumentArchive(doc.getId());
                    loadXWikiDocArchive(archiveDoc, true, context);
                    doc.setDocumentArchive(archiveDoc);
                } finally {
                    context.setDatabase(db);
                }
                // This will also make sure that the Archive has a strong reference
                // and will not be discarded as long as the context exists.
                context.addDocumentArchive(key, archiveDoc);
            }
            return archiveDoc;
        }
{'fraction_non_alphanumeric': 0.09026248941574937, 'fraction_numerical': 0.004741744284504657, 'mean_word_length': 2.6375115491222667, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3875954', 'n_tokens_mistral': 3438, 'n_tokens_neox': 3277, 'n_words': 914}