package org.jboss.windup.graph.model; import java.util.HashSet; import java.util.Set; import org.jboss.windup.graph.model.resource.FileModel; import com.tinkerpop.blueprints.Direction; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.frames.Adjacency; import com.tinkerpop.frames.Property; import com.tinkerpop.frames.annotations.gremlin.GremlinGroovy; import com.tinkerpop.frames.modules.javahandler.JavaHandler; import com.tinkerpop.frames.modules.javahandler.JavaHandlerContext; import com.tinkerpop.frames.modules.typedgraph.TypeValue; import org.jboss.windup.graph.Indexed; /** * Base interface representing an abstract project model with a project name, version, type, and location on disk. Projects may be source-based or * binary based. * * Additional models may extend this to support additional project types (eg, Maven-based projects). * * @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a> */ @TypeValue(ProjectModel.TYPE) public interface ProjectModel extends WindupVertexFrame { String TYPE = "ProjectModel"; String DEPENDENCY = "dependency"; String PARENT_PROJECT = "parentProject"; String ROOT_FILE_MODEL = "rootFileModel"; String PROJECT_MODEL_TO_FILE = "projectModelToFile"; String SOURCE_BASED = "sourceBased"; String DESCRIPTION = "description"; String ORGANIZATION = "organization"; String URL = "url"; String NAME = "name"; String UNIQUE_ID = "uniqueID"; String VERSION = "version"; String PROJECT_TYPE = "projectType"; /** * Denotes the virtual projects, such like Shared Libraries. */ String TYPE_VIRTUAL = "VIRTUAL"; /** * This represents the root directory (in the case of a source-based analysis) or root archive (for binary analysis) containing this particular * project. */ @Adjacency(label = ROOT_FILE_MODEL, direction = Direction.OUT) void setRootFileModel(FileModel fileModel); @Adjacency(label = ROOT_FILE_MODEL, direction = Direction.OUT) FileModel getRootFileModel(); /** * Indicates whether or not this is a source-based project (eg, the project provided by the user for analysis), or a binary project (eg, as part * of the dependencies for a Maven project, or as a binary provided by the user for analysis). */ @Property(SOURCE_BASED) void setSourceBased(boolean sourceBased); /** * Indicates whether or not this is a source-based project (eg, the project provided by the user for analysis), or a binary project (eg, as part * of the dependencies for a Maven project, or as a binary provided by the user for analysis). */ @Property(SOURCE_BASED) Boolean isSourceBased(); /** * The organization associated with this project. */ @Property(ORGANIZATION) String getOrganization(); /** * The organization associated with this project. */ @Property(ORGANIZATION) void setOrganization(String organization); /** * Indicates the project's artifact type (jar, war, ear, etc) */ @Property(PROJECT_TYPE) void setProjectType(String projectType); /** * Indicates the project's artifact type (jar, war, ear, etc) */ @Property(PROJECT_TYPE) String getProjectType(); /** * Contains the project's version. */ @Property(VERSION) String getVersion(); /** * Contains the project's version. */ @Property(VERSION) void setVersion(String version); /** * Project's name. * This is often derived Maven name or MANIFEST.MF name or from project's root filename. */ @Property(NAME) String getName(); /** * Project's name. * This is often derived Maven name or MANIFEST.MF name or from project's root filename. */ @Property(NAME) void setName(String name); /** * Project's unique ID. Not necessarily set for all projects, * only those special, such like shared-libs. */ @Indexed @Property(UNIQUE_ID) String getUniqueID(); /** * Project's unique ID. Not necessarily set for all projects, * only those special, such like shared-libs. */ @Property(UNIQUE_ID) void setUniqueID(String name); /** * Contains the project's description. */ @Property(DESCRIPTION) String getDescription(); /** * Contains the project's description. */ @Property(DESCRIPTION) void setDescription(String description); /** * Contains a url to the project's website. */ @Property(URL) String getURL(); /** * Contains a url to the project's website. */ @Property(URL) void setURL(String url); /** * The parent ProjectModel, or null if no parent is present. */ @Adjacency(label = PARENT_PROJECT, direction = Direction.OUT) void setParentProject(ProjectModel maven); /** * The parent ProjectModel, or null if no parent is present. */ @Adjacency(label = PARENT_PROJECT, direction = Direction.OUT) ProjectModel getParentProject(); /** * A list of child projects */ @Adjacency(label = PARENT_PROJECT, direction = Direction.IN) void addChildProject(ProjectModel maven); /** * A list of child projects */ @Adjacency(label = PARENT_PROJECT, direction = Direction.IN) Iterable<ProjectModel> getChildProjects(); /** * Project dependencies, as well as metadata about those deps. */ @Adjacency(label = DEPENDENCY, direction = Direction.OUT) void addDependency(ProjectDependencyModel maven); /** * Project dependencies, as well as metadata about those deps. */ @Adjacency(label = DEPENDENCY, direction = Direction.OUT) Iterable<ProjectDependencyModel> getDependencies(); /** * Retrieve all files contained within the project. */ @Adjacency(label = PROJECT_MODEL_TO_FILE, direction = Direction.OUT) Iterable<FileModel> getFileModels(); /** * Add a file model to the project. */ @Adjacency(label = PROJECT_MODEL_TO_FILE, direction = Direction.OUT) void addFileModel(FileModel fileModel); /** * Gets all contained files that are not directories */ @GremlinGroovy("it.out('" + PROJECT_MODEL_TO_FILE + "').has('" + FileModel.IS_DIRECTORY + "', false)") Iterable<FileModel> getFileModelsNoDirectories(); /** * Gets all contained files that unparsable */ @GremlinGroovy("it.out('" + PROJECT_MODEL_TO_FILE + "').has('" + FileModel.PARSE_ERROR + "')") Iterable<FileModel> getUnparsableFiles(); /** * Returns the project model that represents the whole application. If this projectModel is the root projectModel, it will return it. * * @return ProjectModel representing the whole application */ @JavaHandler ProjectModel getRootProjectModel(); /** * Returns this project model as well as all of its children, recursively. */ @JavaHandler Set<ProjectModel> getAllProjectModels(); @Adjacency(label = DuplicateProjectModel.CANONICAL_PROJECT, direction = Direction.IN) Iterable<DuplicateProjectModel> getDuplicateProjects(); abstract class Impl implements ProjectModel, JavaHandlerContext<Vertex> { @Override public ProjectModel getRootProjectModel() { ProjectModel projectModel = this; while (projectModel.getParentProject() != null) { projectModel = projectModel.getParentProject(); } // reframe it to make sure that we return a proxy // (otherwise, it may return this method handler implementation, which will have some unexpected side effects) return frame(projectModel.asVertex()); } @Override public Set<ProjectModel> getAllProjectModels() { Set<ProjectModel> result = new HashSet<>(); result.add(frame(it(), ProjectModel.class)); for (ProjectModel child : getChildProjects()) result.addAll(child.getAllProjectModels()); return result; } } }