package org.jboss.windup.graph.model; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.frames.modules.javahandler.JavaHandler; import com.tinkerpop.frames.modules.javahandler.JavaHandlerContext; import org.jboss.windup.graph.model.resource.FileModel; import com.tinkerpop.blueprints.Direction; import com.tinkerpop.frames.Adjacency; import com.tinkerpop.frames.Property; import com.tinkerpop.frames.modules.typedgraph.TypeValue; import java.util.LinkedHashSet; import java.util.Set; /** * Represents an archive within the input application. */ @TypeValue(ArchiveModel.TYPE) public interface ArchiveModel extends FileModel { String TYPE = "ArchiveModel:"; String ARCHIVE_NAME = TYPE + "archiveName"; String UNZIPPED_DIRECTORY = "unzippedDirectory"; String PARENT_ARCHIVE = "parentArchive"; /** * Contains the parent archive. */ @Adjacency(label = PARENT_ARCHIVE, direction = Direction.IN) ArchiveModel getParentArchive(); /** * Contains the parent archive. */ @Adjacency(label = PARENT_ARCHIVE, direction = Direction.IN) void setParentArchive(ArchiveModel archive); /** * Contains the name of this archive (original filename). */ @Property(ARCHIVE_NAME) String getArchiveName(); /** * Contains the name of this archive (original filename). */ @Property(ARCHIVE_NAME) void setArchiveName(String archiveName); /** * Contains the directory to which this archive has been unzipped. It will be null if the archive has not been unzipped. */ @Property(UNZIPPED_DIRECTORY) void setUnzippedDirectory(String unzippedPath); /** * Contains the directory to which this archive has been unzipped. It will be null if the archive has not been unzipped. */ @Property(UNZIPPED_DIRECTORY) String getUnzippedDirectory(); /** * Contains a link to the organization which produced this archive. */ @Adjacency(label = OrganizationModel.ARCHIVE_MODEL, direction = Direction.IN) Iterable<OrganizationModel> getOrganizationModels(); /** * Gets all files in this archive, including subfiles, but not including subfiles of embedded archives. */ @JavaHandler Iterable<FileModel> getAllFiles(); /** * Gets the {@link ArchiveModel}s that are duplicates of this archive. */ @Adjacency(label = DuplicateArchiveModel.CANONICAL_ARCHIVE, direction = Direction.IN) Iterable<DuplicateArchiveModel> getDuplicateArchives(); /** * Gets the "root" archive model. The root is defined as the model for which {@link #getParentArchive()} would return * null. If the current archive is the root, then this will return itself. */ @JavaHandler ArchiveModel getRootArchiveModel(); /** * Indicates whether or not the passed in {@link ArchiveModel} is a child or other descendant of the current * archive. */ @JavaHandler boolean containsArchive(ArchiveModel archiveModel); abstract class Impl extends FileModel.Impl implements ArchiveModel, JavaHandlerContext<Vertex> { @Override public Iterable<FileModel> getAllFiles() { Set<FileModel> results = new LinkedHashSet<>(); for (FileModel child : getFilesInDirectory()) addAllFiles(results, child); return results; } private void addAllFiles(Set<FileModel> files, FileModel file) { files.add(file); // don't include children of embedded archives if (file instanceof ArchiveModel) return; for (FileModel child : file.getFilesInDirectory()) addAllFiles(files, child); } @Override public ArchiveModel getRootArchiveModel() { ArchiveModel archiveModel = this; while (archiveModel.getParentArchive() != null) { archiveModel = archiveModel.getParentArchive(); } // 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(archiveModel.asVertex()); } @Override public boolean containsArchive(ArchiveModel archiveModel) { if (this.asVertex().equals(archiveModel.asVertex())) return true; else if (archiveModel.getParentArchive() != null) return containsArchive(archiveModel.getParentArchive()); else return false; } } }