package net.rubygrapefruit.docs.renderer; import net.rubygrapefruit.docs.model.Referenceable; import java.io.File; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class PageRegistry { private final Map<Chunk, Page> pages = new LinkedHashMap<Chunk, Page>(); private final Map<Referenceable, Page> cache = new HashMap<Referenceable, Page>(); private FrontPage frontPage; public PageRegistry(RenderableDocument document, File outputFile) { List<BuildableChunk> chunks = document.getContents(); if (chunks.isEmpty()) { return; } File outputDir = new File(outputFile.getParentFile(), outputFile.getName() + ".content"); BuildableChunk firstChunk = chunks.get(0); frontPage = new FrontPage(firstChunk, outputFile, outputDir); pages.put(firstChunk, frontPage); PageImpl previous = frontPage; for (int i = 1; i < chunks.size(); i++) { BuildableChunk chunk = chunks.get(i); File pageFile = new File(outputDir, String.format("%s.html", chunk.getId())); OtherPage page = new OtherPage(chunk, pageFile); page.previous = previous; previous.next = page; pages.put(chunk, page); previous = page; } } public Page getPageFor(Chunk chunk) { return pages.get(chunk); } public Page getPageFor(Referenceable element) { Page page = cache.get(element); if (page == null) { for (Page candidate : pages.values()) { if (candidate.getChunk().contains(element)) { page = candidate; break; } } if (page == null) { throw new IllegalArgumentException("Element " + element + " not found."); } cache.put(element, page); } return page; } private abstract class PageImpl extends Page { PageImpl next; PageImpl previous; private PageImpl(Chunk chunk, File file) { super(chunk, file); } @Override public String getNextUrl() { return next == null ? null : getUrlTo(next); } @Override public String getPreviousUrl() { return previous == null ? null : getUrlTo(previous); } @Override public Page getPageFor(Referenceable element) { return PageRegistry.this.getPageFor(element); } } private class OtherPage extends PageImpl { public OtherPage(BuildableChunk chunk, File pageFile) { super(chunk, pageFile); } @Override public String getHomeUrl() { return "../" + frontPage.getFile().getName(); } @Override public String getUrlTo(Page other) { if (other == this) { return null; } if (other == frontPage) { return getHomeUrl(); } return other.getFile().getName(); } } private class FrontPage extends PageImpl { private final File contentDir; private FrontPage(Chunk chunk, File file, File contentDir) { super(chunk, file); this.contentDir = contentDir; } @Override public String getHomeUrl() { return null; } @Override public String getUrlTo(Page other) { if (other == this) { return null; } return contentDir.getName() + "/" + other.getFile().getName(); } } }