package org.springframework.roo.project;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.roo.project.maven.Pom;
/**
* A given {@link Path} within the context of a specific project module.
* <p>
* To obtain the physical location on the file system, pass an instance of this
* class to the {@link PathResolver}.
*
* @author James Tyrrell
* @since 1.2.0
*/
public class LogicalPath {
/**
* The character that appears between the module name and the path name in
* the textual representation of a {@link LogicalPath}. This cannot be any
* character that could feasibly occur in a module name or {@link Path}
* name.
*/
public static final String MODULE_PATH_SEPARATOR = ":";
/**
* The character that separates "folders" in the textual representation of a
* {@link LogicalPath}.
*/
public static final String PATH_SEPARATOR = ".";
/**
* Creates an instance with the given path in the given module
*
* @param path the path to set (required)
* @param module can be blank for none
* @return a non-<code>null</code> instance
*/
public static LogicalPath getInstance(final Path path, final String module) {
return new LogicalPath(module, path);
}
/**
* Creates a {@link LogicalPath} by parsing the given concatenation of
* optional module name and mandatory path name.
*
* @param modulePlusPath a string consisting of an optional module name plus
* the {@link #MODULE_PATH_SEPARATOR} plus the path, or more
* precisely:
* <code>[<i>module_name</i>{@value #MODULE_PATH_SEPARATOR}]<i>path</i></code>
*/
public static LogicalPath getInstance(final String modulePlusPath) {
Validate.notBlank(modulePlusPath, "Module path required");
final int separatorIndex = modulePlusPath.indexOf(MODULE_PATH_SEPARATOR);
if (separatorIndex == -1) {
return new LogicalPath(null, Path.valueOf(modulePlusPath));
}
final Path path =
Path.valueOf(modulePlusPath.substring(separatorIndex + 1, modulePlusPath.length()));
final String module = modulePlusPath.substring(0, separatorIndex);
return new LogicalPath(module, path);
}
private final String module;
private final Path path;
/**
* Constructor
*
* @param module the module containing the given path (can be blank)
* @param path the path within the module, if any (required)
*/
private LogicalPath(final String module, final Path path) {
Validate.notNull(path, "Path required");
this.module = StringUtils.stripToEmpty(module);
this.path = path;
}
public int compareTo(final LogicalPath o) {
if (o == null) {
throw new NullPointerException();
}
return getName().compareTo(o.getName());
}
@Override
public boolean equals(final Object obj) {
return obj instanceof LogicalPath && compareTo((LogicalPath) obj) == 0;
}
/**
* Returns the name of the module containing this path, if any
*
* @return a non-<code>null</code> name (might be empty)
*/
public String getModule() {
return module;
}
/**
* Returns the display name of this {@link LogicalPath}.
*
* @return a non-blank name
*/
public String getName() {
final StringBuilder name = new StringBuilder();
if (StringUtils.isNotBlank(module)) {
name.append(module).append(MODULE_PATH_SEPARATOR);
}
name.append(path);
return name.toString();
}
/**
* Returns the path component of this {@link LogicalPath}
*
* @return a non-<code>null</code> path
*/
public Path getPath() {
return path;
}
/**
* Returns the physical path of this logical path relative to the given POM
*
* @param pom can be <code>null</code>
* @return a non-<code>null</code> path
*/
public String getPathRelativeToPom(final Pom pom) {
return path.getPathRelativeToPom(pom);
}
@Override
public int hashCode() {
return getName().hashCode();
}
/**
* Indicates whether this is the root of the owning module.
*
* @return see above
*/
public boolean isModuleRoot() {
return path == Path.ROOT;
}
/**
* Indicates whether this is the root of the entire user project.
*
* @return see above
*/
public boolean isProjectRoot() {
return isModuleRoot() && StringUtils.isBlank(module);
}
@Override
public final String toString() {
return getName();
}
}