IndexWithBreadcrumbs.java
package org.jbehave.core.io.rest;
import static java.text.MessageFormat.format;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.jbehave.core.io.CodeLocations.codeLocationFromPath;
import static org.jbehave.core.io.rest.filesystem.FilesystemUtils.fileNameWithoutExt;
import static org.jbehave.core.io.rest.filesystem.FilesystemUtils.normalisedPathOf;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.jbehave.core.io.StoryFinder;
public abstract class IndexWithBreadcrumbs implements ResourceIndexer {
private static final String EMPTY = "";
private static final String FULL_PATH = "{0}/{1}";
private RESTClient client;
private ResourceNameResolver nameResolver;
public IndexWithBreadcrumbs(RESTClient client,
ResourceNameResolver nameResolver) {
this.client = client;
this.nameResolver = nameResolver;
}
@Override
public Map<String, Resource> indexResources(String rootURI) {
String entity = get(uri(rootURI));
Map<String, Resource> index = createIndexFromEntity(rootURI, entity);
addBreadcrumbs(index);
return index;
}
@Override
public Map<String, Resource> indexResources(String rootURI,
String rootPath, String syntax, String includes) {
Map<String, Resource> index = createIndexFromPaths(rootURI, rootPath,
syntax, includes);
addBreadcrumbs(index);
return index;
}
protected Map<String, Resource> createIndexFromPaths(String rootURI,
String rootPath, String syntax, String includes) {
Map<String, Resource> index = new HashMap<>();
List<String> paths = new StoryFinder().findPaths(
codeLocationFromPath(rootPath), includes, EMPTY);
for (String path : paths) {
addPath(rootURI, rootPath, fullPath(rootPath, path), syntax, index);
}
return index;
}
private void addPath(String rootURI, String rootPath, String path,
String syntax, Map<String, Resource> index) {
File file = new File(path);
String name = resolveName(fileNameWithoutExt(file));
String parentName = parentName(file, rootPath);
String uri = fullPath(rootURI, name);
Resource resource = new Resource(uri, name, parentName);
resource.setContent(contentOf(file));
if (isNotBlank(syntax)) {
resource.setSyntax(syntax);
}
index.put(name, resource);
if (parentName != null) {
addPath(rootURI, rootPath, file.getParent(), syntax, index);
}
}
private String parentName(File file, String rootPath) {
File parent = file.getParentFile();
if (parent != null && !normalisedPathOf(parent).equals(rootPath)) {
return resolveName(parent.getName());
}
return null;
}
private String fullPath(String root, String path) {
return format(FULL_PATH, root, path);
}
private String contentOf(File file) {
if (file.isDirectory()) {
return EMPTY;
}
try {
return FileUtils.readFileToString(file);
} catch (IOException e) {
throw new RuntimeException(
"Failed to read content of file " + file, e);
}
}
protected void addBreadcrumbs(Map<String, Resource> index) {
for (Resource resource : index.values()) {
List<String> breadcrumbs = new ArrayList<>();
collectBreadcrumbs(breadcrumbs, resource, index);
resource.setBreadcrumbs(breadcrumbs);
}
}
private void collectBreadcrumbs(List<String> breadcrumbs,
Resource resource, Map<String, Resource> index) {
if (resource.hasParent()) {
String parentName = resource.getParentName();
breadcrumbs.add(0, parentName);
Resource parent = index.get(parentName);
if (parent != null) {
collectBreadcrumbs(breadcrumbs, parent, index);
}
}
}
private String get(String uri) {
return client.get(uri);
}
protected abstract Map<String, Resource> createIndexFromEntity(
String rootURI, String entity);
protected abstract String uri(String rootPath);
protected String resolveName(String input) {
return nameResolver.resolve(input);
}
public static class ToLowerCase implements ResourceNameResolver {
@Override
public String resolve(String input) {
return input.toLowerCase();
}
}
}