<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 org.xwiki.extension.script.internal;

import java.util.Collection;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.apache.commons.lang3.StringUtils;
import org.xwiki.bridge.DocumentAccessBridge;
import org.xwiki.component.annotation.Component;
import org.xwiki.context.Execution;
import org.xwiki.extension.CoreExtension;
import org.xwiki.extension.Extension;
import org.xwiki.extension.ExtensionId;
import org.xwiki.extension.ExtensionManager;
import org.xwiki.extension.LocalExtension;
import org.xwiki.extension.internal.VersionManager;
import org.xwiki.extension.job.InstallRequest;
import org.xwiki.extension.job.Job;
import org.xwiki.extension.job.JobException;
import org.xwiki.extension.job.JobManager;
import org.xwiki.extension.job.JobStatus;
import org.xwiki.extension.job.UninstallRequest;
import org.xwiki.extension.repository.CoreExtensionRepository;
import org.xwiki.extension.repository.ExtensionRepositoryManager;
import org.xwiki.extension.repository.LocalExtensionRepository;
import org.xwiki.extension.unmodifiable.UnmodifiableJobStatus;
import org.xwiki.extension.unmodifiable.UnmodifiableUtils;
import org.xwiki.script.service.ScriptService;

/**
 * Entry point of extension manager from scripts.
 * 
 * @version $Id$
 */
@Component
@Named("extension")
@Singleton
public class ExtensionManagerScriptService implements ScriptService
{
    /** The key under which the last encountered error is stored in the current execution context. */
    private static final String EXTENSIONERROR_KEY = "extensionerror";

    /** The real extension manager bridged by this script service. */
    @Inject
    private ExtensionManager extensionManager;

    /** Also exposed by the brige. */
    @Inject
    private VersionManager versionManager;

    /** Needed for checking programming rights. */
    @Inject
    private DocumentAccessBridge documentAccessBridge;

    /** The repository with custom installed extensions. */
    @Inject
    private LocalExtensionRepository localExtensionRepository;

    /** The repository with core modules provided by the platform. */
    @Inject
    private CoreExtensionRepository coreExtensionRepository;

    /** Repository manager, needed for cross-repository operations. */
    @Inject
    private ExtensionRepositoryManager repositoryManager;

    /** Handles and provides status feedback on extension operations (installation, upgrade, removal). */
    @Inject
    private JobManager taskManager;

    /** Provides access to the current context. */
    @Inject
    private Execution execution;

    /**
     * Gives access to the {@link VersionManager} for version utility methods.
     * 
     * @return the default version manager
     */
    public VersionManager getVersionManager()
    {
        return this.versionManager;
    }

    // Extensions

    /**
     * Search among all {@link org.xwiki.extension.repository.Searchable} repositories for extensions matching the
     * search terms.
     * 
     * @param pattern the words to search for
     * @param offset the offset from where to start returning search results, 0-based
     * @param nb the maximum number of search results to return
     * @return the found extensions descriptors, empty list if nothing could be found
     * @see org.xwiki.extension.repository.Searchable
     */
    public Collection<Extension> search(String pattern, int offset, int nb)
    {
        return UnmodifiableUtils.unmodifiableExtensions(this.repositoryManager.search(pattern, offset, nb));
    }

    /**
     * Get the extension handler corresponding to the given extension ID (groupID:artifactId) and version. The returned
     * handler can be used to get more information about the extension, such as the authors, an extension description,
     * its license...
     * 
     * @param id the extension id or provided feature (virtual extension) of the extension to resolve
     * @param version the specific version to resolve
     * @return the read-only handler corresponding to the requested extension, or {@code null} if the extension couldn't
     *         be resolved, in which case {@link #getLastError()} contains the failure reason
     */
    public Extension resolve(String id, String version)
    {
        setError(null);

        Extension extension = null;

        try {
            extension =
                UnmodifiableUtils.unmodifiableExtension(this.extensionManager
                    .resolveExtension(new ExtensionId(id, version)));
        } catch (Exception e) {
            setError(e);
        }

        return extension;
    }

    /**
     * Get a list of all currently installed extensions. This doesn't include core extensions, only custom extensions
     * installed by the administrators.
     * 
     * @return a list of read-only handlers corresponding to the installed extensions, an empty list if nothing is
     *         installed
     */
    public Collection<LocalExtension> getInstalledExtensions()
    {
        return UnmodifiableUtils.unmodifiableExtensions(this.localExtensionRepository.getInstalledExtensions());
    }

