IndexWithBreadcrumbs.java

  1. package org.jbehave.core.io.rest;

  2. import static java.text.MessageFormat.format;
  3. import static org.apache.commons.lang3.StringUtils.isNotBlank;
  4. import static org.jbehave.core.io.CodeLocations.codeLocationFromPath;
  5. import static org.jbehave.core.io.rest.filesystem.FilesystemUtils.fileNameWithoutExt;
  6. import static org.jbehave.core.io.rest.filesystem.FilesystemUtils.normalisedPathOf;

  7. import java.io.File;
  8. import java.io.IOException;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;

  13. import org.apache.commons.io.FileUtils;
  14. import org.jbehave.core.io.StoryFinder;

  15. public abstract class IndexWithBreadcrumbs implements ResourceIndexer {

  16.     private static final String EMPTY = "";
  17.     private static final String FULL_PATH = "{0}/{1}";
  18.    
  19.     private RESTClient client;
  20.     private ResourceNameResolver nameResolver;

  21.     public IndexWithBreadcrumbs(RESTClient client,
  22.             ResourceNameResolver nameResolver) {
  23.         this.client = client;
  24.         this.nameResolver = nameResolver;
  25.     }

  26.     @Override
  27.     public Map<String, Resource> indexResources(String rootURI) {
  28.         String entity = get(uri(rootURI));
  29.         Map<String, Resource> index = createIndexFromEntity(rootURI, entity);
  30.         addBreadcrumbs(index);
  31.         return index;
  32.     }

  33.     @Override
  34.     public Map<String, Resource> indexResources(String rootURI,
  35.             String rootPath, String syntax, String includes) {
  36.         Map<String, Resource> index = createIndexFromPaths(rootURI, rootPath,
  37.                 syntax, includes);
  38.         addBreadcrumbs(index);
  39.         return index;
  40.     }

  41.     protected Map<String, Resource> createIndexFromPaths(String rootURI,
  42.             String rootPath, String syntax, String includes) {
  43.         Map<String, Resource> index = new HashMap<>();
  44.         List<String> paths = new StoryFinder().findPaths(
  45.                 codeLocationFromPath(rootPath), includes, EMPTY);
  46.         for (String path : paths) {
  47.             addPath(rootURI, rootPath, fullPath(rootPath, path), syntax, index);
  48.         }
  49.         return index;
  50.     }

  51.     private void addPath(String rootURI, String rootPath, String path,
  52.             String syntax, Map<String, Resource> index) {
  53.         File file = new File(path);
  54.         String name = resolveName(fileNameWithoutExt(file));
  55.         String parentName = parentName(file, rootPath);
  56.         String uri = fullPath(rootURI, name);
  57.         Resource resource = new Resource(uri, name, parentName);
  58.         resource.setContent(contentOf(file));
  59.         if (isNotBlank(syntax)) {
  60.             resource.setSyntax(syntax);
  61.         }
  62.         index.put(name, resource);
  63.         if (parentName != null) {
  64.             addPath(rootURI, rootPath, file.getParent(), syntax, index);
  65.         }
  66.     }

  67.     private String parentName(File file, String rootPath) {
  68.         File parent = file.getParentFile();
  69.         if (parent != null && !normalisedPathOf(parent).equals(rootPath)) {
  70.             return resolveName(parent.getName());
  71.         }
  72.         return null;
  73.     }

  74.     private String fullPath(String root, String path) {
  75.         return format(FULL_PATH, root,  path);
  76.     }

  77.     private String contentOf(File file) {
  78.         if (file.isDirectory()) {
  79.             return EMPTY;
  80.         }
  81.         try {
  82.             return FileUtils.readFileToString(file);
  83.         } catch (IOException e) {
  84.             throw new RuntimeException(
  85.                     "Failed to read content of file " + file, e);
  86.         }
  87.     }

  88.     protected void addBreadcrumbs(Map<String, Resource> index) {
  89.         for (Resource resource : index.values()) {
  90.             List<String> breadcrumbs = new ArrayList<>();
  91.             collectBreadcrumbs(breadcrumbs, resource, index);
  92.             resource.setBreadcrumbs(breadcrumbs);
  93.         }
  94.     }

  95.     private void collectBreadcrumbs(List<String> breadcrumbs,
  96.             Resource resource, Map<String, Resource> index) {
  97.         if (resource.hasParent()) {
  98.             String parentName = resource.getParentName();
  99.             breadcrumbs.add(0, parentName);
  100.             Resource parent = index.get(parentName);
  101.             if (parent != null) {
  102.                 collectBreadcrumbs(breadcrumbs, parent, index);
  103.             }
  104.         }
  105.     }

  106.     private String get(String uri) {
  107.         return client.get(uri);
  108.     }
  109.    
  110.     protected abstract Map<String, Resource> createIndexFromEntity(
  111.             String rootURI, String entity);

  112.     protected abstract String uri(String rootPath);

  113.     protected String resolveName(String input) {
  114.         return nameResolver.resolve(input);
  115.     }
  116.    
  117.     public static class ToLowerCase implements ResourceNameResolver {

  118.         @Override
  119.         public String resolve(String input) {
  120.             return input.toLowerCase();
  121.         }

  122.     }
  123. }