Package org.jboss.forge.addon.manager.impl

Source Code of org.jboss.forge.addon.manager.impl.InstallRequestImpl

/*
* Copyright 2012 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.jboss.forge.addon.manager.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.Callable;
import java.util.logging.Logger;

import org.jboss.forge.addon.manager.AddonManager;
import org.jboss.forge.addon.manager.InstallRequest;
import org.jboss.forge.addon.manager.impl.filters.DirectAddonFilter;
import org.jboss.forge.addon.manager.impl.filters.LocalResourceFilter;
import org.jboss.forge.container.Forge;
import org.jboss.forge.container.addons.AddonId;
import org.jboss.forge.container.lock.LockMode;
import org.jboss.forge.container.repositories.AddonDependencyEntry;
import org.jboss.forge.container.repositories.AddonRepository;
import org.jboss.forge.container.repositories.MutableAddonRepository;
import org.jboss.forge.container.util.Assert;
import org.jboss.forge.container.util.Predicate;
import org.jboss.forge.dependencies.Coordinate;
import org.jboss.forge.dependencies.DependencyNode;
import org.jboss.forge.dependencies.collection.DependencyNodeUtil;

/**
* When an addon is installed, another addons could be required. This object returns the necessary information for the
* installation of an addon to succeed, like required addons and dependencies
*
* @author <a href="mailto:ggastald@redhat.com">George Gastaldi</a>
*
*/
public class InstallRequestImpl implements InstallRequest
{
   private AddonManager addonManager;
   private Forge forge;

   private DependencyNode requestedAddonNode;
   private Stack<DependencyNode> requiredAddons = new Stack<DependencyNode>();
   private Stack<DependencyNode> optionalAddons = new Stack<DependencyNode>();

   private Logger log = Logger.getLogger(getClass().getName());

   /**
    * Package-access constructor. Only AddonManager should be allowed to call this constructor.
    *
    * @param addonManager
    */
   InstallRequestImpl(AddonManager addonManager, Forge forge, DependencyNode requestedAddonNode)
   {
      this.addonManager = addonManager;
      this.forge = forge;
      this.requestedAddonNode = requestedAddonNode;

      /*
       * To return the addons on which this addon depends, we'll need to traverse the tree using the breadth first
       * order, and then add them to a stack. This will guarantee their order.
       */
      Iterator<DependencyNode> iterator = DependencyNodeUtil.breadthFirstIterator(requestedAddonNode);
      while (iterator.hasNext())
      {
         DependencyNode node = iterator.next();
         if (DependencyNodeUtil.isForgeAddon(node.getDependency().getCoordinate()) && !node.equals(requestedAddonNode))
         {
            if (node.getDependency().isOptional())
            {
               optionalAddons.push(node);
            }
            else
            {
               requiredAddons.push(node);
            }
         }
      }
   }

   @Override
   public DependencyNode getRequestedAddon()
   {
      return this.requestedAddonNode;
   }

   @Override
   public List<DependencyNode> getOptionalAddons()
   {
      return Collections.unmodifiableList(optionalAddons);
   }

   @Override
   public List<DependencyNode> getRequiredAddons()
   {
      return Collections.unmodifiableList(requiredAddons);
   }

   @Override
   public void perform()
   {
      forge.getLockManager().performLocked(LockMode.WRITE, new Callable<AddonId>()
      {
         @Override
         public AddonId call() throws Exception
         {
            for (DependencyNode requiredAddon : getRequiredAddons())
            {
               AddonId requiredAddonId = toAddonId(requiredAddon);
               boolean deployed = false;
               for (AddonRepository repository : forge.getRepositories())
               {
                  if (repository.isDeployed(requiredAddonId))
                  {
                     log.info("Addon " + requiredAddonId + " is already deployed. Skipping...");
                     deployed = true;
                     break;
                  }
               }

               if (!deployed)
               {
                  addonManager.install(requiredAddonId).perform();
               }
            }

            AddonId requestedAddonId = toAddonId(requestedAddonNode);

            for (AddonRepository repository : forge.getRepositories())
            {
               if (repository instanceof MutableAddonRepository)
               {
                  MutableAddonRepository mutableRepository = (MutableAddonRepository) repository;
                  deploy(mutableRepository, requestedAddonId, requestedAddonNode);
                  mutableRepository.enable(requestedAddonId);
                  break;
               }
            }
            return requestedAddonId;
         }
      });
   }

