package files;
import static util.ListUtils.removeLast;
import static util.StringUtils.getStemAndExtension;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
/**
* A path to a source file, relative to a root source directory. This path
* includes all directories corresponding to package name components (if any).
*/
public class RelativeSourcePath
{
/****************************************************************************/
private final Package pkg;
/****************************************************************************/
private final String fileStem;
/****************************************************************************/
private final String fileExt;
/****************************************************************************/
private final Path relativePath;
/****************************************************************************/
public static RelativeSourcePath make(Package pkg, String fileName)
{
return new RelativeSourcePath(pkg, fileName);
}
/*****************************************************************************
* Makes a path for the regular source file corresponding to the given
* package string (the fully qualified dot-separated name of a class).
*/
public static RelativeSourcePath make(String pkgStr)
{
int dot = pkgStr.lastIndexOf('.');
return dot == -1
? make(new Package(""), pkgStr)
: make(new Package(pkgStr.substring(0, dot)),
pkgStr.substring(dot + 1) + ".java");
}
// TODO This is cleaner than the current constructor, but cannot be
// inherited by RootedSourcePath.
//
// /****************************************************************************/
// public static RelativeSourcePath make(Path relative)
// {
// int lastName = relative.getNameCount() - 1;
// String name = relative.getName(lastName).toString();
// String pkgPath = relative.subpath(0, lastName).toString();
//
// return make(new Package(pkgPath), name);
// }
/****************************************************************************/
public RelativeSourcePath(Package pkg, String fileName)
{
String[] stemAndExt = getStemAndExtension(fileName);
this.pkg = pkg;
this.fileStem = stemAndExt[0];
this.fileExt = stemAndExt[1];
this.relativePath = pkg.relativePath().resolve(Paths.get(fileName));
}
/****************************************************************************/
public RelativeSourcePath(Path relative)
{
List<String> components = new ArrayList<>(relative.getNameCount() - 1);
for (Path p : relative) {
components.add(p.toString());
}
String[] stemAndExt = getStemAndExtension(removeLast(components));
this.relativePath = relative;
this.pkg = new Package(components);
this.fileStem = stemAndExt[0];
this.fileExt = stemAndExt[1];
}
/****************************************************************************/
public Package pkg()
{
return pkg;
}
/****************************************************************************/
public String fileStem()
{
return fileStem;
}
/****************************************************************************/
public String fileExt()
{
return fileExt;
}
/****************************************************************************/
public String fileName()
{
return fileExt.isEmpty() ? fileStem : fileStem + "." + fileExt;
}
/****************************************************************************/
public Path relativePath()
{
return relativePath;
}
/*****************************************************************************
* Returns a "package string" to the class that has the same name than
* this file.
*/
public String pkgString()
{
String pkgName = pkg.toString();
return pkgName.isEmpty() ? fileStem : pkgName + "." + fileStem;
}
/****************************************************************************/
@Override public String toString()
{
return relativePath.toString();
}
/****************************************************************************/
@Override public boolean equals(Object o)
{
if (!(o instanceof RelativeSourcePath)) { return false; }
RelativeSourcePath other = (RelativeSourcePath) o;
return other.canEqual(this) && relativePath.equals(other.relativePath);
}
/****************************************************************************/
public boolean canEqual(Object other)
{
return (other instanceof RelativeSourcePath);
}
/****************************************************************************/
@Override public int hashCode()
{
return toString().hashCode();
}
}