    /**
     * Get a list of currently installed extensions for the given namespace. This doesn't include core extensions, only
     * custom extensions installed by the administrators .
     * 
     * @param namespace the target namespace (virtual wiki name) for which to retrieve the list of installed extensions
     * @return a list of read-only handlers corresponding to the installed extensions, an empty list if nothing is
     *         installed in the target namespace
     */
    public Collection<LocalExtension> getInstalledExtensions(String namespace)
    {
        return UnmodifiableUtils.unmodifiableExtensions(this.localExtensionRepository.getInstalledExtensions(namespace));
    }

    /**
     * Get the extension handler corresponding to the given installed extension ID (groupID:artifactId) and namespace.
     * The returned handler can be used to get more information about the extension, such as the authors, an extension
     * description, its license...
     * 
     * @param id the extension id or provided feature (virtual extension) of the extension to resolve
     * @param namespace the optional namespace (wiki name) where the extension should be installed
     * @return the read-only handler corresponding to the requested extension, or {@code null} if the extension isn't
     *         installed in the target namespace
     */
    public LocalExtension getInstalledExtension(String id, String namespace)
    {
        return UnmodifiableUtils.unmodifiableExtension(this.localExtensionRepository.getInstalledExtension(id, namespace));
    }

    /**
     * Get a list of core extensions provided by the current version of the platform.
     * 
     * @return a list of read-only handlers corresponding to the core extensions
     */
    public Collection<CoreExtension> getCoreExtensions()
    {
        return UnmodifiableUtils.unmodifiableExtensions(this.coreExtensionRepository.getCoreExtensions());
    }

