package org.jboss.windup.graph.traversal;
import com.google.common.base.Function;
import org.jboss.windup.graph.model.ProjectModel;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import java.util.logging.Logger;
import org.jboss.windup.graph.service.ProjectService;
/**
* <p>
* Provides a traversal over children that are shared across multiple applications
* (i.e. those which are contained in the 'shared-libs' project);
* if duplicated within the given application, it takes only one instance.
* </p>
*
* <p>
* Put another way, if we have a ProjectModel's forrest that looks like this:
* <ul>
* <li>root.ear</li>
* <ul>
* <li>WEB-INF/lib/duplicated.jar</li>
* <li>WEB-INF/lib/other.jar</li>
* </ul>
* </li>
* <li>duplicated.war</li>
* <li>duplicated.jar</li>
* </ul>
*
* <ul>
* <li>root2.ear</li>
* <ul>
* <li>WEB-INF/lib/duplicated.jar</li>
* <li>WEB-INF/lib/foo.jar</li>
* </ul>
* </li>
* <li>duplicated.war</li>
* </ul>
*
* Then for root.ear, this will only iterate WEB-INF/lib/duplicated.jar and duplicated.war.
* </p>
* <p>
* This is most useful to summarize what part of the application will be migrated by migrating the shared libraries.
* </p>
*
* @author <a href="http://ondra.zizka.cz/">Ondrej Zizka, zizka@seznam.cz</a>
*/
public class SharedLibsTraversalStrategy implements TraversalStrategy
{
public static final Logger LOG = Logger.getLogger(SharedLibsTraversalStrategy.class.getName());
public SharedLibsTraversalStrategy()
{
reset();
}
@Override
public ProjectModelTraversal.TraversalState getTraversalState(ProjectModelTraversal traversal)
{
if (ProjectService.SHARED_LIBS_UNIQUE_ID.equals(traversal.getCanonicalProject().getRootProjectModel().getUniqueID()))
return ProjectModelTraversal.TraversalState.ALL;
else
return ProjectModelTraversal.TraversalState.CHILDREN_ONLY;
}
@Override
public void reset()
{
}
@Override
public Iterable<ProjectModelTraversal> getChildren(final ProjectModelTraversal traversal)
{
ProjectModel canonicalProject = traversal.getCanonicalProject();
Iterable<ProjectModelTraversal> defaultChildren = Iterables.transform(canonicalProject.getChildProjects(), new Function<ProjectModel, ProjectModelTraversal>()
{
@Override
public ProjectModelTraversal apply(ProjectModel input)
{
return new ProjectModelTraversal(traversal, input, SharedLibsTraversalStrategy.this);
}
});
return Iterables.filter(defaultChildren, new Predicate<ProjectModelTraversal>()
{
@Override
public boolean apply(ProjectModelTraversal input)
{
// which are shared between apps.
ProjectModelTraversal.TraversalState traversalState = getTraversalState(input);
return traversalState != ProjectModelTraversal.TraversalState.NONE;
}
});
}
}