All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.telenav.cactus.maven.mojobase.SharedProjectTreeMojo Maven / Gradle / Ivy

There is a newer version: 1.5.49
Show newest version
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// © 2011-2022 Telenav, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package com.telenav.cactus.maven.mojobase;

import com.mastfrog.function.optional.ThrowingOptional;
import com.telenav.cactus.git.GitCheckout;
import com.telenav.cactus.maven.shared.SharedDataKey;
import com.telenav.cactus.maven.tree.ProjectTree;
import com.telenav.cactus.maven.trigger.RunPolicy;
import java.util.Optional;
import org.apache.maven.project.MavenProject;

/**
 * Subtype of SharedDataMojo which shares a single (expensive to create)
 * ProjectTree instance all other subtypes of it within a build.
 *
 * @author Tim Boudreau
 */
public abstract class SharedProjectTreeMojo extends BaseMojo
{
    protected SharedProjectTreeMojo(RunPolicy policy)
    {
        super(policy);
    }

    protected SharedProjectTreeMojo()
    {
    }

    protected SharedProjectTreeMojo(boolean oncePerSession)
    {
        super(oncePerSession);
    }

    private SharedDataKey key()
    {
        // It is possible for this mojo to be run either against no git checkout
        // at all, or against a POM where child projects are in non-submodule
        // raw git checkouts underneath a root POM being run.  So, we generate
        // a key for the tree based on the root checkout, so we don't accidentally
        // return the tree for the first requester in the case that there is
        // actually more than one independent git checkout involved in the
        // build.  99.9% of the time, there is only one, but the failure mode
        // if there isn't would be very difficult to diagnose.
        if (session().getAllProjects().size() > 1)
        {
            MavenProject prj = project();
            Optional co = GitCheckout.checkout(prj.getBasedir());
            if (!co.isPresent())
            {
                return TreeHolder.KEY;
            }
            ThrowingOptional subRoot = co.get().submoduleRoot();
            if (!subRoot.isPresent())
            {
                return TreeHolder.KEY;
            }
            return SharedDataKey.of("tree_" + subRoot.get().checkoutRoot(),
                    TreeHolder.class);
        }
        return TreeHolder.KEY;
    }

    @Override
    synchronized ThrowingOptional projectTreeInternal(
            boolean invalidateCache)
    {
        if (tree != null)
        {
            if (tree.isPresent() && invalidateCache)
            {
                tree.get().invalidateCache();;
            }
            return tree;
        }
        TreeHolder holder = sharedData().computeIfAbsent(key(), () ->
        {
            return new TreeHolder(super.projectTreeInternal(false));
        });
        return holder.tree;
    }

    /**
     * Ensures that the key for the project tree is one only this class can
     * construct or access.
     */
    private static final class TreeHolder
    {
        private static final SharedDataKey KEY = SharedDataKey.of(
                "///tree", TreeHolder.class);
        final ThrowingOptional tree;

        public TreeHolder(ThrowingOptional tree)
        {
            this.tree = tree;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy