<commit_before>package com.atlassian.plugin.parsers;

import com.atlassian.plugin.ModuleDescriptor;
import com.atlassian.plugin.ModuleDescriptorFactory;
import com.atlassian.plugin.Plugin;
import com.atlassian.plugin.PluginInformation;
import com.atlassian.plugin.PluginParseException;
import com.atlassian.plugin.Resources;
import com.atlassian.plugin.descriptors.UnloadableModuleDescriptor;
import com.atlassian.plugin.descriptors.UnloadableModuleDescriptorFactory;
import com.atlassian.plugin.descriptors.UnrecognisedModuleDescriptor;
import com.atlassian.plugin.descriptors.UnrecognisedModuleDescriptorFactory;
import com.atlassian.plugin.impl.UnloadablePluginFactory;
import com.atlassian.plugin.util.PluginUtils;

import org.apache.commons.lang.Validate;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * Provides access to the descriptor information retrieved from an XML InputStream.
 * <p/>
 * Uses the dom4j {@link SAXReader} to parse the XML stream into a document
 * when the parser is constructed.
 *
 * @see XmlDescriptorParserFactory
 */
public class XmlDescriptorParser implements DescriptorParser
{
    private static final Logger log = LoggerFactory.getLogger(XmlDescriptorParser.class);

    private final Document document;
    private final Set<String> applicationKeys;

    /**
     * Constructs a parser with an already-constructed document
     * @param source the source document
     * @param applicationKeys the application key to filter modules with, null for all unspecified
     * @throws PluginParseException if there is a problem reading the descriptor from the XML {@link InputStream}.
     * @since 2.2.0
     */
    public XmlDescriptorParser(final Document source, final String... applicationKeys) throws PluginParseException
    {
        Validate.notNull(source, "XML descriptor source document cannot be null");
        document = source;
        if (applicationKeys == null)
        {
            this.applicationKeys = Collections.emptySet();
        }
        else
        {
            this.applicationKeys = new HashSet<String>(Arrays.asList(applicationKeys));
        }
    }

    /**
     * Constructs a parser with a stream of an XML document for a specific application
     * @param source The descriptor stream
     * @param applicationKeys the application key to filter modules with, null for all unspecified
     * @throws PluginParseException if there is a problem reading the descriptor from the XML {@link InputStream}.
     * @since 2.2.0
     */
    public XmlDescriptorParser(final InputStream source, final String... applicationKeys) throws PluginParseException
    {
        Validate.notNull(source, "XML descriptor source cannot be null");
        document = createDocument(source);
        if (applicationKeys == null)
        {
            this.applicationKeys = Collections.emptySet();
        }
        else
        {
            this.applicationKeys = new HashSet<String>(Arrays.asList(applicationKeys));
        }
    }

    protected Document createDocument(final InputStream source) throws PluginParseException
    {
        final SAXReader reader = new SAXReader();
        try
        {
            return reader.read(source);
        }
        catch (final DocumentException e)
        {
            throw new PluginParseException("Cannot parse XML plugin descriptor", e);
        }
    }

    protected Document getDocument()
    {
        return document;
    }

    public Plugin configurePlugin(final ModuleDescriptorFactory moduleDescriptorFactory, final Plugin plugin) throws PluginParseException<commit_msg>PLUG-748 XmlDescriptorParser should merge adjacent text nodes<commit_after>package com.atlassian.plugin.parsers;

import com.atlassian.plugin.ModuleDescriptor;
import com.atlassian.plugin.ModuleDescriptorFactory;
import com.atlassian.plugin.Plugin;
import com.atlassian.plugin.PluginInformation;
import com.atlassian.plugin.PluginParseException;
import com.atlassian.plugin.Resources;
import com.atlassian.plugin.descriptors.UnloadableModuleDescriptor;
import com.atlassian.plugin.descriptors.UnloadableModuleDescriptorFactory;
import com.atlassian.plugin.descriptors.UnrecognisedModuleDescriptor;
import com.atlassian.plugin.descriptors.UnrecognisedModuleDescriptorFactory;
import com.atlassian.plugin.impl.UnloadablePluginFactory;
import com.atlassian.plugin.util.PluginUtils;

import org.apache.commons.lang.Validate;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * Provides access to the descriptor information retrieved from an XML InputStream.
 * <p/>
 * Uses the dom4j {@link SAXReader} to parse the XML stream into a document
 * when the parser is constructed.
 *
 * @see XmlDescriptorParserFactory
 */
public class XmlDescriptorParser implements DescriptorParser
{
    private static final Logger log = LoggerFactory.getLogger(XmlDescriptorParser.class);

    private final Document document;
    private final Set<String> applicationKeys;

    /**
     * Constructs a parser with an already-constructed document
     * @param source the source document
     * @param applicationKeys the application key to filter modules with, null for all unspecified
     * @throws PluginParseException if there is a problem reading the descriptor from the XML {@link InputStream}.
     * @since 2.2.0
     */
    public XmlDescriptorParser(final Document source, final String... applicationKeys) throws PluginParseException
    {
        Validate.notNull(source, "XML descriptor source document cannot be null");
        document = source;
        if (applicationKeys == null)
        {
            this.applicationKeys = Collections.emptySet();
        }
        else
        {
            this.applicationKeys = new HashSet<String>(Arrays.asList(applicationKeys));
        }
    }

    /**
     * Constructs a parser with a stream of an XML document for a specific application
     * @param source The descriptor stream
     * @param applicationKeys the application key to filter modules with, null for all unspecified
     * @throws PluginParseException if there is a problem reading the descriptor from the XML {@link InputStream}.
     * @since 2.2.0
     */
    public XmlDescriptorParser(final InputStream source, final String... applicationKeys) throws PluginParseException
    {
        Validate.notNull(source, "XML descriptor source cannot be null");
        document = createDocument(source);
        if (applicationKeys == null)
        {
            this.applicationKeys = Collections.emptySet();
        }
        else
        {
            this.applicationKeys = new HashSet<String>(Arrays.asList(applicationKeys));
        }
    }

    protected Document createDocument(final InputStream source) throws PluginParseException
    {
        final SAXReader reader = new SAXReader();
        reader.setMergeAdjacentText(true);
        try
        {
            return reader.read(source);
        }
        catch (final DocumentException e)
        {
            throw new PluginParseException("Cannot parse XML plugin descriptor", e);
        }
    }

    protected Document getDocument()
    {
        return document;
    }

    public Plugin configurePlugin(final ModuleDescriptorFactory moduleDescriptorFactory, final Plugin plugin) throws PluginParseException
{'fraction_non_alphanumeric': 0.07529621607848133, 'fraction_numerical': 0.003694738183208052, 'mean_word_length': 3.490846681922197, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '1378285', 'n_tokens_mistral': 2018, 'n_tokens_neox': 1983, 'n_words': 592}