private String resolvePluginVersion()

in maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionManager.java [101:307]


    private String resolvePluginVersion( String groupId, String artifactId, MavenProject project, Settings settings,
                                         ArtifactRepository localRepository, boolean resolveAsReportPlugin )
        throws PluginVersionResolutionException, InvalidPluginException, PluginVersionNotFoundException
    {
        // first pass...if the plugin is specified in the pom, try to retrieve the version from there.
        String version = getVersionFromPluginConfig( groupId, artifactId, project, resolveAsReportPlugin );

        // NOTE: We CANNOT check the current project version here, so delay it until later.
        // It will prevent plugins from building themselves, if they are part of the lifecycle mapping.

        // if there was no explicit version, try for one in the reactor
        if ( version == null )
        {
            if ( project.getProjectReferences() != null )
            {
                String refId = ArtifactUtils.versionlessKey( groupId, artifactId );
                MavenProject ref = (MavenProject) project.getProjectReferences().get( refId );
                if ( ref != null )
                {
                    version = ref.getVersion();
                }
            }
        }

        // we're NEVER going to persist POM-derived plugin versions.
        String updatedVersion = null;

        // we're not going to prompt the user to accept a plugin update until we find one.
        boolean promptToPersist = false;

        RuntimeInfo settingsRTInfo = settings.getRuntimeInfo();

        // determine the behavior WRT prompting the user and installing plugin updates.
        Boolean pluginUpdateOverride = settingsRTInfo.getPluginUpdateOverride();

        // second pass...if we're using the plugin registry, and the plugin is listed in the plugin-registry.xml, use
        // the version from <useVersion/>.
        if ( StringUtils.isEmpty( version ) && settings.isUsePluginRegistry() )
        {
            // resolve existing useVersion.
            version = resolveExistingFromPluginRegistry( groupId, artifactId );

            if ( StringUtils.isNotEmpty( version ) )
            {
                // 2. check for updates. Determine whether this is the right time to attempt to update the version.
                // Only check for plugin updates if:
                //
                //  a. the CLI switch to force plugin updates is set, OR BOTH OF THE FOLLOWING:
                //  b. the CLI switch to suppress plugin updates is NOT set, AND
                //  c. the update interval for the plugin has triggered an update check.
                if ( Boolean.TRUE.equals( pluginUpdateOverride )
                    || ( !Boolean.FALSE.equals( pluginUpdateOverride ) && shouldCheckForUpdates( groupId, artifactId ) ) )
                {
                    updatedVersion =
                        resolveMetaVersion( groupId, artifactId, project, localRepository, Artifact.LATEST_VERSION );

                    if ( StringUtils.isNotEmpty( updatedVersion ) && !updatedVersion.equals( version ) )
                    {
                        // see if this version we've resolved is on our previously rejected list.
                        boolean isRejected = checkForRejectedStatus( groupId, artifactId, updatedVersion );

                        // we should only prompt to use this version if the user has not previously rejected it.
                        promptToPersist = !isRejected;

                        // if we've rejected this version previously, forget about updating.
                        if ( isRejected )
                        {
                            updatedVersion = null;
                        }
                        else
                        {
                            getLogger().info(
                                "Plugin \'" + constructPluginKey( groupId, artifactId ) + "\' has updates." );
                        }
                    }
                }
            }
        }

        boolean forcePersist = false;

        // third pass...we're always checking for latest install/deploy, so retrieve the version for LATEST metadata and
        // also set that resolved version as the <useVersion/> in settings.xml.
        if ( StringUtils.isEmpty( version ) )
        {
            // 1. resolve the version to be used
            version = resolveMetaVersion( groupId, artifactId, project, localRepository, Artifact.LATEST_VERSION );

            if ( version != null )
            {
                // 2. Set the updatedVersion so the user will be prompted whether to make this version permanent.
                updatedVersion = version;

                // 3. Persist this version without prompting.
                forcePersist = true;
                promptToPersist = false;
            }
        }

        // final pass...retrieve the version for RELEASE and also set that resolved version as the <useVersion/>
        // in settings.xml.
        if ( StringUtils.isEmpty( version ) )
        {
            // 1. resolve the version to be used
            version = resolveMetaVersion( groupId, artifactId, project, localRepository, Artifact.RELEASE_VERSION );

            if ( version != null )
            {
                // 2. Set the updatedVersion so the user will be prompted whether to make this version permanent.
                updatedVersion = version;

                // 3. Persist this version without prompting.
                forcePersist = true;
                promptToPersist = false;
            }
        }

        // if we're still empty here, and the current project matches the plugin in question, use the current project's
        // version, I guess...
        if ( StringUtils.isEmpty( version ) && project.getGroupId().equals( groupId )
            && project.getArtifactId().equals( artifactId ) )
        {
            version = project.getVersion();
        }

        // if we still haven't found a version, then fail early before we get into the update goop.
        if ( StringUtils.isEmpty( version ) )
        {
            throw new PluginVersionNotFoundException( groupId, artifactId );
        }

        // if the plugin registry is inactive, then the rest of this goop is useless...
        if ( settings.isUsePluginRegistry() )
        {
            // determine whether this build is running in interactive mode
            // If it's not, then we'll defer to the autoUpdate setting from the registry
            // for a decision on updating the plugin in the registry...rather than prompting
            // the user.
            boolean inInteractiveMode = settings.isInteractiveMode();

            // determines what should be done if we're in non-interactive mode.
            // if true, then just update the registry with the new versions.
            String s = getPluginRegistry( groupId, artifactId ).getAutoUpdate();
            boolean autoUpdate = true;
            if ( s != null )
            {
                autoUpdate = Boolean.valueOf( s ).booleanValue();
            }

            // We should persist by default if:
            //
            // 0. RELEASE or LATEST was used to resolve the plugin version (it's not in the registry)
            //
            // -OR-
            //
            // 1. we detected a change in the plugin version from what was in the registry, or
            //      a. the plugin is not registered
            // 2. the pluginUpdateOverride flag has NOT been set to Boolean.FALSE (suppression mode)
            // 3. we're in interactive mode, or
            //      a. the registry is declared to be in autoUpdate mode
            //
            // NOTE: This is only the default value; it may be changed as the result of prompting the user.
            boolean persistUpdate = forcePersist || ( promptToPersist
                && !Boolean.FALSE.equals( pluginUpdateOverride ) && ( inInteractiveMode || autoUpdate ) );

            // retrieve the apply-to-all flag, if it's been set previously.
            Boolean applyToAll = settings.getRuntimeInfo().getApplyToAllPluginUpdates();

            // Incorporate interactive-mode CLI overrides, and previous decisions on apply-to-all, if appropriate.
            //
            // don't prompt if RELEASE or LATEST was used to resolve the plugin version
            // don't prompt if not in interactive mode.
            // don't prompt if the CLI pluginUpdateOverride is set (either suppression or force mode will stop prompting)
            // don't prompt if the user has selected ALL/NONE previously in this session
            //
            // NOTE: We're incorporating here, to make the usages of this check more consistent and
            // resistant to change.
            promptToPersist =
                promptToPersist && pluginUpdateOverride == null && applyToAll == null && inInteractiveMode;

            if ( promptToPersist )
            {
                persistUpdate = promptToPersistPluginUpdate( version, updatedVersion, groupId, artifactId, settings );
            }

            // if it is determined that we should use this version, persist it as useVersion.
            // cases where this version will be persisted:
            // 1. the user is prompted and answers yes or all
            // 2. the user has previously answered all in this session
            // 3. the build is running in non-interactive mode, and the registry setting is for auto-update
            if ( !Boolean.FALSE.equals( applyToAll ) && persistUpdate )
            {
                updatePluginVersionInRegistry( groupId, artifactId, updatedVersion );

                // we're using the updated version of the plugin in this session as well.
                version = updatedVersion;
            }
            // otherwise, if we prompted the user to update, we should treat this as a rejectedVersion, and
            // persist it iff the plugin pre-exists and is in the user-level registry.
            else if ( promptToPersist )
            {
                addNewVersionToRejectedListInExisting( groupId, artifactId, updatedVersion );
            }
        }

        return version;
    }