package ru.naumen.gintonic.project.source.references; import java.io.Serializable; import java.util.Collection; import java.util.List; import org.eclipse.core.resources.*; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jface.text.ITextSelection; import ru.naumen.gintonic.project.files.SelectAndReveal; import ru.naumen.gintonic.project.navigate.IJumpable; import ru.naumen.gintonic.project.navigate.selection.ICompilationUnitSelection; import ru.naumen.gintonic.utils.ICompilationUnitSelectionUtils; import ru.naumen.gintonic.utils.ICompilationUnitUtils; import ru.naumen.gintonic.utils.StringUtils; /** * A leightweight reference to a source code location. It is currently used to * navigate from one source code location to another. * * @author tmajunke */ public class SourceCodeReference implements Serializable, IJumpable { private static final long serialVersionUID = -9134622846341053959L; private String projectName; private List<String> srcFolderPathComponents; private List<String> packageNameComponents; private String primaryTypeName; private Integer offset; private Integer length; public void setProjectName(String projectName) { this.projectName = projectName; } public void setSrcFolderPathComponents(List<String> srcFolderPathComponents) { this.srcFolderPathComponents = srcFolderPathComponents; } public void setPackageNameComponents(List<String> packageNameComponents) { this.packageNameComponents = packageNameComponents; } public void setPrimaryTypeName(String primaryTypeName) { this.primaryTypeName = primaryTypeName; } public void setOffset(Integer offset) { this.offset = offset; } public void setLength(Integer length) { this.length = length; } /** * The name of the project the type belongs to. */ public String getProjectName() { return projectName; } /** * Returns the path to the src folder. Most likely this is ["src"] but maven * projects use ["src", "main", "java"]. * * @return the path to the src folder. */ public List<String> getSrcFolderPathComponents() { return srcFolderPathComponents; } /** * Returns the package as list of strings (e.g ["java","lang"]). * * @return the package as list of strings. */ public List<String> getPackageNameComponents() { return packageNameComponents; } /** * The package name fully qualified (e.g "java.lang"). Is empty for the * default package. */ public String getPackageNameComponentsFullyQualified() { return StringUtils.join('.', getPackageNameComponents()); } /** * Returns the simple name of the java type (e.g for {@link Collection} it * would be Collection). */ public String getPrimaryTypeName() { return primaryTypeName; } /** * Returns the fully qualified type name (e.g for {@link Collection} it * would be java.util.Collection). */ public String getPrimaryTypeNameFullyQualified() { return getPackageNameComponentsFullyQualified() + "." + getPrimaryTypeName(); } /** * Returns the character index into the original source file indicating * where the source fragment corresponding to this reference begins. * * @see ASTNode#getStartPosition() */ public Integer getOffset() { return offset; } /** * Returns the length in characters of the original source file indicating * where the source fragment corresponding to this reference ends. * * @see ASTNode#getLength() */ public Integer getLength() { return length; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((length == null) ? 0 : length.hashCode()); result = prime * result + ((offset == null) ? 0 : offset.hashCode()); result = prime * result + ((packageNameComponents == null) ? 0 : packageNameComponents.hashCode()); result = prime * result + ((primaryTypeName == null) ? 0 : primaryTypeName.hashCode()); result = prime * result + ((projectName == null) ? 0 : projectName.hashCode()); result = prime * result + ((srcFolderPathComponents == null) ? 0 : srcFolderPathComponents.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; SourceCodeReference other = (SourceCodeReference) obj; if (length == null) { if (other.length != null) return false; } else if (!length.equals(other.length)) return false; if (offset == null) { if (other.offset != null) return false; } else if (!offset.equals(other.offset)) return false; if (packageNameComponents == null) { if (other.packageNameComponents != null) return false; } else if (!packageNameComponents.equals(other.packageNameComponents)) return false; if (primaryTypeName == null) { if (other.primaryTypeName != null) return false; } else if (!primaryTypeName.equals(other.primaryTypeName)) return false; if (projectName == null) { if (other.projectName != null) return false; } else if (!projectName.equals(other.projectName)) return false; if (srcFolderPathComponents == null) { if (other.srcFolderPathComponents != null) return false; } else if (!srcFolderPathComponents.equals(other.srcFolderPathComponents)) return false; return true; } @Override public String toString() { return "@" + projectName + srcFolderPathComponents + packageNameComponents + "." + primaryTypeName + "(" + offset + "," + length + ")"; } @Override public void jump() { jump(getOffset()); } public void jump(int offset) { IFile file = resolveIFile(); SelectAndReveal.selectAndReveal(file, offset, 0); } public IFile resolveIFile() { IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceRoot root = workspace.getRoot(); IProject project = root.getProject(projectName); char pathSeparator = StringUtils.PATH_SEPARATOR; String sourceFolder = StringUtils.join(pathSeparator, srcFolderPathComponents) + pathSeparator + StringUtils.join(pathSeparator, getPackageNameComponents()); IFolder folder = project.getFolder(sourceFolder); String filename = getPrimaryTypeName() + ICompilationUnitUtils.JAVA_EXTENSION; IFile file = folder.getFile(filename); return file; } public ICompilationUnit resolveICompilationUnit() { IFile resolvedIFile = resolveIFile(); ICompilationUnit compilationUnit = JavaCore.createCompilationUnitFrom(resolvedIFile); return compilationUnit; } public static SourceCodeReference createCurrent() { ICompilationUnitSelection compilationUnitSelection = ICompilationUnitSelectionUtils.getCompilationUnitSelection(); if (compilationUnitSelection == null) { return null; } ICompilationUnit icompilationUnit = compilationUnitSelection.getICompilationUnit(); ITextSelection textSelection= compilationUnitSelection.getITextSelection(); SourceCodeReference codeReference = new SourceCodeReference(); IResource resource = icompilationUnit.getResource(); IProject project = resource.getProject(); codeReference.setProjectName(project.getName()); List<String> srcFolderPath = ICompilationUnitUtils.getSrcFolderPathComponents(icompilationUnit); codeReference.setSrcFolderPathComponents(srcFolderPath); IPackageFragment parent = (IPackageFragment) icompilationUnit.getParent(); String packageDotSeparated = parent.getElementName(); List<String> packageAsList = StringUtils.split('.', packageDotSeparated); codeReference.setPackageNameComponents(packageAsList); String typeName = ICompilationUnitUtils.getNameWithoutJavaExtension(icompilationUnit); codeReference.setPrimaryTypeName(typeName); if (textSelection != null) { int offset = textSelection.getOffset(); codeReference.setOffset(offset); int length = textSelection.getLength(); codeReference.setLength(length); } return codeReference; } }