    /**
     * Get the extension handler corresponding to the given core extension ID (groupID:artifactId). The returned handler
     * can be used to get more information about the extension, such as the authors, an extension description, its
     * license...
     * 
     * @param id the extension id or provided feature (virtual extension) of the extension to resolve
     * @return the read-only handler corresponding to the requested extension, or {@code null} if the extension isn't
     *         provided by the platform
     */
    public CoreExtension getCoreExtension(String id)
    {<commit_msg>XWIKI-7158: Several security holes in the extension script service API Fix checkstyle<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 org.xwiki.extension.script.internal;

import java.util.Collection;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.apache.commons.lang3.StringUtils;
import org.xwiki.bridge.DocumentAccessBridge;
import org.xwiki.component.annotation.Component;
import org.xwiki.context.Execution;
import org.xwiki.extension.CoreExtension;
import org.xwiki.extension.Extension;
import org.xwiki.extension.ExtensionId;
import org.xwiki.extension.ExtensionManager;
import org.xwiki.extension.LocalExtension;
import org.xwiki.extension.internal.VersionManager;
import org.xwiki.extension.job.InstallRequest;
import org.xwiki.extension.job.Job;
import org.xwiki.extension.job.JobException;
import org.xwiki.extension.job.JobManager;
import org.xwiki.extension.job.JobStatus;
import org.xwiki.extension.job.UninstallRequest;
import org.xwiki.extension.repository.CoreExtensionRepository;
import org.xwiki.extension.repository.ExtensionRepositoryManager;
import org.xwiki.extension.repository.LocalExtensionRepository;
import org.xwiki.extension.unmodifiable.UnmodifiableJobStatus;
import org.xwiki.extension.unmodifiable.UnmodifiableUtils;
import org.xwiki.script.service.ScriptService;

/**
 * Entry point of extension manager from scripts.
 * 
 * @version $Id$
 */
@Component
@Named("extension")
@Singleton
public class ExtensionManagerScriptService implements ScriptService
{
    /** The key under which the last encountered error is stored in the current execution context. */
    private static final String EXTENSIONERROR_KEY = "extensionerror";

    /** The real extension manager bridged by this script service. */
    @Inject
    private ExtensionManager extensionManager;

    /** Also exposed by the brige. */
    @Inject
    private VersionManager versionManager;

    /** Needed for checking programming rights. */
    @Inject
    private DocumentAccessBridge documentAccessBridge;

    /** The repository with custom installed extensions. */
    @Inject
    private LocalExtensionRepository localExtensionRepository;

    /** The repository with core modules provided by the platform. */
    @Inject
    private CoreExtensionRepository coreExtensionRepository;

    /** Repository manager, needed for cross-repository operations. */
    @Inject
    private ExtensionRepositoryManager repositoryManager;

    /** Handles and provides status feedback on extension operations (installation, upgrade, removal). */
    @Inject
    private JobManager taskManager;

    /** Provides access to the current context. */
    @Inject
    private Execution execution;

    /**
     * Gives access to the {@link VersionManager} for version utility methods.
     * 
     * @return the default version manager
     */
    public VersionManager getVersionManager()
    {
        return this.versionManager;
    }

    // Extensions

    /**
     * Search among all {@link org.xwiki.extension.repository.Searchable} repositories for extensions matching the
     * search terms.
     * 
     * @param pattern the words to search for
     * @param offset the offset from where to start returning search results, 0-based
     * @param nb the maximum number of search results to return
     * @return the found extensions descriptors, empty list if nothing could be found
     * @see org.xwiki.extension.repository.Searchable
     */
    public Collection<Extension> search(String pattern, int offset, int nb)
    {
        return UnmodifiableUtils.unmodifiableExtensions(this.repositoryManager.search(pattern, offset, nb));
    }

    /**
     * Get the extension handler corresponding to the given extension ID (groupID:artifactId) and version. The returned
     * handler can be used to get more information about the extension, such as the authors, an extension description,
     * its license...
     * 
     * @param id the extension id or provided feature (virtual extension) of the extension to resolve
     * @param version the specific version to resolve
     * @return the read-only handler corresponding to the requested extension, or {@code null} if the extension couldn't
     *         be resolved, in which case {@link #getLastError()} contains the failure reason
     */
    public Extension resolve(String id, String version)
    {
        setError(null);

        Extension extension = null;

        try {
            extension =
                UnmodifiableUtils.unmodifiableExtension(this.extensionManager.resolveExtension(new ExtensionId(id,
                    version)));
        } catch (Exception e) {
            setError(e);
        }

        return extension;
    }

    /**
     * Get a list of all currently installed extensions. This doesn't include core extensions, only custom extensions
     * installed by the administrators.
     * 
     * @return a list of read-only handlers corresponding to the installed extensions, an empty list if nothing is
     *         installed
     */
    public Collection<LocalExtension> getInstalledExtensions()
    {
        return UnmodifiableUtils.unmodifiableExtensions(this.localExtensionRepository.getInstalledExtensions());
    }

    /**
     * Get a list of currently installed extensions for the given namespace. This doesn't include core extensions, only
     * custom extensions installed by the administrators .
     * 
     * @param namespace the target namespace (virtual wiki name) for which to retrieve the list of installed extensions
     * @return a list of read-only handlers corresponding to the installed extensions, an empty list if nothing is
     *         installed in the target namespace
     */
    public Collection<LocalExtension> getInstalledExtensions(String namespace)
    {
        return UnmodifiableUtils
            .unmodifiableExtensions(this.localExtensionRepository.getInstalledExtensions(namespace));
    }

    /**
     * Get the extension handler corresponding to the given installed extension ID (groupID:artifactId) and namespace.
     * The returned handler can be used to get more information about the extension, such as the authors, an extension
     * description, its license...
     * 
     * @param id the extension id or provided feature (virtual extension) of the extension to resolve
     * @param namespace the optional namespace (wiki name) where the extension should be installed
     * @return the read-only handler corresponding to the requested extension, or {@code null} if the extension isn't
     *         installed in the target namespace
     */
    public LocalExtension getInstalledExtension(String id, String namespace)
    {
        return UnmodifiableUtils.unmodifiableExtension(this.localExtensionRepository.getInstalledExtension(id,
            namespace));
    }

    /**
     * Get a list of core extensions provided by the current version of the platform.
     * 
     * @return a list of read-only handlers corresponding to the core extensions
     */
    public Collection<CoreExtension> getCoreExtensions()
    {
        return UnmodifiableUtils.unmodifiableExtensions(this.coreExtensionRepository.getCoreExtensions());
    }

    /**
     * Get the extension handler corresponding to the given core extension ID (groupID:artifactId). The returned handler
     * can be used to get more information about the extension, such as the authors, an extension description, its
     * license...
     * 
     * @param id the extension id or provided feature (virtual extension) of the extension to resolve
     * @return the read-only handler corresponding to the requested extension, or {@code null} if the extension isn't
     *         provided by the platform
     */
    public CoreExtension getCoreExtension(String id)
    {
{'fraction_non_alphanumeric': 0.06906491410123371, 'fraction_numerical': 0.0019601060763288366, 'mean_word_length': 3.462824800617443, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '2660524', 'n_tokens_mistral': 4174, 'n_tokens_neox': 4059, 'n_words': 1653}