   @Override
   public void perform(final AddonRepository target)
   {
      Assert.isTrue(target instanceof MutableAddonRepository, "Addon repository ["
               + target.getRootDirectory().getAbsolutePath()
               + "] is not writable.");

      forge.getLockManager().performLocked(LockMode.WRITE, new Callable<AddonId>()
      {
         @Override
         public AddonId call() throws Exception
         {
            for (DependencyNode requiredAddon : getRequiredAddons())
            {
               AddonId requiredAddonId = toAddonId(requiredAddon);
               boolean deployed = false;
               for (AddonRepository repository : forge.getRepositories())
               {
                  if (repository.isDeployed(requiredAddonId))
                  {
                     log.info("Addon " + requiredAddonId + " is already deployed. Skipping...");
                     deployed = true;
                     break;
                  }
               }

               if (!deployed)
               {
                  addonManager.install(requiredAddonId).perform(target);
               }
            }

            AddonId requestedAddonId = toAddonId(requestedAddonNode);

            MutableAddonRepository mutableRepository = (MutableAddonRepository) target;
            deploy(mutableRepository, requestedAddonId, requestedAddonNode);
            mutableRepository.enable(requestedAddonId);
            return requestedAddonId;
         }
      });
   }

   private AddonId toAddonId(DependencyNode node)
   {
      Coordinate coord = node.getDependency().getCoordinate();
      DependencyNode forgeApi = DependencyNodeUtil.selectFirst(DependencyNodeUtil.breadthFirstIterator(node),
               new Predicate<DependencyNode>()
               {
                  @Override
                  public boolean accept(DependencyNode node)
                  {
                     Coordinate coordinate = node.getDependency().getCoordinate();
                     return "org.jboss.forge".equals(coordinate.getGroupId())
                              && "forge-addon-container-api".equals(coordinate.getArtifactId());
                  }
               });

      String apiVersion = null;
      if (forgeApi != null)
      {
         apiVersion = forgeApi.getDependency().getCoordinate().getVersion();
      }

      return AddonId.from(coord.getGroupId() + ":" + coord.getArtifactId(), coord.getVersion(), apiVersion);
   }

   private void deploy(MutableAddonRepository repository, AddonId addon, DependencyNode root)
   {
      List<File> resourceJars = toResourceJars(DependencyNodeUtil.select(root, new LocalResourceFilter(root)));

      if (resourceJars.isEmpty())
      {
         log.fine("No resource JARs found for " + addon);
      }
      List<AddonDependencyEntry> addonDependencies =
               toAddonDependencies(DependencyNodeUtil
                        .select(root.getChildren().iterator(), new DirectAddonFilter(root)));

      if (addonDependencies.isEmpty())
      {
         log.fine("No dependencies found for addon " + addon);
      }
      log.info("Deploying addon " + addon);
      repository.deploy(addon, addonDependencies, resourceJars);
   }

   private List<AddonDependencyEntry> toAddonDependencies(List<DependencyNode> dependencies)
   {
      List<AddonDependencyEntry> addonDependencies = new ArrayList<AddonDependencyEntry>();
      for (DependencyNode dep : dependencies)
      {
         boolean export = false;
         boolean optional = dep.getDependency().isOptional();
         String scopeType = dep.getDependency().getScopeType();
         if (scopeType != null && !optional)
         {
            if ("compile".equalsIgnoreCase(scopeType) || "runtime".equalsIgnoreCase(scopeType))
               export = true;
            else if ("provided".equalsIgnoreCase(scopeType))
               export = false;
         }
         AddonDependencyEntry addonDep = AddonDependencyEntry.create(toAddonId(dep), export, optional);
         addonDependencies.add(addonDep);
      }
      return addonDependencies;
   }

   private List<File> toResourceJars(List<DependencyNode> dependencies)
   {
      List<File> result = new ArrayList<File>();
      for (DependencyNode dependency : dependencies)
      {
         result.add(dependency.getDependency().getArtifact().getUnderlyingResourceObject());
      }
      return result;
   }

   @Override
   public String toString()
   {
      return DependencyNodeUtil.prettyPrint(requestedAddonNode, new Predicate<DependencyNode>()
      {
         @Override
         public boolean accept(DependencyNode node)
         {
            return DependencyNodeUtil.isForgeAddon(node.getDependency().getCoordinate())
                     && !node.getDependency().isOptional();
         }
      });
   }
}
TOP

Related Classes of org.jboss.forge.addon.manager.impl.InstallRequestImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.